mirror of https://github.com/MISP/misp-bump
Renamed to MISPBump
parent
617a0a6c61
commit
cde59784b1
|
@ -2,8 +2,8 @@
|
|||
<project version="4">
|
||||
<component name="ProjectModuleManager">
|
||||
<modules>
|
||||
<module fileurl="file://$PROJECT_DIR$/Misp.iml" filepath="$PROJECT_DIR$/Misp.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/app/app.iml" filepath="$PROJECT_DIR$/app/app.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/misp-auth.iml" filepath="$PROJECT_DIR$/misp-auth.iml" />
|
||||
</modules>
|
||||
</component>
|
||||
</project>
|
BIN
MISPauth .pdf
BIN
MISPauth .pdf
Binary file not shown.
Binary file not shown.
Before Width: | Height: | Size: 57 KiB |
Binary file not shown.
Before Width: | Height: | Size: 122 KiB |
Binary file not shown.
Before Width: | Height: | Size: 1.1 MiB |
Binary file not shown.
Before Width: | Height: | Size: 88 KiB |
Binary file not shown.
Before Width: | Height: | Size: 77 KiB |
|
@ -2,10 +2,10 @@ apply plugin: 'com.android.application'
|
|||
|
||||
android {
|
||||
compileSdkVersion 27
|
||||
buildToolsVersion "27.0.3"
|
||||
buildToolsVersion "28.0.0"
|
||||
defaultConfig {
|
||||
applicationId "de.overview.wg.its.mispauth"
|
||||
minSdkVersion 21
|
||||
minSdkVersion 23
|
||||
targetSdkVersion 27
|
||||
versionCode 1
|
||||
versionName "1.0"
|
||||
|
@ -17,6 +17,9 @@ android {
|
|||
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
|
||||
}
|
||||
}
|
||||
packagingOptions {
|
||||
exclude 'META-INF/DEPENDENCIES'
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
|
@ -30,6 +33,13 @@ dependencies {
|
|||
implementation 'com.android.support:design:27.1.1'
|
||||
|
||||
implementation 'com.android.volley:volley:1.1.0'
|
||||
implementation 'com.github.kenglxn.QRGen:android:2.4.0'
|
||||
implementation 'com.github.kenglxn.QRGen:android:2.5.0'
|
||||
implementation group: 'org.mongodb', name: 'bson', version: '3.8.0'
|
||||
implementation group: 'com.google.code.gson', name: 'gson', version: '2.8.5'
|
||||
|
||||
|
||||
|
||||
implementation 'com.google.android.gms:play-services-vision:15.0.2'
|
||||
implementation 'com.android.support:gridlayout-v7:27.1.1'
|
||||
implementation 'com.ernestoyaquello.stepperform:vertical-stepper-form:0.9.9'
|
||||
}
|
||||
|
|
|
@ -16,11 +16,11 @@ import static org.junit.Assert.*;
|
|||
*/
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
public class ExampleInstrumentedTest {
|
||||
@Test
|
||||
public void useAppContext() throws Exception {
|
||||
// Context of the app under test.
|
||||
Context appContext = InstrumentationRegistry.getTargetContext();
|
||||
@Test
|
||||
public void useAppContext() throws Exception {
|
||||
// Context of the app under test.
|
||||
Context appContext = InstrumentationRegistry.getTargetContext();
|
||||
|
||||
assertEquals("de.overview.wg.its.mispauth", appContext.getPackageName());
|
||||
}
|
||||
assertEquals("de.overview.wg.its.mispauth", appContext.getPackageName());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,8 +12,9 @@
|
|||
android:roundIcon="@mipmap/ic_launcher_round"
|
||||
android:supportsRtl="true"
|
||||
android:theme="@style/AppTheme">
|
||||
|
||||
<activity android:name=".activity.MainActivity">
|
||||
<activity
|
||||
android:name=".MainActivity"
|
||||
android:label="@string/app_name">
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.MAIN"/>
|
||||
|
||||
|
@ -22,15 +23,19 @@
|
|||
</activity>
|
||||
|
||||
<activity
|
||||
android:name=".activity.SettingsActivity"
|
||||
android:label="@string/title_activity_settings"
|
||||
android:parentActivityName=".activity.MainActivity"/>
|
||||
android:screenOrientation="portrait"
|
||||
android:name=".SyncActivity"
|
||||
android:label="Sync"
|
||||
android:parentActivityName=".MainActivity"
|
||||
android:theme="@style/AppTheme.Fullscreen">
|
||||
</activity>
|
||||
|
||||
<activity
|
||||
android:screenOrientation="portrait"
|
||||
android:name=".activity.SyncActivity"
|
||||
android:label="@string/title_activity_sync"
|
||||
android:parentActivityName=".activity.MainActivity"/>
|
||||
android:name=".CredentialsActivity"
|
||||
android:label="@string/credentials_activity"
|
||||
android:parentActivityName=".MainActivity"/>
|
||||
<activity android:name=".UploadActivity"/>
|
||||
</application>
|
||||
|
||||
</manifest>
|
|
@ -0,0 +1,417 @@
|
|||
package de.overview.wg.its.mispauth;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.app.Dialog;
|
||||
import android.content.DialogInterface;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
import android.support.design.widget.FloatingActionButton;
|
||||
import android.support.design.widget.Snackbar;
|
||||
import android.support.design.widget.TextInputLayout;
|
||||
import android.support.v7.app.AlertDialog;
|
||||
import android.support.v7.app.AppCompatActivity;
|
||||
import android.support.v7.widget.Toolbar;
|
||||
import android.text.Editable;
|
||||
import android.text.TextWatcher;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.CheckBox;
|
||||
import android.widget.CompoundButton;
|
||||
import android.widget.ProgressBar;
|
||||
import android.widget.TextView;
|
||||
import com.android.volley.VolleyError;
|
||||
import de.overview.wg.its.mispauth.auxiliary.PreferenceManager;
|
||||
import de.overview.wg.its.mispauth.auxiliary.ReadableError;
|
||||
import de.overview.wg.its.mispauth.cam.DialogFactory;
|
||||
import de.overview.wg.its.mispauth.model.Organisation;
|
||||
import de.overview.wg.its.mispauth.model.User;
|
||||
import de.overview.wg.its.mispauth.network.MispRequest;
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
@SuppressWarnings("ConstantConditions")
|
||||
@SuppressLint("SetTextI18n")
|
||||
public class CredentialsActivity extends AppCompatActivity implements View.OnClickListener {
|
||||
|
||||
private boolean changesMade;
|
||||
private boolean saveAuthkey, saveAuthkeyPrefSet;
|
||||
|
||||
private TextInputLayout urlLayout, apiLayout;
|
||||
private TextView emptyView;
|
||||
private ViewGroup organisationView;
|
||||
private ProgressBar progressBar;
|
||||
|
||||
private Organisation myOrganisation;
|
||||
private User myUser;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_credentials);
|
||||
|
||||
initializeViews();
|
||||
loadPreferences();
|
||||
addSaveChangesListener();
|
||||
}
|
||||
|
||||
private void initializeViews() {
|
||||
|
||||
Toolbar toolbar = findViewById(R.id.toolbar);
|
||||
setSupportActionBar(toolbar);
|
||||
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
|
||||
getSupportActionBar().setDisplayShowHomeEnabled(true);
|
||||
|
||||
progressBar = findViewById(R.id.progressBar);
|
||||
|
||||
urlLayout = findViewById(R.id.input_layout_server_url);
|
||||
apiLayout = findViewById(R.id.input_layout_api_key);
|
||||
|
||||
FloatingActionButton fab = findViewById(R.id.fab_download_own_org_info);
|
||||
fab.setOnClickListener(this);
|
||||
|
||||
emptyView = findViewById(R.id.empty);
|
||||
organisationView = findViewById(R.id.myOrganisationView);
|
||||
|
||||
}
|
||||
|
||||
private void loadPreferences() {
|
||||
|
||||
PreferenceManager preferenceManager = PreferenceManager.Instance(this);
|
||||
|
||||
saveAuthkeyPrefSet = preferenceManager.saveAuthkeyEnabledExists();
|
||||
saveAuthkey = preferenceManager.saveAuthkeyEnabled();
|
||||
|
||||
urlLayout.getEditText().setText(preferenceManager.getMyServerUrl());
|
||||
apiLayout.getEditText().setText(preferenceManager.getMyServerApiKey());
|
||||
|
||||
myOrganisation = preferenceManager.getMyOrganisation();
|
||||
|
||||
if (myOrganisation == null) {
|
||||
|
||||
emptyView.setVisibility(View.VISIBLE);
|
||||
organisationView.setVisibility(View.GONE);
|
||||
|
||||
} else {
|
||||
|
||||
emptyView.setVisibility(View.GONE);
|
||||
organisationView.setVisibility(View.VISIBLE);
|
||||
|
||||
visualizeOrganisation();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private void savePreferences() {
|
||||
|
||||
PreferenceManager preferenceManager = PreferenceManager.Instance(this);
|
||||
|
||||
preferenceManager.setMyServerUrl(urlLayout.getEditText().getText().toString());
|
||||
preferenceManager.setSaveAuthkeyEnabled(saveAuthkey);
|
||||
|
||||
if (saveAuthkey) {
|
||||
preferenceManager.setMyServerApiKey(apiLayout.getEditText().getText().toString());
|
||||
} else {
|
||||
preferenceManager.setMyServerApiKey("");
|
||||
}
|
||||
|
||||
if (myUser != null) {
|
||||
preferenceManager.setMyUser(myUser);
|
||||
}
|
||||
|
||||
if (myOrganisation != null) {
|
||||
preferenceManager.setMyOrganisation(myOrganisation);
|
||||
}
|
||||
|
||||
changesMade = false;
|
||||
}
|
||||
|
||||
private void addSaveChangesListener() {
|
||||
urlLayout.getEditText().addTextChangedListener(new TextWatcher() {
|
||||
@Override
|
||||
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTextChanged(CharSequence s, int start, int before, int count) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterTextChanged(Editable s) {
|
||||
changesMade = true;
|
||||
}
|
||||
});
|
||||
|
||||
apiLayout.getEditText().addTextChangedListener(new TextWatcher() {
|
||||
@Override
|
||||
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onTextChanged(CharSequence s, int start, int before, int count) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterTextChanged(Editable s) {
|
||||
changesMade = true;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void tryDownloadOrgInfo() {
|
||||
|
||||
if (myOrganisation != null) {
|
||||
|
||||
DialogInterface.OnClickListener pos = new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
downloadOrgInfo();
|
||||
}
|
||||
};
|
||||
|
||||
new DialogFactory(this).createOverrideDialog(pos, null).show();
|
||||
|
||||
} else {
|
||||
|
||||
downloadOrgInfo();
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private boolean validCredentials() {
|
||||
boolean inputError = false;
|
||||
String url = urlLayout.getEditText().getText().toString();
|
||||
String auth = apiLayout.getEditText().getText().toString();
|
||||
|
||||
if (url.equals("")) {
|
||||
urlLayout.setError("Required");
|
||||
inputError = true;
|
||||
}
|
||||
|
||||
if (auth.equals("")) {
|
||||
apiLayout.setError("Required");
|
||||
inputError = true;
|
||||
}
|
||||
|
||||
if (inputError) {
|
||||
return false;
|
||||
}
|
||||
|
||||
urlLayout.setError(null);
|
||||
apiLayout.setError(null);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private void downloadOrgInfo() {
|
||||
|
||||
if (!validCredentials()) {
|
||||
return;
|
||||
}
|
||||
|
||||
apiLayout.clearFocus();
|
||||
urlLayout.clearFocus();
|
||||
|
||||
progressBar.setVisibility(View.VISIBLE);
|
||||
emptyView.setVisibility(View.GONE);
|
||||
|
||||
final MispRequest mispRequest = MispRequest.Instance(this);
|
||||
mispRequest.setServerCredentials(urlLayout.getEditText().getText().toString(), apiLayout.getEditText().getText().toString());
|
||||
|
||||
mispRequest.getMyUser(new MispRequest.UserCallback() {
|
||||
@Override
|
||||
public void onResult(JSONObject jsonUser) {
|
||||
try {
|
||||
myUser = new User(jsonUser);
|
||||
} catch (JSONException e) {
|
||||
makeSnackBar("Could not interpret user format");
|
||||
return;
|
||||
}
|
||||
|
||||
mispRequest.getOrganisation(myUser.getId(), new MispRequest.OrganisationCallback() {
|
||||
@Override
|
||||
public void onResult(JSONObject organisationInformation) {
|
||||
try {
|
||||
myOrganisation = new Organisation(organisationInformation);
|
||||
changesMade = true;
|
||||
} catch (JSONException e) {
|
||||
makeSnackBar("Could not interpret organisation format");
|
||||
return;
|
||||
}
|
||||
|
||||
organisationView.setVisibility(View.VISIBLE);
|
||||
emptyView.setVisibility(View.GONE);
|
||||
|
||||
progressBar.setVisibility(View.GONE);
|
||||
visualizeOrganisation();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(VolleyError volleyError) {
|
||||
makeSnackBar(ReadableError.toReadable(volleyError));
|
||||
progressBar.setVisibility(View.GONE);
|
||||
organisationView.setVisibility(View.GONE);
|
||||
emptyView.setVisibility(View.VISIBLE);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(VolleyError volleyError) {
|
||||
makeSnackBar(ReadableError.toReadable(volleyError));
|
||||
progressBar.setVisibility(View.GONE);
|
||||
organisationView.setVisibility(View.GONE);
|
||||
emptyView.setVisibility(View.VISIBLE);
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
private void visualizeOrganisation() {
|
||||
|
||||
TextView title = organisationView.findViewById(R.id.organisation_title);
|
||||
title.setText(myOrganisation.getName());
|
||||
|
||||
TextView uuid = organisationView.findViewById(R.id.organisation_uuid);
|
||||
uuid.setText(myOrganisation.getUuid());
|
||||
|
||||
TextView description = organisationView.findViewById(R.id.organisation_description);
|
||||
description.setText(myOrganisation.getDescription());
|
||||
|
||||
TextView nationality = organisationView.findViewById(R.id.organisation_nationality);
|
||||
nationality.setText(myOrganisation.getNationality());
|
||||
|
||||
TextView sector = findViewById(R.id.organisation_sector);
|
||||
sector.setText(myOrganisation.getSector());
|
||||
|
||||
TextView users = findViewById(R.id.organisation_user_count);
|
||||
|
||||
users.setText("" + myOrganisation.getUserCount());
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
int id = v.getId();
|
||||
|
||||
switch (id) {
|
||||
case R.id.fab_download_own_org_info:
|
||||
tryDownloadOrgInfo();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
getMenuInflater().inflate(R.menu.menu_credentials, menu);
|
||||
return super.onCreateOptionsMenu(menu);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
|
||||
int id = item.getItemId();
|
||||
|
||||
switch (id) {
|
||||
case android.R.id.home:
|
||||
exitSafely();
|
||||
return true;
|
||||
|
||||
// case R.id.menu_item_deleteData:
|
||||
// DialogInterface.OnClickListener pos = new DialogInterface.OnClickListener() {
|
||||
// @Override
|
||||
// public void onClick(DialogInterface dialog, int which) {
|
||||
// PreferenceManager.Instance(getApplicationContext()).clearCredentialPreferences();
|
||||
// urlLayout.getEditText().setText("");
|
||||
// apiLayout.getEditText().setText("");
|
||||
// myOrganisation = null;
|
||||
// myUser = null;
|
||||
// emptyView.setVisibility(View.VISIBLE);
|
||||
// organisationView.setVisibility(View.GONE);
|
||||
// }
|
||||
// };
|
||||
//
|
||||
// new DialogFactory(this).createDeleteDialog(pos, null).show();
|
||||
//
|
||||
// break;
|
||||
|
||||
case R.id.load_config:
|
||||
|
||||
// MOTOROLA
|
||||
if (Build.VERSION.SDK_INT <= 25) {
|
||||
urlLayout.getEditText().setText("http://192.168.178.200");
|
||||
apiLayout.getEditText().setText("dcfgDrNy3SyASmo9WRqyJ4LhsN1xWJ7phfTjklFa");
|
||||
} else {
|
||||
urlLayout.getEditText().setText("http://192.168.178.201");
|
||||
apiLayout.getEditText().setText("5BGhMzdHIWvaxyrTUUVNk2NflDPzXJRZQvOa3CE2");
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBackPressed() {
|
||||
exitSafely();
|
||||
}
|
||||
|
||||
private void exitSafely() {
|
||||
|
||||
if (changesMade || !saveAuthkeyPrefSet) {
|
||||
saveDialog(new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
savePreferences();
|
||||
finish();
|
||||
}
|
||||
}, new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
finish();
|
||||
}
|
||||
});
|
||||
} else {
|
||||
finish();
|
||||
}
|
||||
}
|
||||
|
||||
private void makeSnackBar(String message) {
|
||||
Snackbar.make(findViewById(R.id.coordinator), message, Snackbar.LENGTH_LONG).show();
|
||||
}
|
||||
|
||||
private void saveDialog(DialogInterface.OnClickListener positive, DialogInterface.OnClickListener negative) {
|
||||
AlertDialog.Builder adb = new AlertDialog.Builder(this);
|
||||
|
||||
adb.setTitle(getResources().getString(R.string.unsaved_changes));
|
||||
adb.setMessage("\n" + getResources().getString(R.string.save_changes));
|
||||
|
||||
@SuppressLint("InflateParams")
|
||||
View checkBoxView = getLayoutInflater().inflate(R.layout.dialog_save_authkey, null);
|
||||
CheckBox c = checkBoxView.findViewById(R.id.checkbox);
|
||||
c.setChecked(saveAuthkey);
|
||||
|
||||
c.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
|
||||
@Override
|
||||
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
|
||||
saveAuthkey = isChecked;
|
||||
}
|
||||
});
|
||||
|
||||
adb.setView(checkBoxView);
|
||||
|
||||
adb.setPositiveButton(getResources().getString(R.string.save), positive);
|
||||
adb.setNegativeButton(getResources().getString(R.string.discard), negative);
|
||||
|
||||
Dialog d = adb.create();
|
||||
d.setCancelable(false);
|
||||
d.getWindow().setWindowAnimations(R.style.DialogAnimation);
|
||||
d.show();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,185 @@
|
|||
package de.overview.wg.its.mispauth;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
import android.app.Dialog;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.graphics.drawable.Drawable;
|
||||
import android.os.Bundle;
|
||||
import android.support.design.widget.FloatingActionButton;
|
||||
import android.support.v4.content.ContextCompat;
|
||||
import android.support.v4.graphics.drawable.DrawableCompat;
|
||||
import android.support.v7.app.AlertDialog;
|
||||
import android.support.v7.app.AppCompatActivity;
|
||||
import android.support.v7.widget.DefaultItemAnimator;
|
||||
import android.support.v7.widget.LinearLayoutManager;
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
import android.support.v7.widget.Toolbar;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.widget.CheckBox;
|
||||
import android.widget.TextView;
|
||||
import de.overview.wg.its.mispauth.adapter.SyncedPartnerAdapter;
|
||||
import de.overview.wg.its.mispauth.auxiliary.PreferenceManager;
|
||||
import de.overview.wg.its.mispauth.model.SyncedPartner;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@SuppressWarnings("ConstantConditions")
|
||||
public class MainActivity extends AppCompatActivity {
|
||||
|
||||
private List<SyncedPartner> syncedPartnerList = new ArrayList<>();
|
||||
private SyncedPartnerAdapter syncedPartnerAdapter;
|
||||
private TextView emptyPartnerListView;
|
||||
private RecyclerView syncedPartnerRecyclerView;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_main);
|
||||
|
||||
initializeViews();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
getMenuInflater().inflate(R.menu.menu_main, menu);
|
||||
|
||||
// Make icon white (compat limitation in xml)
|
||||
Drawable drawable = menu.findItem(R.id.menu_item_credential_settings).getIcon();
|
||||
drawable = DrawableCompat.wrap(drawable);
|
||||
DrawableCompat.setTint(drawable, ContextCompat.getColor(this, R.color.colorWhite));
|
||||
menu.findItem(R.id.menu_item_credential_settings).setIcon(drawable);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
int id = item.getItemId();
|
||||
|
||||
switch (id) {
|
||||
case R.id.menu_item_credential_settings:
|
||||
startActivity(new Intent(this, CredentialsActivity.class));
|
||||
return true;
|
||||
|
||||
case R.id.menu_item_delete_local_data:
|
||||
createSelectDeleteDialog();
|
||||
return true;
|
||||
}
|
||||
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
|
||||
private void initializeViews() {
|
||||
|
||||
Toolbar toolbar = findViewById(R.id.toolbar);
|
||||
setSupportActionBar(toolbar);
|
||||
getSupportActionBar().setDisplayShowTitleEnabled(true);
|
||||
|
||||
FloatingActionButton fab = findViewById(R.id.fab);
|
||||
fab.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
startSyncActivity();
|
||||
}
|
||||
});
|
||||
|
||||
emptyPartnerListView = findViewById(R.id.empty);
|
||||
syncedPartnerRecyclerView = findViewById(R.id.recyclerView);
|
||||
|
||||
syncedPartnerAdapter = new SyncedPartnerAdapter(this, syncedPartnerList);
|
||||
RecyclerView.LayoutManager mLayoutManager = new LinearLayoutManager(getApplicationContext());
|
||||
syncedPartnerRecyclerView.setLayoutManager(mLayoutManager);
|
||||
syncedPartnerRecyclerView.setItemAnimator(new DefaultItemAnimator());
|
||||
syncedPartnerRecyclerView.setAdapter(syncedPartnerAdapter);
|
||||
|
||||
refreshSyncedPartnerList();
|
||||
}
|
||||
|
||||
private void createSelectDeleteDialog() {
|
||||
|
||||
final PreferenceManager prefs = PreferenceManager.Instance(this);
|
||||
|
||||
AlertDialog.Builder adb = new AlertDialog.Builder(this);
|
||||
|
||||
adb.setTitle("Delete Local Data");
|
||||
adb.setMessage("(Checked items will be deleted)");
|
||||
|
||||
@SuppressLint("InflateParams")
|
||||
View checkBoxView = getLayoutInflater().inflate(R.layout.dialog_select_delete_data, null);
|
||||
|
||||
final CheckBox checkSyncedPartner = checkBoxView.findViewById(R.id.check_synced_partner_list);
|
||||
final CheckBox checkCredentials = checkBoxView.findViewById(R.id.check_credentials);
|
||||
final CheckBox checkUserData = checkBoxView.findViewById(R.id.check_user_preferences);
|
||||
|
||||
adb.setView(checkBoxView);
|
||||
|
||||
adb.setPositiveButton(getResources().getString(R.string.delete), new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
if (checkSyncedPartner.isChecked()) {
|
||||
prefs.clearSyncedInformationPreferences();
|
||||
}
|
||||
|
||||
if (checkCredentials.isChecked()) {
|
||||
prefs.clearCredentialPreferences();
|
||||
}
|
||||
|
||||
if (checkUserData.isChecked()) {
|
||||
prefs.clearUserPreferences();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
adb.setNegativeButton(getResources().getString(android.R.string.cancel), null);
|
||||
|
||||
Dialog d = adb.create();
|
||||
d.getWindow().setWindowAnimations(R.style.DialogAnimation);
|
||||
d.show();
|
||||
}
|
||||
|
||||
private void refreshSyncedPartnerList() {
|
||||
syncedPartnerList = PreferenceManager.Instance(this).getSyncedPartnerList();
|
||||
|
||||
if (syncedPartnerList == null) {
|
||||
emptyPartnerListView.setVisibility(View.VISIBLE);
|
||||
syncedPartnerRecyclerView.setVisibility(View.GONE);
|
||||
} else {
|
||||
syncedPartnerAdapter.setSyncedPartnerList(syncedPartnerList);
|
||||
}
|
||||
}
|
||||
|
||||
private void startSyncActivity() {
|
||||
|
||||
PreferenceManager preferenceManager = PreferenceManager.Instance(this);
|
||||
|
||||
if (preferenceManager.getMyOrganisation() == null || preferenceManager.getMyUser() == null) {
|
||||
|
||||
AlertDialog.Builder adb = new AlertDialog.Builder(this);
|
||||
adb.setTitle(getResources().getString(R.string.missing_local_information_title));
|
||||
adb.setMessage(getResources().getString(R.string.missing_local_information_message));
|
||||
|
||||
adb.setPositiveButton(getResources().getString(R.string.enter_credentials), new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
startCredentialsActivity();
|
||||
}
|
||||
});
|
||||
|
||||
adb.setNegativeButton(android.R.string.cancel, null);
|
||||
adb.show();
|
||||
|
||||
} else {
|
||||
Intent intent = new Intent(this, SyncActivity.class);
|
||||
startActivity(intent);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void startCredentialsActivity() {
|
||||
startActivity(new Intent(this, CredentialsActivity.class));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,281 @@
|
|||
package de.overview.wg.its.mispauth;
|
||||
|
||||
import android.animation.Animator;
|
||||
import android.content.Intent;
|
||||
import android.graphics.Point;
|
||||
import android.os.Bundle;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.support.v4.app.FragmentManager;
|
||||
import android.support.v4.app.FragmentTransaction;
|
||||
import android.support.v7.app.AppCompatActivity;
|
||||
import android.view.Display;
|
||||
import android.view.View;
|
||||
import android.view.ViewAnimationUtils;
|
||||
import android.view.WindowManager;
|
||||
import android.view.animation.DecelerateInterpolator;
|
||||
import android.widget.*;
|
||||
import com.google.gson.Gson;
|
||||
import de.overview.wg.its.mispauth.auxiliary.AESSecurity;
|
||||
import de.overview.wg.its.mispauth.auxiliary.PreferenceManager;
|
||||
import de.overview.wg.its.mispauth.auxiliary.RandomString;
|
||||
import de.overview.wg.its.mispauth.auxiliary.TempAuth;
|
||||
import de.overview.wg.its.mispauth.cam.CameraFragment;
|
||||
import de.overview.wg.its.mispauth.model.*;
|
||||
import net.glxn.qrgen.android.QRCode;
|
||||
|
||||
public class SyncActivity extends AppCompatActivity implements View.OnClickListener {
|
||||
|
||||
private static final String SCAN_PUB_KEY_FRAG_TAG = "scan_public_key_fragment_tag";
|
||||
private static final String SCAN_INFO_FRAG_TAG = "scan_info_fragment_tag";
|
||||
|
||||
private AESSecurity aesSecurity;
|
||||
|
||||
private Fragment currentFragment;
|
||||
private String currentFragmentTag;
|
||||
|
||||
// Views for QR code
|
||||
private LinearLayout qrBackground;
|
||||
private ImageView qrImageView;
|
||||
private Button forwardButton;
|
||||
private TextView forwardDescription;
|
||||
|
||||
private SyncInformationQr partnerInformation;
|
||||
|
||||
private FragmentManager manager;
|
||||
private FragmentTransaction transaction;
|
||||
private PreferenceManager preferenceManager;
|
||||
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
|
||||
super.onCreate(savedInstanceState);
|
||||
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
|
||||
setContentView(R.layout.activity_public_key_exchange);
|
||||
|
||||
manager = getSupportFragmentManager();
|
||||
preferenceManager = PreferenceManager.Instance(this);
|
||||
|
||||
initializeViews();
|
||||
|
||||
aesSecurity = AESSecurity.getInstance();
|
||||
|
||||
setScanTypeFragment(0);
|
||||
}
|
||||
|
||||
private void initializeViews() {
|
||||
|
||||
ImageButton closeButton = findViewById(R.id.close);
|
||||
forwardButton = findViewById(R.id.forward);
|
||||
|
||||
closeButton.setOnClickListener(this);
|
||||
|
||||
forwardButton.setOnClickListener(this);
|
||||
forwardButton.setEnabled(false);
|
||||
forwardDescription = findViewById(R.id.forward_description);
|
||||
|
||||
qrImageView = findViewById(R.id.qr_imageView);
|
||||
qrBackground = findViewById(R.id.qr_background);
|
||||
|
||||
setContinueScreenEnabled(false);
|
||||
}
|
||||
|
||||
private void setScanTypeFragment(int mode) {
|
||||
|
||||
transaction = manager.beginTransaction();
|
||||
|
||||
User myUser = preferenceManager.getMyUser();
|
||||
Organisation myOrg = preferenceManager.getMyOrganisation();
|
||||
|
||||
switch (mode) {
|
||||
|
||||
case 0:
|
||||
|
||||
setContinueScreenEnabled(false);
|
||||
|
||||
PublicKeyQr pkqr = new PublicKeyQr(myOrg.getName(),
|
||||
myUser.getEmail(),
|
||||
AESSecurity.publicKeyToString(aesSecurity.getPublicKey()));
|
||||
|
||||
setQrContent(pkqr.toJSON().toString(), 0.6f);
|
||||
|
||||
currentFragment = CameraFragment.newInstance(CameraFragment.ScanMode.PUBLIC_KEY);
|
||||
currentFragmentTag = SCAN_PUB_KEY_FRAG_TAG;
|
||||
|
||||
break;
|
||||
|
||||
case 1:
|
||||
|
||||
setContinueScreenEnabled(false);
|
||||
|
||||
TempAuth.TMP_AUTH_KEY = new RandomString(40).nextString();
|
||||
|
||||
Server serverForMeOnOtherInstance = new Server();
|
||||
serverForMeOnOtherInstance.setAuthkey(TempAuth.TMP_AUTH_KEY);
|
||||
serverForMeOnOtherInstance.setName("SyncServer for " + myOrg.getName());
|
||||
serverForMeOnOtherInstance.setUrl(preferenceManager.getMyServerUrl());
|
||||
|
||||
SyncInformationQr siqr = new SyncInformationQr(
|
||||
preferenceManager.getMyOrganisation(),
|
||||
serverForMeOnOtherInstance,
|
||||
preferenceManager.getMyUser());
|
||||
|
||||
setQrContent(aesSecurity.encrypt(siqr.toJSON().toString()), 0.9f);
|
||||
|
||||
currentFragment = CameraFragment.newInstance(CameraFragment.ScanMode.INFO);
|
||||
currentFragmentTag = SCAN_INFO_FRAG_TAG;
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
transaction.remove(currentFragment);
|
||||
transaction.commit();
|
||||
|
||||
currentFragment = null;
|
||||
|
||||
finish();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
transaction.replace(R.id.fragment_container, currentFragment, currentFragmentTag);
|
||||
transaction.commit();
|
||||
}
|
||||
|
||||
private void setQrContent(String content, float qrToScreenRatio) {
|
||||
|
||||
Display display = getWindowManager().getDefaultDisplay();
|
||||
Point size = new Point();
|
||||
display.getSize(size);
|
||||
|
||||
int width = (int) (size.x * qrToScreenRatio);
|
||||
|
||||
//noinspection SuspiciousNameCombination
|
||||
qrImageView.setImageBitmap(QRCode.from(content)
|
||||
.withColor(0xFF000000, 0x00FFFFFF)
|
||||
.withSize(width, width)
|
||||
.bitmap());
|
||||
|
||||
circularReveal(qrBackground, true, 400);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
|
||||
switch (v.getId()) {
|
||||
|
||||
case R.id.close:
|
||||
finish();
|
||||
break;
|
||||
|
||||
case R.id.forward:
|
||||
|
||||
if (currentFragmentTag.equals(SCAN_PUB_KEY_FRAG_TAG)) {
|
||||
setScanTypeFragment(1);
|
||||
} else if (currentFragmentTag.equals(SCAN_INFO_FRAG_TAG)) {
|
||||
startUploadActivity();
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private void setContinueScreenEnabled(boolean enabled) {
|
||||
if (enabled) {
|
||||
forwardButton.setVisibility(View.VISIBLE);
|
||||
forwardDescription.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
forwardButton.setVisibility(View.INVISIBLE);
|
||||
forwardDescription.setVisibility(View.INVISIBLE);
|
||||
}
|
||||
|
||||
forwardButton.setEnabled(enabled);
|
||||
}
|
||||
|
||||
public void onPublicKeyResult(PublicKeyQr pkqr) {
|
||||
aesSecurity.setForeignPublicKey(AESSecurity.publicKeyFromString(pkqr.getKey()));
|
||||
|
||||
runOnUiThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
setContinueScreenEnabled(true);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void onSyncInfoResult(SyncInformationQr siqr) {
|
||||
partnerInformation = siqr;
|
||||
|
||||
runOnUiThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
setContinueScreenEnabled(true);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void startUploadActivity() {
|
||||
|
||||
Intent i = new Intent(this, UploadActivity.class);
|
||||
String partnerString = new Gson().toJson(partnerInformation);
|
||||
i.putExtra(UploadActivity.PARTNER_INFO_BUNDLE_KEY, partnerString);
|
||||
|
||||
startActivity(i);
|
||||
finish();
|
||||
|
||||
}
|
||||
|
||||
private void circularReveal(final View v, final boolean open, final long duration) {
|
||||
|
||||
v.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
int cx = v.getWidth() / 2;
|
||||
int cy = v.getHeight() / 2;
|
||||
|
||||
float finalRadius = (float) Math.hypot(cx, cy);
|
||||
|
||||
Animator anim;
|
||||
|
||||
|
||||
if (open) {
|
||||
anim = ViewAnimationUtils.createCircularReveal(v, cx, cy, 0, finalRadius);
|
||||
v.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
anim = ViewAnimationUtils.createCircularReveal(v, cx, cy, finalRadius, 0);
|
||||
}
|
||||
|
||||
anim.setInterpolator(new DecelerateInterpolator());
|
||||
|
||||
anim.setDuration(duration);
|
||||
anim.addListener(new Animator.AnimatorListener() {
|
||||
@Override
|
||||
public void onAnimationStart(Animator animation) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAnimationEnd(Animator animation) {
|
||||
if (!open) {
|
||||
v.setVisibility(View.INVISIBLE);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAnimationCancel(Animator animation) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onAnimationRepeat(Animator animation) {
|
||||
|
||||
}
|
||||
});
|
||||
anim.start();
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
}
|
|
@ -0,0 +1,240 @@
|
|||
package de.overview.wg.its.mispauth;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.support.design.widget.FloatingActionButton;
|
||||
import android.support.v7.app.AppCompatActivity;
|
||||
import android.support.v7.widget.DefaultItemAnimator;
|
||||
import android.support.v7.widget.LinearLayoutManager;
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
import android.support.v7.widget.Toolbar;
|
||||
import android.view.View;
|
||||
import com.android.volley.VolleyError;
|
||||
import com.google.gson.Gson;
|
||||
import de.overview.wg.its.mispauth.adapter.UploadStateAdapter;
|
||||
import de.overview.wg.its.mispauth.auxiliary.PreferenceManager;
|
||||
import de.overview.wg.its.mispauth.auxiliary.ReadableError;
|
||||
import de.overview.wg.its.mispauth.auxiliary.TempAuth;
|
||||
import de.overview.wg.its.mispauth.model.*;
|
||||
import de.overview.wg.its.mispauth.network.MispRequest;
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@SuppressWarnings("ConstantConditions")
|
||||
public class UploadActivity extends AppCompatActivity implements View.OnClickListener {
|
||||
|
||||
static final String PARTNER_INFO_BUNDLE_KEY = "partner_info";
|
||||
|
||||
private MispRequest mispRequest;
|
||||
private SyncInformationQr partnerInformation;
|
||||
|
||||
private Organisation partnerOrganisation;
|
||||
private User partnerSyncUser;
|
||||
private Server partnerServer;
|
||||
|
||||
private UploadStateAdapter uploadStateAdapter;
|
||||
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_upload);
|
||||
|
||||
Bundle b = getIntent().getExtras();
|
||||
assert b != null;
|
||||
String info = b.getString(PARTNER_INFO_BUNDLE_KEY);
|
||||
|
||||
partnerInformation = new Gson().fromJson(info, SyncInformationQr.class);
|
||||
|
||||
mispRequest = MispRequest.Instance(this);
|
||||
|
||||
initializeViews();
|
||||
|
||||
SyncUpload();
|
||||
}
|
||||
|
||||
private void initializeViews() {
|
||||
|
||||
Toolbar toolbar = findViewById(R.id.toolbar);
|
||||
setSupportActionBar(toolbar);
|
||||
|
||||
getSupportActionBar().setDisplayShowHomeEnabled(false);
|
||||
getSupportActionBar().setDisplayHomeAsUpEnabled(false);
|
||||
getSupportActionBar().setDisplayShowTitleEnabled(true);
|
||||
|
||||
FloatingActionButton fab = findViewById(R.id.fab);
|
||||
fab.setOnClickListener(this);
|
||||
|
||||
RecyclerView recyclerView = findViewById(R.id.recyclerView);
|
||||
uploadStateAdapter = new UploadStateAdapter();
|
||||
RecyclerView.LayoutManager mLayoutManager = new LinearLayoutManager(this);
|
||||
recyclerView.setLayoutManager(mLayoutManager);
|
||||
recyclerView.setItemAnimator(new DefaultItemAnimator());
|
||||
recyclerView.setAdapter(uploadStateAdapter);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
|
||||
int id = v.getId();
|
||||
|
||||
switch (id) {
|
||||
case R.id.fab:
|
||||
finish();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private void setCurrentStateWrapper(int stateNumber, UploadState.State state) {
|
||||
syncUploadStates.get(stateNumber).setCurrentState(state);
|
||||
uploadStateAdapter.notifyItemChanged(stateNumber);
|
||||
}
|
||||
|
||||
private List<UploadState> syncUploadStates = new ArrayList<>();
|
||||
|
||||
private void SyncUpload() {
|
||||
|
||||
partnerOrganisation = partnerInformation.getOrganisation();
|
||||
partnerSyncUser = partnerInformation.getUser();
|
||||
partnerServer = partnerInformation.getServer();
|
||||
|
||||
syncUploadStates.add(new UploadState("Add local organisation"));
|
||||
syncUploadStates.add(new UploadState("Add sync user to organisation"));
|
||||
syncUploadStates.add(new UploadState("Add external organisation"));
|
||||
syncUploadStates.add(new UploadState("Add sync server"));
|
||||
|
||||
uploadStateAdapter.setStateList(syncUploadStates);
|
||||
|
||||
uploadSyncOrganisation();
|
||||
}
|
||||
|
||||
private void uploadSyncOrganisation() {
|
||||
setCurrentStateWrapper(0, UploadState.State.IN_PROGRESS);
|
||||
// syncUploadStates.get(0).setCurrentState(UploadState.State.IN_PROGRESS);
|
||||
mispRequest.addOrganisation(partnerOrganisation, new MispRequest.OrganisationCallback() {
|
||||
@Override
|
||||
public void onResult(JSONObject organisationInformation) {
|
||||
try {
|
||||
|
||||
Organisation retOrg = new Organisation(organisationInformation);
|
||||
setCurrentStateWrapper(0, UploadState.State.DONE);
|
||||
// syncUploadStates.get(0).setCurrentState(UploadState.State.DONE);
|
||||
uploadSyncUser(retOrg.getId());
|
||||
|
||||
} catch (JSONException e) {
|
||||
syncUploadStates.get(0).setError("Could not read server response");
|
||||
setCurrentStateWrapper(0, UploadState.State.ERROR);
|
||||
// syncUploadStates.get(0).setCurrentState(UploadState.State.ERROR);
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(VolleyError volleyError) {
|
||||
syncUploadStates.get(0).setError(ReadableError.toReadable(volleyError));
|
||||
setCurrentStateWrapper(0, UploadState.State.ERROR);
|
||||
// syncUploadStates.get(0).setCurrentState(UploadState.State.ERROR);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void uploadSyncUser(int orgID) {
|
||||
|
||||
setCurrentStateWrapper(1, UploadState.State.IN_PROGRESS);
|
||||
// syncUploadStates.get(1).setCurrentState(UploadState.State.IN_PROGRESS);
|
||||
|
||||
partnerSyncUser.setOrgId(orgID);
|
||||
partnerSyncUser.setAuthkey(TempAuth.TMP_AUTH_KEY);
|
||||
partnerSyncUser.setRoleId(User.RoleId.SYNC_USER);
|
||||
|
||||
mispRequest.addUser(partnerSyncUser, new MispRequest.UserCallback() {
|
||||
@Override
|
||||
public void onResult(JSONObject myUserInformation) {
|
||||
setCurrentStateWrapper(1, UploadState.State.DONE);
|
||||
// syncUploadStates.get(1).setCurrentState(UploadState.State.DONE);
|
||||
uploadExternalSyncOrganisation();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(VolleyError volleyError) {
|
||||
syncUploadStates.get(1).setError(ReadableError.toReadable(volleyError));
|
||||
setCurrentStateWrapper(1, UploadState.State.ERROR);
|
||||
// syncUploadStates.get(1).setCurrentState(UploadState.State.ERROR);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void uploadExternalSyncOrganisation() {
|
||||
|
||||
setCurrentStateWrapper(2, UploadState.State.IN_PROGRESS);
|
||||
|
||||
partnerOrganisation.setName(partnerOrganisation.getName() + " (Remote)");
|
||||
partnerOrganisation.setLocal(false);
|
||||
|
||||
mispRequest.addOrganisation(partnerOrganisation, new MispRequest.OrganisationCallback() {
|
||||
@Override
|
||||
public void onResult(JSONObject organisationInformation) {
|
||||
try {
|
||||
|
||||
Organisation extOrg = new Organisation(organisationInformation);
|
||||
setCurrentStateWrapper(2, UploadState.State.DONE);
|
||||
uploadSyncServer(extOrg.getId());
|
||||
|
||||
} catch (JSONException e) {
|
||||
syncUploadStates.get(2).setError("Could not read server response");
|
||||
setCurrentStateWrapper(2, UploadState.State.ERROR);
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(VolleyError volleyError) {
|
||||
syncUploadStates.get(2).setError(ReadableError.toReadable(volleyError));
|
||||
setCurrentStateWrapper(2, UploadState.State.ERROR);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void uploadSyncServer(int remoteOrgId) {
|
||||
|
||||
setCurrentStateWrapper(3, UploadState.State.IN_PROGRESS);
|
||||
|
||||
partnerServer.setRemoteOrgId(remoteOrgId);
|
||||
partnerServer.setPush(true);
|
||||
|
||||
mispRequest.addServer(partnerServer, new MispRequest.ServerCallback() {
|
||||
@Override
|
||||
public void onResult(JSONObject servers) {
|
||||
setCurrentStateWrapper(3, UploadState.State.DONE);
|
||||
updateSyncedOrganisationList();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(VolleyError volleyError) {
|
||||
syncUploadStates.get(3).setError(ReadableError.toReadable(volleyError));
|
||||
setCurrentStateWrapper(3, UploadState.State.ERROR);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void updateSyncedOrganisationList() {
|
||||
|
||||
PreferenceManager preferenceManager = PreferenceManager.Instance(this);
|
||||
|
||||
List<SyncedPartner> syncedPartnerList = preferenceManager.getSyncedPartnerList();
|
||||
|
||||
if (syncedPartnerList == null) {
|
||||
syncedPartnerList = new ArrayList<>();
|
||||
}
|
||||
|
||||
SyncedPartner sp = new SyncedPartner(
|
||||
partnerInformation.getOrganisation().getName(),
|
||||
partnerInformation.getServer().getUrl());
|
||||
|
||||
sp.generateTimeStamp();
|
||||
syncedPartnerList.add(sp);
|
||||
preferenceManager.setSyncedPartnerList(syncedPartnerList);
|
||||
}
|
||||
}
|
|
@ -1,125 +0,0 @@
|
|||
package de.overview.wg.its.mispauth.activity;
|
||||
|
||||
import android.content.Intent;
|
||||
import android.os.Bundle;
|
||||
import android.support.design.widget.FloatingActionButton;
|
||||
import android.support.v4.widget.SwipeRefreshLayout;
|
||||
import android.support.v7.app.AppCompatActivity;
|
||||
import android.support.v7.widget.DividerItemDecoration;
|
||||
import android.support.v7.widget.LinearLayoutManager;
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
import android.support.v7.widget.Toolbar;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.widget.Toast;
|
||||
import com.android.volley.VolleyError;
|
||||
import de.overview.wg.its.mispauth.R;
|
||||
import de.overview.wg.its.mispauth.adapter.ExtOrgAdapter;
|
||||
import de.overview.wg.its.mispauth.auxiliary.PreferenceManager;
|
||||
import de.overview.wg.its.mispauth.auxiliary.ReadableError;
|
||||
import de.overview.wg.its.mispauth.model.Organisation;
|
||||
import de.overview.wg.its.mispauth.network.MispRequest;
|
||||
import org.json.JSONObject;
|
||||
|
||||
public class MainActivity extends AppCompatActivity {
|
||||
|
||||
private Organisation[] externalOrganisations;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_main);
|
||||
|
||||
Toolbar toolbar = findViewById(R.id.toolbar);
|
||||
setSupportActionBar(toolbar);
|
||||
|
||||
getExternalOrganisations();
|
||||
setUpRecyclerView();
|
||||
|
||||
FloatingActionButton fabAdd = findViewById(R.id.fab_add);
|
||||
final FloatingActionButton fabSync = findViewById(R.id.fab_sync);
|
||||
|
||||
fabAdd.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
if (fabSync.getVisibility() == View.GONE) {
|
||||
fabSync.setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
fabSync.setVisibility(View.GONE);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
fabSync.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
startSyncActivity();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
getMenuInflater().inflate(R.menu.menu_main, menu);
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
int id = item.getItemId();
|
||||
|
||||
if (id == R.id.menu_item_settings) {
|
||||
startActivity(new Intent(this, SettingsActivity.class));
|
||||
return true;
|
||||
}
|
||||
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
|
||||
private void setUpRecyclerView() {
|
||||
RecyclerView orgRecyclerView = findViewById(R.id.orgRecyclerView);
|
||||
orgRecyclerView.setHasFixedSize(true);
|
||||
|
||||
RecyclerView.LayoutManager orgLayoutManager = new LinearLayoutManager(this);
|
||||
orgRecyclerView.setLayoutManager(orgLayoutManager);
|
||||
|
||||
DividerItemDecoration dividerItemDecoration = new DividerItemDecoration(orgRecyclerView.getContext(), 1);
|
||||
orgRecyclerView.addItemDecoration(dividerItemDecoration);
|
||||
|
||||
RecyclerView.Adapter orgAdapter = new ExtOrgAdapter(this, externalOrganisations);
|
||||
orgRecyclerView.setAdapter(orgAdapter);
|
||||
|
||||
if (externalOrganisations.length == 0) {
|
||||
orgRecyclerView.setVisibility(View.GONE);
|
||||
findViewById(R.id.empty_view).setVisibility(View.VISIBLE);
|
||||
} else {
|
||||
orgRecyclerView.setVisibility(View.VISIBLE);
|
||||
findViewById(R.id.empty_view).setVisibility(View.GONE);
|
||||
}
|
||||
|
||||
final SwipeRefreshLayout refreshLayout = findViewById(R.id.recycler_refresh);
|
||||
refreshLayout.setOnRefreshListener(new SwipeRefreshLayout.OnRefreshListener() {
|
||||
@Override
|
||||
public void onRefresh() {
|
||||
// TODO do stuff
|
||||
// refreshLayout.setRefreshing(false);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private void getExternalOrganisations() {
|
||||
Organisation a = new Organisation();
|
||||
a.setName("Ferrari");
|
||||
a.setDescription("Ferrari has nothing to share");
|
||||
a.setSector("Fast cars");
|
||||
a.setNationality("Italy");
|
||||
a.setLocal(true);
|
||||
|
||||
externalOrganisations = new Organisation[]{a};
|
||||
}
|
||||
|
||||
private void startSyncActivity() {
|
||||
startActivity(new Intent(this, SyncActivity.class));
|
||||
}
|
||||
}
|
|
@ -1,211 +0,0 @@
|
|||
package de.overview.wg.its.mispauth.activity;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.support.design.widget.Snackbar;
|
||||
import android.support.design.widget.TextInputLayout;
|
||||
import android.support.v7.app.AppCompatActivity;
|
||||
import android.support.v7.widget.Toolbar;
|
||||
import android.util.Log;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.view.inputmethod.InputMethodManager;
|
||||
import android.widget.EditText;
|
||||
import android.widget.ProgressBar;
|
||||
import android.widget.TextView;
|
||||
import com.android.volley.VolleyError;
|
||||
import de.overview.wg.its.mispauth.R;
|
||||
import de.overview.wg.its.mispauth.auxiliary.PreferenceManager;
|
||||
import de.overview.wg.its.mispauth.auxiliary.ReadableError;
|
||||
import de.overview.wg.its.mispauth.model.Organisation;
|
||||
import de.overview.wg.its.mispauth.model.User;
|
||||
import de.overview.wg.its.mispauth.network.MispRequest;
|
||||
import org.json.JSONObject;
|
||||
|
||||
public class SettingsActivity extends AppCompatActivity {
|
||||
|
||||
private static final String TAG = "DEBUG";
|
||||
|
||||
private PreferenceManager preferenceManager;
|
||||
private ProgressBar progressBar;
|
||||
private TextInputLayout serverUrlLayout, apiKeyLayout;
|
||||
private EditText serverUrlText, apiKeyText;
|
||||
|
||||
private Organisation org;
|
||||
private User user;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_settings);
|
||||
|
||||
Toolbar toolbar = findViewById(R.id.toolbar);
|
||||
setSupportActionBar(toolbar);
|
||||
|
||||
getSupportActionBar().setDisplayShowHomeEnabled(true);
|
||||
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
|
||||
|
||||
serverUrlLayout = findViewById(R.id.input_layout_server_url);
|
||||
apiKeyLayout = findViewById(R.id.input_layout_api_key);
|
||||
serverUrlText = findViewById(R.id.edit_server_url);
|
||||
apiKeyText = findViewById(R.id.edit_api_key);
|
||||
progressBar = findViewById(R.id.progressBar);
|
||||
|
||||
findViewById(R.id.fab_download_own_org_info).setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
downloadMyOrgInfo();
|
||||
}
|
||||
});
|
||||
|
||||
apiKeyText.setOnKeyListener(new View.OnKeyListener() {
|
||||
public boolean onKey(View v, int keyCode, KeyEvent event) {
|
||||
if (keyCode == 66) {
|
||||
hideKeyboard(v);
|
||||
apiKeyText.clearFocus();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
});
|
||||
|
||||
restoreSavedValues();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
getMenuInflater().inflate(R.menu.menu_settings, menu);
|
||||
return true;
|
||||
}
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
int id = item.getItemId();
|
||||
|
||||
if (id == R.id.menu_item_deleteData) {
|
||||
serverUrlText.setText("");
|
||||
apiKeyText.setText("");
|
||||
preferenceManager.deleteAllLocalData();
|
||||
return true;
|
||||
}
|
||||
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
|
||||
private void setOrganisation(Organisation org) {
|
||||
|
||||
if(org == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
TextView title = findViewById(R.id.organisation_title);
|
||||
TextView uuid = findViewById(R.id.organisation_uuid);
|
||||
TextView description = findViewById(R.id.organisation_description);
|
||||
TextView nationality = findViewById(R.id.organisation_nationality);
|
||||
TextView sector = findViewById(R.id.organisation_sector);
|
||||
TextView userCount = findViewById(R.id.organisation_user_count);
|
||||
|
||||
title.setText(org.getName());
|
||||
uuid.setText(org.getUuid());
|
||||
description.setText(org.getDescription());
|
||||
nationality.setText(org.getNationality());
|
||||
sector.setText(org.getSector());
|
||||
userCount.setText("" + org.getUserCount());
|
||||
}
|
||||
|
||||
private void restoreSavedValues() {
|
||||
preferenceManager = PreferenceManager.Instance(this);
|
||||
|
||||
serverUrlText.setText(preferenceManager.getMyServerUrl());
|
||||
apiKeyText.setText(preferenceManager.getMyServerApiKey());
|
||||
|
||||
setOrganisation(preferenceManager.getMyOrganisation());
|
||||
}
|
||||
|
||||
private void downloadMyOrgInfo(){
|
||||
user = new User();
|
||||
org = new Organisation();
|
||||
|
||||
boolean failed = false;
|
||||
|
||||
String tmpServerUrl = serverUrlText.getText().toString();
|
||||
String tmpApiKey = apiKeyText.getText().toString();
|
||||
|
||||
if(tmpServerUrl.isEmpty()) {
|
||||
serverUrlLayout.setError("Server URL is required");
|
||||
failed = true;
|
||||
}
|
||||
|
||||
if(tmpApiKey.isEmpty()) {
|
||||
apiKeyLayout.setError("API Key is required");
|
||||
failed = true;
|
||||
}
|
||||
|
||||
if(failed) {
|
||||
return;
|
||||
} else {
|
||||
serverUrlLayout.setError(null);
|
||||
apiKeyLayout.setError(null);
|
||||
}
|
||||
|
||||
final MispRequest request = MispRequest.Instance(this);
|
||||
request.setServerCredentials(tmpServerUrl, tmpApiKey);
|
||||
|
||||
progressBar.setVisibility(View.VISIBLE);
|
||||
|
||||
request.myUserInformation(new MispRequest.UserCallback() {
|
||||
|
||||
@Override
|
||||
public void onResult(JSONObject myUserInformation) {
|
||||
|
||||
user.fromJSON(myUserInformation);
|
||||
preferenceManager.setMyUser(user);
|
||||
|
||||
int orgID = user.getOrgId();
|
||||
|
||||
request.getOrganisation(orgID, new MispRequest.OrganisationCallback() {
|
||||
|
||||
@Override
|
||||
public void onResult(JSONObject organisationInformation) {
|
||||
progressBar.setVisibility(View.GONE);
|
||||
|
||||
org.fromJSON(organisationInformation);
|
||||
|
||||
preferenceManager.setMyOrganisation(org);
|
||||
|
||||
setOrganisation(org);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(VolleyError volleyError) {
|
||||
progressBar.setVisibility(View.GONE);
|
||||
MakeSnackbar(ReadableError.toReadable(volleyError));
|
||||
Log.e(TAG, "onError: " + volleyError.toString());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(VolleyError volleyError) {
|
||||
progressBar.setVisibility(View.GONE);
|
||||
MakeSnackbar(ReadableError.toReadable(volleyError));
|
||||
}
|
||||
});
|
||||
|
||||
// If auth was successful: save new credentials
|
||||
preferenceManager.setMyServerUrl(tmpServerUrl);
|
||||
preferenceManager.setMyServerApiKey(tmpApiKey);
|
||||
}
|
||||
|
||||
private void MakeSnackbar(String msg){
|
||||
View contextView = findViewById(R.id.coordinator);
|
||||
Snackbar.make(contextView, msg, Snackbar.LENGTH_LONG).show();
|
||||
}
|
||||
|
||||
private void hideKeyboard(View view) {
|
||||
InputMethodManager manager = (InputMethodManager) view.getContext().getSystemService(INPUT_METHOD_SERVICE);
|
||||
if (manager != null) {
|
||||
manager.hideSoftInputFromWindow(view.getWindowToken(), 0);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,218 +0,0 @@
|
|||
package de.overview.wg.its.mispauth.activity;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.support.v4.app.FragmentTransaction;
|
||||
import android.support.v7.app.AppCompatActivity;
|
||||
import android.support.v7.widget.Toolbar;
|
||||
import android.view.View;
|
||||
import android.widget.Button;
|
||||
import de.overview.wg.its.mispauth.R;
|
||||
import de.overview.wg.its.mispauth.auxiliary.PreferenceManager;
|
||||
import de.overview.wg.its.mispauth.fragment.*;
|
||||
|
||||
public class SyncActivity extends AppCompatActivity {
|
||||
|
||||
private static final String TAG = "DEBUG";
|
||||
|
||||
private PreferenceManager preferenceManager;
|
||||
|
||||
private Button prevButton, nextButton;
|
||||
private int partnerChoice = -1;
|
||||
|
||||
private int currentFragmentPosition = 0;
|
||||
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.activity_sync);
|
||||
|
||||
Toolbar toolbar = findViewById(R.id.toolbar);
|
||||
setSupportActionBar(toolbar);
|
||||
getSupportActionBar().setDisplayHomeAsUpEnabled(true);
|
||||
|
||||
preferenceManager = PreferenceManager.Instance(this);
|
||||
|
||||
nextButton = findViewById(R.id.nextButton);
|
||||
prevButton = findViewById(R.id.backButton);
|
||||
|
||||
nextButton.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
getFragment(currentFragmentPosition + 1, true);
|
||||
}
|
||||
});
|
||||
prevButton.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
getFragment(currentFragmentPosition - 1, true);
|
||||
}
|
||||
});
|
||||
|
||||
getFragment(0, false);
|
||||
}
|
||||
|
||||
private void getNextFragment() {
|
||||
getFragment(currentFragmentPosition + 1, true);
|
||||
}
|
||||
|
||||
private void getFragment(int position, boolean animate) {
|
||||
|
||||
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
|
||||
|
||||
if (animate) {
|
||||
if (position > currentFragmentPosition) {
|
||||
transaction.setCustomAnimations(R.anim.enter_from_right, R.anim.exit_to_left, R.anim.enter_from_left, R.anim.exit_to_right);
|
||||
} else {
|
||||
transaction.setCustomAnimations(R.anim.enter_from_left, R.anim.exit_to_right, R.anim.enter_from_right, R.anim.exit_to_left);
|
||||
}
|
||||
}
|
||||
|
||||
currentFragmentPosition = position;
|
||||
|
||||
switch (position) {
|
||||
|
||||
case 0:
|
||||
prevButton.setEnabled(false);
|
||||
nextButton.setEnabled(false);
|
||||
|
||||
prevButton.setText(R.string.back);
|
||||
nextButton.setText(R.string.next);
|
||||
|
||||
transaction.replace(R.id.fragmentContainer, new SyncStartFragment());
|
||||
break;
|
||||
|
||||
case 1:
|
||||
prevButton.setEnabled(true);
|
||||
|
||||
prevButton.setText(R.string.back);
|
||||
nextButton.setText(R.string.next);
|
||||
|
||||
if (partnerChoice == 1) {
|
||||
|
||||
nextButton.setEnabled(false);
|
||||
transaction.replace(R.id.fragmentContainer, new ScanQrFragment(), "FRAGMENT_SCAN");
|
||||
|
||||
} else {
|
||||
|
||||
nextButton.setEnabled(true);
|
||||
transaction.replace(R.id.fragmentContainer, new ShowQrFragment(), "FRAGMENT_SHOW");
|
||||
|
||||
}
|
||||
break;
|
||||
|
||||
case 2:
|
||||
if (partnerChoice == 1) {
|
||||
|
||||
prevButton.setEnabled(true);
|
||||
nextButton.setEnabled(true);
|
||||
|
||||
prevButton.setText(R.string.reject);
|
||||
nextButton.setText(R.string.accept);
|
||||
|
||||
transaction.replace(R.id.fragmentContainer, new ReviewQrFragment());
|
||||
|
||||
} else {
|
||||
|
||||
prevButton.setEnabled(true);
|
||||
nextButton.setEnabled(false);
|
||||
|
||||
prevButton.setText(R.string.back);
|
||||
nextButton.setText(R.string.next);
|
||||
|
||||
transaction.replace(R.id.fragmentContainer, new ScanQrFragment(), "FRAGMENT_SCAN");
|
||||
}
|
||||
break;
|
||||
|
||||
case 3:
|
||||
|
||||
if (partnerChoice == 1) {
|
||||
prevButton.setEnabled(true);
|
||||
nextButton.setEnabled(true);
|
||||
|
||||
prevButton.setText(R.string.back);
|
||||
nextButton.setText(R.string.next);
|
||||
|
||||
transaction.replace(R.id.fragmentContainer, new ShowQrFragment(), "FRAGMENT_SHOW");
|
||||
} else {
|
||||
prevButton.setEnabled(true);
|
||||
nextButton.setEnabled(true);
|
||||
|
||||
prevButton.setText(R.string.reject);
|
||||
nextButton.setText(R.string.accept);
|
||||
|
||||
transaction.replace(R.id.fragmentContainer, new ReviewQrFragment());
|
||||
}
|
||||
break;
|
||||
|
||||
case 4:
|
||||
|
||||
nextButton.setText(R.string.done);
|
||||
nextButton.setEnabled(true);
|
||||
|
||||
nextButton.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
finish();
|
||||
}
|
||||
});
|
||||
|
||||
transaction.replace(R.id.fragmentContainer, new UploadFragment());
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
transaction.commit();
|
||||
}
|
||||
|
||||
public void setPartnerChoice(int choice) {
|
||||
|
||||
partnerChoice = choice;
|
||||
|
||||
if (choice != -1) {
|
||||
nextButton.setEnabled(true);
|
||||
} else {
|
||||
nextButton.setEnabled(false);
|
||||
}
|
||||
}
|
||||
|
||||
public void setScannedQr(String qr) {
|
||||
|
||||
runOnUiThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
if (partnerChoice == 1) {
|
||||
getFragment(2, true);
|
||||
} else {
|
||||
getFragment(3, true);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// try {
|
||||
// OrganisationDialog d = new OrganisationDialog(this);
|
||||
// Organisation o = new Organisation();
|
||||
// o.fromJSON(new JSONObject(qr));
|
||||
// d.createAcceptDialog(o, new OrganisationDialog.DialogCallback() {
|
||||
// @Override
|
||||
// public void onAccept() {
|
||||
// nextButton.setEnabled(true);
|
||||
// }
|
||||
//
|
||||
// @Override
|
||||
// public void onReject() {
|
||||
// scanFragment.setReadQr(true);
|
||||
// scanFragment.openCamera();
|
||||
// }
|
||||
// });
|
||||
//
|
||||
// } catch (JSONException e) {
|
||||
// e.printStackTrace();
|
||||
// }
|
||||
|
||||
}
|
||||
|
||||
public void uploadReady() {
|
||||
nextButton.setEnabled(true);
|
||||
}
|
||||
}
|
|
@ -1,64 +0,0 @@
|
|||
package de.overview.wg.its.mispauth.adapter;
|
||||
|
||||
import android.content.Context;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.RelativeLayout;
|
||||
import android.widget.TextView;
|
||||
import de.overview.wg.its.mispauth.R;
|
||||
import de.overview.wg.its.mispauth.auxiliary.OrganisationDialog;
|
||||
import de.overview.wg.its.mispauth.model.Organisation;
|
||||
|
||||
public class ExtOrgAdapter extends RecyclerView.Adapter<ExtOrgAdapter.ViewHolder> {
|
||||
|
||||
private Context context;
|
||||
private Organisation[] dataSet;
|
||||
|
||||
public ExtOrgAdapter(Context context, Organisation[] dataSet) {
|
||||
this.context = context;
|
||||
this.dataSet = dataSet;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public ViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
|
||||
View extOrgView = LayoutInflater.from(parent.getContext()).inflate(R.layout.view_holder_ext_org, parent, false);
|
||||
return new ViewHolder(extOrgView);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(@NonNull ViewHolder holder, final int position) {
|
||||
holder.orgTitle.setText(dataSet[position].getName());
|
||||
holder.subTitle.setText(dataSet[position].getDescription());
|
||||
|
||||
holder.parentLayout.setOnClickListener(new View.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View v) {
|
||||
OrganisationDialog d = new OrganisationDialog(context);
|
||||
d.createInfoDialog(dataSet[position]);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
return dataSet.length;
|
||||
}
|
||||
|
||||
public static class ViewHolder extends RecyclerView.ViewHolder{
|
||||
|
||||
RelativeLayout parentLayout;
|
||||
TextView orgTitle;
|
||||
TextView subTitle;
|
||||
|
||||
public ViewHolder(View v) {
|
||||
super(v);
|
||||
parentLayout = v.findViewById(R.id.parent_layout);
|
||||
orgTitle = v.findViewById(R.id.ext_org_title);
|
||||
subTitle = v.findViewById(R.id.ext_org_sub_title);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,58 @@
|
|||
package de.overview.wg.its.mispauth.adapter;
|
||||
|
||||
import android.content.Context;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.TextView;
|
||||
import de.overview.wg.its.mispauth.R;
|
||||
import de.overview.wg.its.mispauth.model.SyncedPartner;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
public class SyncedPartnerAdapter extends RecyclerView.Adapter<SyncedPartnerAdapter.MyViewHolder> {
|
||||
|
||||
private List<SyncedPartner> syncedPartnerList;
|
||||
|
||||
public class MyViewHolder extends RecyclerView.ViewHolder {
|
||||
public TextView title, dateAdded, url;
|
||||
public MyViewHolder(View view) {
|
||||
super(view);
|
||||
title = view.findViewById(R.id.title);
|
||||
dateAdded = view.findViewById(R.id.dateSynced);
|
||||
url = view.findViewById(R.id.url);
|
||||
}
|
||||
}
|
||||
|
||||
public SyncedPartnerAdapter(Context context, List<SyncedPartner> syncedPartnerList) {
|
||||
this.syncedPartnerList = syncedPartnerList;
|
||||
}
|
||||
|
||||
public void setSyncedPartnerList(List<SyncedPartner> syncedPartnerList) {
|
||||
this.syncedPartnerList = syncedPartnerList;
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
|
||||
View itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.row_synced_organisation, parent, false);
|
||||
return new MyViewHolder(itemView);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(@NonNull MyViewHolder holder, int position) {
|
||||
SyncedPartner syncedPartner = syncedPartnerList.get(position);
|
||||
|
||||
holder.title.setText(syncedPartner.getName());
|
||||
holder.url.setText(syncedPartner.getUrl());
|
||||
holder.dateAdded.setText(syncedPartner.getSyncDate());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
return syncedPartnerList.size();
|
||||
}
|
||||
}
|
|
@ -0,0 +1,93 @@
|
|||
package de.overview.wg.its.mispauth.adapter;
|
||||
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.v7.widget.RecyclerView;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ImageView;
|
||||
import android.widget.TextView;
|
||||
import de.overview.wg.its.mispauth.R;
|
||||
import de.overview.wg.its.mispauth.model.UploadState;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class UploadStateAdapter extends RecyclerView.Adapter<UploadStateAdapter.MyViewHolder> {
|
||||
|
||||
private List<UploadState> stateList = new ArrayList<>();
|
||||
|
||||
class MyViewHolder extends RecyclerView.ViewHolder {
|
||||
|
||||
private TextView title, error;
|
||||
private ImageView pendingIcon, errorIcon, doneIcon, inProgressIcon;
|
||||
|
||||
private MyViewHolder(View view) {
|
||||
|
||||
super(view);
|
||||
|
||||
title = view.findViewById(R.id.title);
|
||||
error = view.findViewById(R.id.state_error_text);
|
||||
|
||||
pendingIcon = view.findViewById(R.id.state_pending);
|
||||
errorIcon = view.findViewById(R.id.state_error);
|
||||
doneIcon = view.findViewById(R.id.state_done);
|
||||
inProgressIcon = view.findViewById(R.id.state_in_progress);
|
||||
}
|
||||
|
||||
private void setState(UploadState.State state) {
|
||||
|
||||
error.setVisibility(View.GONE);
|
||||
errorIcon.setVisibility(View.GONE);
|
||||
pendingIcon.setVisibility(View.GONE);
|
||||
doneIcon.setVisibility(View.GONE);
|
||||
inProgressIcon.setVisibility(View.GONE);
|
||||
|
||||
switch (state) {
|
||||
case PENDING:
|
||||
pendingIcon.setVisibility(View.VISIBLE);
|
||||
break;
|
||||
|
||||
case IN_PROGRESS:
|
||||
inProgressIcon.setVisibility(View.VISIBLE);
|
||||
break;
|
||||
|
||||
case DONE:
|
||||
doneIcon.setVisibility(View.VISIBLE);
|
||||
break;
|
||||
|
||||
case ERROR:
|
||||
errorIcon.setVisibility(View.VISIBLE);
|
||||
error.setVisibility(View.VISIBLE);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void setStateList(List<UploadState> stateList) {
|
||||
this.stateList = stateList;
|
||||
notifyDataSetChanged();
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public UploadStateAdapter.MyViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
|
||||
View itemView = LayoutInflater.from(parent.getContext()).inflate(R.layout.row_upload_state, parent, false);
|
||||
return new UploadStateAdapter.MyViewHolder(itemView);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onBindViewHolder(@NonNull UploadStateAdapter.MyViewHolder holder, int position) {
|
||||
UploadState state = stateList.get(position);
|
||||
|
||||
holder.title.setText(state.getTitle());
|
||||
holder.error.setText(state.getError());
|
||||
holder.setState(stateList.get(position).getCurrentState());
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getItemCount() {
|
||||
return stateList.size();
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,119 @@
|
|||
package de.overview.wg.its.mispauth.auxiliary;
|
||||
|
||||
import android.util.Base64;
|
||||
|
||||
import javax.crypto.*;
|
||||
import javax.crypto.spec.SecretKeySpec;
|
||||
import java.security.*;
|
||||
import java.security.spec.InvalidKeySpecException;
|
||||
import java.security.spec.X509EncodedKeySpec;
|
||||
|
||||
public class AESSecurity {
|
||||
|
||||
private static final String TAG = "MISP_LOGGING";
|
||||
private static final String ALGORITHM = "AES";
|
||||
|
||||
private static AESSecurity instance;
|
||||
|
||||
private PublicKey publickey;
|
||||
private KeyAgreement keyAgreement;
|
||||
private byte[] sharedSecret;
|
||||
|
||||
private AESSecurity() {
|
||||
initialize();
|
||||
}
|
||||
|
||||
private void initialize() {
|
||||
KeyPairGenerator kpg = null;
|
||||
|
||||
try {
|
||||
kpg = KeyPairGenerator.getInstance("EC");
|
||||
kpg.initialize(256);
|
||||
|
||||
KeyPair kp = kpg.generateKeyPair();
|
||||
|
||||
publickey = kp.getPublic();
|
||||
|
||||
keyAgreement = KeyAgreement.getInstance("ECDH");
|
||||
keyAgreement.init(kp.getPrivate());
|
||||
|
||||
} catch (NoSuchAlgorithmException | InvalidKeyException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public void setForeignPublicKey(PublicKey publickey) {
|
||||
try {
|
||||
keyAgreement.doPhase(publickey, true);
|
||||
sharedSecret = keyAgreement.generateSecret();
|
||||
} catch (InvalidKeyException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public String encrypt(String data) {
|
||||
try {
|
||||
Key key = generateKey();
|
||||
Cipher c = Cipher.getInstance(ALGORITHM);
|
||||
c.init(Cipher.ENCRYPT_MODE, key);
|
||||
|
||||
byte[] encVal = c.doFinal(data.getBytes());
|
||||
|
||||
return Base64.encodeToString(encVal, 0);
|
||||
|
||||
} catch (BadPaddingException | InvalidKeyException | NoSuchPaddingException | IllegalBlockSizeException | NoSuchAlgorithmException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
public String decrypt(String data) {
|
||||
try {
|
||||
Key key = generateKey();
|
||||
Cipher c = Cipher.getInstance(ALGORITHM);
|
||||
c.init(Cipher.DECRYPT_MODE, key);
|
||||
|
||||
byte[] decoded = Base64.decode(data, 0);
|
||||
byte[] decValue = c.doFinal(decoded);
|
||||
return new String(decValue);
|
||||
} catch (BadPaddingException | InvalidKeyException | NoSuchPaddingException | IllegalBlockSizeException | NoSuchAlgorithmException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
public PublicKey getPublicKey() {
|
||||
return publickey;
|
||||
}
|
||||
|
||||
private Key generateKey() {
|
||||
return new SecretKeySpec(sharedSecret, ALGORITHM);
|
||||
}
|
||||
|
||||
public static String publicKeyToString(PublicKey key) {
|
||||
return Base64.encodeToString(key.getEncoded(), Base64.DEFAULT);
|
||||
}
|
||||
public static PublicKey publicKeyFromString(String key) {
|
||||
|
||||
KeyFactory kf = null;
|
||||
|
||||
byte[] input = Base64.decode(key, Base64.DEFAULT);
|
||||
|
||||
try {
|
||||
kf = KeyFactory.getInstance("EC"); // normal: DH
|
||||
return kf.generatePublic(new X509EncodedKeySpec(input));
|
||||
} catch (NoSuchAlgorithmException | InvalidKeySpecException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public static AESSecurity getInstance() {
|
||||
if(instance == null) {
|
||||
instance = new AESSecurity();
|
||||
}
|
||||
|
||||
return instance;
|
||||
}
|
||||
}
|
|
@ -1,94 +0,0 @@
|
|||
package de.overview.wg.its.mispauth.auxiliary;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.support.v7.app.AlertDialog;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.widget.TextView;
|
||||
import de.overview.wg.its.mispauth.R;
|
||||
import de.overview.wg.its.mispauth.model.Organisation;
|
||||
|
||||
public class OrganisationDialog {
|
||||
|
||||
private AlertDialog.Builder dialogBuilder;
|
||||
private LayoutInflater inflater;
|
||||
|
||||
public OrganisationDialog(Context context) {
|
||||
dialogBuilder = new AlertDialog.Builder(context);
|
||||
inflater = ((Activity)context).getLayoutInflater();
|
||||
}
|
||||
|
||||
public void createInfoDialog(Organisation org) {
|
||||
|
||||
View dialogContent = inflater.inflate(R.layout.view_holder_organisation, null);
|
||||
dialogBuilder.setView(dialogContent);
|
||||
|
||||
TextView title = dialogContent.findViewById(R.id.organisation_title);
|
||||
title.setText(org.getName());
|
||||
|
||||
TextView uuid = dialogContent.findViewById(R.id.organisation_uuid);
|
||||
uuid.setText(org.getUuid());
|
||||
|
||||
TextView description = dialogContent.findViewById(R.id.organisation_description);
|
||||
description.setText(org.getDescription());
|
||||
|
||||
TextView sector = dialogContent.findViewById(R.id.organisation_sector);
|
||||
sector.setText(org.getSector());
|
||||
|
||||
TextView nationality = dialogContent.findViewById(R.id.organisation_nationality);
|
||||
nationality.setText(org.getNationality());
|
||||
|
||||
TextView userCount = dialogContent.findViewById(R.id.organisation_user_count);
|
||||
userCount.setText("" + org.getUserCount());
|
||||
|
||||
dialogBuilder.setPositiveButton("OK", null);
|
||||
dialogBuilder.setCancelable(true);
|
||||
dialogBuilder.create().show();
|
||||
}
|
||||
|
||||
public void createAcceptDialog(Organisation org, final DialogCallback callback) {
|
||||
View dialogContent = inflater.inflate(R.layout.view_holder_organisation, null);
|
||||
dialogBuilder.setView(dialogContent);
|
||||
|
||||
TextView title = dialogContent.findViewById(R.id.organisation_title);
|
||||
title.setText(org.getName());
|
||||
|
||||
TextView uuid = dialogContent.findViewById(R.id.organisation_uuid);
|
||||
uuid.setText(org.getUuid());
|
||||
|
||||
TextView description = dialogContent.findViewById(R.id.organisation_description);
|
||||
description.setText(org.getDescription());
|
||||
|
||||
TextView sector = dialogContent.findViewById(R.id.organisation_sector);
|
||||
sector.setText(org.getSector());
|
||||
|
||||
TextView nationality = dialogContent.findViewById(R.id.organisation_nationality);
|
||||
nationality.setText(org.getNationality());
|
||||
|
||||
TextView userCount = dialogContent.findViewById(R.id.organisation_user_count);
|
||||
userCount.setText("" + org.getUserCount());
|
||||
|
||||
dialogBuilder.setNegativeButton("REJECT", new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
callback.onReject();
|
||||
}
|
||||
});
|
||||
dialogBuilder.setPositiveButton("ACCEPT", new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
callback.onAccept();
|
||||
}
|
||||
});
|
||||
|
||||
dialogBuilder.setCancelable(false);
|
||||
dialogBuilder.create().show();
|
||||
}
|
||||
|
||||
public interface DialogCallback {
|
||||
void onAccept();
|
||||
void onReject();
|
||||
}
|
||||
}
|
|
@ -2,31 +2,72 @@ package de.overview.wg.its.mispauth.auxiliary;
|
|||
|
||||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.reflect.TypeToken;
|
||||
import de.overview.wg.its.mispauth.model.Organisation;
|
||||
import de.overview.wg.its.mispauth.model.SyncedPartner;
|
||||
import de.overview.wg.its.mispauth.model.User;
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import java.lang.reflect.Type;
|
||||
import java.util.List;
|
||||
|
||||
public class PreferenceManager {
|
||||
|
||||
private static PreferenceManager instance;
|
||||
private SharedPreferences sharedPreferences;
|
||||
|
||||
private SharedPreferences userPreferences;
|
||||
private SharedPreferences credentialPreferences;
|
||||
private SharedPreferences syncedInstancesPreferences;
|
||||
|
||||
private static final String CREDENTIAL_PREFERENCE = "de.overview.wg.its.mispauth.credential_preference";
|
||||
private static final String SAVED_INSTANCES_PREFERENCE = "de.overview.wg.its.mispauth.saved_instances_preference";
|
||||
private static final String USER_PREFERENCE = "de.overview.wg.its.mispauth.user_preferences";
|
||||
|
||||
private static String PREF_KEY_SERVER_URL = "key_server_url";
|
||||
private static String PREF_KEY_SERVER_API_KEY = "key_server_api_key";
|
||||
private static String PREF_KEY_MY_ORGANISATION = "key_my_organisation";
|
||||
private static String PREF_KEY_MY_USER = "key_my_user";
|
||||
private static String PREF_KEY_SAVE_AUTHKEY_ENABLED = "key_save_authkey_enabled";
|
||||
private static String PREF_KEY_SYNCED_ORGANISATIONS = "key_synced_organisations";
|
||||
|
||||
private PreferenceManager(Context context) {
|
||||
sharedPreferences = android.preference.PreferenceManager.getDefaultSharedPreferences(context);
|
||||
credentialPreferences = context.getSharedPreferences(CREDENTIAL_PREFERENCE, Context.MODE_PRIVATE);
|
||||
syncedInstancesPreferences = context.getSharedPreferences(SAVED_INSTANCES_PREFERENCE, Context.MODE_PRIVATE);
|
||||
userPreferences = context.getSharedPreferences(USER_PREFERENCE, Context.MODE_PRIVATE);
|
||||
}
|
||||
|
||||
public List<SyncedPartner> getSyncedPartnerList() {
|
||||
String list = syncedInstancesPreferences.getString(PREF_KEY_SYNCED_ORGANISATIONS, "");
|
||||
Type type = new TypeToken<List<SyncedPartner>>() {}.getType();
|
||||
return new Gson().fromJson(list, type);
|
||||
}
|
||||
public void setSyncedPartnerList(List<SyncedPartner> syncedPartnerList) {
|
||||
String json = new Gson().toJson(syncedPartnerList);
|
||||
SharedPreferences.Editor editor = syncedInstancesPreferences.edit();
|
||||
editor.putString(PREF_KEY_SYNCED_ORGANISATIONS, json);
|
||||
editor.apply();
|
||||
}
|
||||
|
||||
public boolean saveAuthkeyEnabledExists() {
|
||||
return userPreferences.contains(PREF_KEY_SAVE_AUTHKEY_ENABLED);
|
||||
}
|
||||
public boolean saveAuthkeyEnabled() {
|
||||
return userPreferences.getBoolean(PREF_KEY_SAVE_AUTHKEY_ENABLED, false);
|
||||
}
|
||||
public void setSaveAuthkeyEnabled(boolean save) {
|
||||
SharedPreferences.Editor editor = userPreferences.edit();
|
||||
editor.putBoolean(PREF_KEY_SAVE_AUTHKEY_ENABLED, save);
|
||||
editor.apply();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return own Organisation if available, else null
|
||||
*/
|
||||
public Organisation getMyOrganisation() {
|
||||
try {
|
||||
JSONObject jsonObject = new JSONObject(sharedPreferences.getString(PREF_KEY_MY_ORGANISATION, ""));
|
||||
JSONObject jsonObject = new JSONObject(credentialPreferences.getString(PREF_KEY_MY_ORGANISATION, ""));
|
||||
Organisation org = new Organisation();
|
||||
org.fromJSON(jsonObject);
|
||||
return org;
|
||||
|
@ -37,14 +78,14 @@ public class PreferenceManager {
|
|||
return null;
|
||||
}
|
||||
public void setMyOrganisation(Organisation org) {
|
||||
SharedPreferences.Editor editor = sharedPreferences.edit();
|
||||
SharedPreferences.Editor editor = credentialPreferences.edit();
|
||||
editor.putString(PREF_KEY_MY_ORGANISATION, org.toJSON().toString());
|
||||
editor.apply();
|
||||
}
|
||||
|
||||
public User getMyUser() {
|
||||
try {
|
||||
JSONObject jsonObject = new JSONObject(sharedPreferences.getString(PREF_KEY_MY_USER, ""));
|
||||
JSONObject jsonObject = new JSONObject(credentialPreferences.getString(PREF_KEY_MY_USER, ""));
|
||||
User user = new User();
|
||||
user.fromJSON(jsonObject);
|
||||
return user;
|
||||
|
@ -55,34 +96,40 @@ public class PreferenceManager {
|
|||
return null;
|
||||
}
|
||||
public void setMyUser(User user) {
|
||||
SharedPreferences.Editor editor = sharedPreferences.edit();
|
||||
SharedPreferences.Editor editor = credentialPreferences.edit();
|
||||
editor.putString(PREF_KEY_MY_USER, user.toJSON().toString());
|
||||
editor.apply();
|
||||
}
|
||||
|
||||
public String getMyServerUrl() {
|
||||
return sharedPreferences.getString(PREF_KEY_SERVER_URL, "");
|
||||
return credentialPreferences.getString(PREF_KEY_SERVER_URL, "");
|
||||
}
|
||||
public void setMyServerUrl(String serverUrl) {
|
||||
SharedPreferences.Editor editor = sharedPreferences.edit();
|
||||
SharedPreferences.Editor editor = credentialPreferences.edit();
|
||||
editor.putString(PREF_KEY_SERVER_URL, serverUrl);
|
||||
editor.apply();
|
||||
}
|
||||
|
||||
public String getMyServerApiKey() {
|
||||
return sharedPreferences.getString(PREF_KEY_SERVER_API_KEY, "");
|
||||
return credentialPreferences.getString(PREF_KEY_SERVER_API_KEY, "");
|
||||
}
|
||||
public void setMyServerApiKey(String apiKey) {
|
||||
SharedPreferences.Editor editor = sharedPreferences.edit();
|
||||
SharedPreferences.Editor editor = credentialPreferences.edit();
|
||||
editor.putString(PREF_KEY_SERVER_API_KEY, apiKey);
|
||||
editor.apply();
|
||||
}
|
||||
|
||||
public void deleteAllLocalData() {
|
||||
SharedPreferences.Editor editor = sharedPreferences.edit();
|
||||
editor.clear();
|
||||
editor.apply();
|
||||
|
||||
public void clearUserPreferences() {
|
||||
userPreferences.edit().clear().apply();
|
||||
}
|
||||
public void clearCredentialPreferences() {
|
||||
credentialPreferences.edit().clear().apply();
|
||||
}
|
||||
public void clearSyncedInformationPreferences() {
|
||||
syncedInstancesPreferences.edit().clear().apply();
|
||||
}
|
||||
|
||||
|
||||
public static PreferenceManager Instance(Context context) {
|
||||
if(instance == null) {
|
||||
|
|
|
@ -0,0 +1,51 @@
|
|||
package de.overview.wg.its.mispauth.auxiliary;
|
||||
|
||||
import java.security.SecureRandom;
|
||||
import java.util.Locale;
|
||||
import java.util.Objects;
|
||||
import java.util.Random;
|
||||
|
||||
public class RandomString {
|
||||
|
||||
private static final String upper = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
||||
private static final String lower = upper.toLowerCase(Locale.ROOT);
|
||||
private static final String digits = "0123456789";
|
||||
private static final String alphaNum = upper + lower + digits;
|
||||
|
||||
private final Random random;
|
||||
private final char[] symbols;
|
||||
private final char[] buf;
|
||||
|
||||
public RandomString(int length, Random random, String symbols) {
|
||||
|
||||
if (length < 1) {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
if (symbols.length() < 2) {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
|
||||
this.random = Objects.requireNonNull(random);
|
||||
this.symbols = symbols.toCharArray();
|
||||
this.buf = new char[length];
|
||||
|
||||
}
|
||||
|
||||
public RandomString(int length, Random random) {
|
||||
this(length, random, alphaNum);
|
||||
}
|
||||
|
||||
public RandomString(int length) {
|
||||
this(length, new SecureRandom());
|
||||
}
|
||||
|
||||
public String nextString() {
|
||||
|
||||
for (int idx = 0; idx < buf.length; ++idx) {
|
||||
buf[idx] = symbols[random.nextInt(symbols.length)];
|
||||
}
|
||||
|
||||
return new String(buf);
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
package de.overview.wg.its.mispauth.auxiliary;
|
||||
|
||||
public class TempAuth {
|
||||
|
||||
public static String TMP_AUTH_KEY;
|
||||
|
||||
}
|
|
@ -0,0 +1,76 @@
|
|||
package de.overview.wg.its.mispauth.cam;
|
||||
|
||||
/*
|
||||
* Copyright 2014 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.AttributeSet;
|
||||
import android.view.TextureView;
|
||||
|
||||
/**
|
||||
* A {@link TextureView} that can be adjusted to a specified aspect ratio.
|
||||
*/
|
||||
public class AutoFitTextureView extends TextureView {
|
||||
|
||||
private int mRatioWidth = 0;
|
||||
private int mRatioHeight = 0;
|
||||
|
||||
public AutoFitTextureView(Context context) {
|
||||
this(context, null);
|
||||
}
|
||||
|
||||
public AutoFitTextureView(Context context, AttributeSet attrs) {
|
||||
this(context, attrs, 0);
|
||||
}
|
||||
|
||||
public AutoFitTextureView(Context context, AttributeSet attrs, int defStyle) {
|
||||
super(context, attrs, defStyle);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the aspect ratio for this view. The size of the view will be measured based on the ratio
|
||||
* calculated from the parameters. Note that the actual sizes of parameters don't matter, that
|
||||
* is, calling setAspectRatio(2, 3) and setAspectRatio(4, 6) make the same result.
|
||||
*
|
||||
* @param width Relative horizontal size
|
||||
* @param height Relative vertical size
|
||||
*/
|
||||
public void setAspectRatio(int width, int height) {
|
||||
if (width < 0 || height < 0) {
|
||||
throw new IllegalArgumentException("Size cannot be negative.");
|
||||
}
|
||||
mRatioWidth = width;
|
||||
mRatioHeight = height;
|
||||
requestLayout();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
|
||||
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
|
||||
int width = MeasureSpec.getSize(widthMeasureSpec);
|
||||
int height = MeasureSpec.getSize(heightMeasureSpec);
|
||||
if (0 == mRatioWidth || 0 == mRatioHeight) {
|
||||
setMeasuredDimension(width, height);
|
||||
} else {
|
||||
if (width < height * mRatioWidth / mRatioHeight) {
|
||||
setMeasuredDimension(width, width * mRatioHeight / mRatioWidth);
|
||||
} else {
|
||||
setMeasuredDimension(height * mRatioWidth / mRatioHeight, height);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,929 @@
|
|||
package de.overview.wg.its.mispauth.cam;
|
||||
|
||||
import android.Manifest;
|
||||
import android.app.Activity;
|
||||
import android.app.AlertDialog;
|
||||
import android.app.Dialog;
|
||||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.content.res.Configuration;
|
||||
import android.graphics.*;
|
||||
import android.hardware.camera2.CameraAccessException;
|
||||
import android.hardware.camera2.CameraCaptureSession;
|
||||
import android.hardware.camera2.CameraCharacteristics;
|
||||
import android.hardware.camera2.CameraDevice;
|
||||
import android.hardware.camera2.CameraManager;
|
||||
import android.hardware.camera2.CaptureRequest;
|
||||
import android.hardware.camera2.params.StreamConfigurationMap;
|
||||
import android.media.Image;
|
||||
import android.media.ImageReader;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.os.HandlerThread;
|
||||
import android.renderscript.*;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.v4.app.ActivityCompat;
|
||||
import android.support.v4.app.DialogFragment;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.support.v4.content.ContextCompat;
|
||||
import android.util.Log;
|
||||
import android.util.Size;
|
||||
import android.util.SparseArray;
|
||||
import android.util.SparseIntArray;
|
||||
import android.view.*;
|
||||
import android.widget.Toast;
|
||||
import com.google.android.gms.vision.Frame;
|
||||
import com.google.android.gms.vision.barcode.Barcode;
|
||||
import com.google.android.gms.vision.barcode.BarcodeDetector;
|
||||
import de.overview.wg.its.mispauth.SyncActivity;
|
||||
import de.overview.wg.its.mispauth.R;
|
||||
import de.overview.wg.its.mispauth.auxiliary.AESSecurity;
|
||||
import de.overview.wg.its.mispauth.model.PublicKeyQr;
|
||||
import de.overview.wg.its.mispauth.model.SyncInformationQr;
|
||||
import org.json.JSONException;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.Semaphore;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
public class CameraFragment extends Fragment implements ActivityCompat.OnRequestPermissionsResultCallback {
|
||||
|
||||
private SyncActivity parentActivity;
|
||||
|
||||
@Override
|
||||
public void onAttach(Context context) {
|
||||
super.onAttach(context);
|
||||
parentActivity = (SyncActivity) context;
|
||||
}
|
||||
|
||||
/**
|
||||
* Conversion from screen rotation to JPEG orientation.
|
||||
*/
|
||||
private static final SparseIntArray ORIENTATIONS = new SparseIntArray();
|
||||
private static final int REQUEST_CAMERA_PERMISSION = 1;
|
||||
private static final String FRAGMENT_DIALOG = "dialog";
|
||||
|
||||
static {
|
||||
ORIENTATIONS.append(Surface.ROTATION_0, 90);
|
||||
ORIENTATIONS.append(Surface.ROTATION_90, 0);
|
||||
ORIENTATIONS.append(Surface.ROTATION_180, 270);
|
||||
ORIENTATIONS.append(Surface.ROTATION_270, 180);
|
||||
}
|
||||
|
||||
/**
|
||||
* Tag for the {@link Log}.
|
||||
*/
|
||||
private static final String TAG = "MISP_LOGGING";
|
||||
|
||||
/**
|
||||
* Max preview width that is guaranteed by Camera2 API
|
||||
*/
|
||||
private static final int MAX_PREVIEW_WIDTH = 1920;
|
||||
|
||||
/**
|
||||
* Max preview height that is guaranteed by Camera2 API
|
||||
*/
|
||||
private static final int MAX_PREVIEW_HEIGHT = 1080;
|
||||
|
||||
/**
|
||||
* {@link TextureView.SurfaceTextureListener} handles several lifecycle events on a
|
||||
* {@link TextureView}.
|
||||
*/
|
||||
private final TextureView.SurfaceTextureListener mSurfaceTextureListener = new TextureView.SurfaceTextureListener() {
|
||||
|
||||
@Override
|
||||
public void onSurfaceTextureAvailable(SurfaceTexture texture, int width, int height) {
|
||||
openCamera(width, height);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSurfaceTextureSizeChanged(SurfaceTexture texture, int width, int height) {
|
||||
configureTransform(width, height);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onSurfaceTextureDestroyed(SurfaceTexture texture) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSurfaceTextureUpdated(SurfaceTexture texture) {
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* ID of the current {@link CameraDevice}.
|
||||
*/
|
||||
private String mCameraId;
|
||||
|
||||
/**
|
||||
* An {@link AutoFitTextureView} for camera preview.
|
||||
*/
|
||||
private AutoFitTextureView mTextureView;
|
||||
|
||||
/**
|
||||
* A {@link CameraCaptureSession } for camera preview.
|
||||
*/
|
||||
private CameraCaptureSession mCaptureSession;
|
||||
|
||||
/**
|
||||
* A reference to the opened {@link CameraDevice}.
|
||||
*/
|
||||
private CameraDevice mCameraDevice;
|
||||
|
||||
/**
|
||||
* The {@link android.util.Size} of camera preview.
|
||||
*/
|
||||
private Size mPreviewSize;
|
||||
|
||||
/**
|
||||
* {@link CameraDevice.StateCallback} is called when {@link CameraDevice} changes its state.
|
||||
*/
|
||||
private final CameraDevice.StateCallback mStateCallback = new CameraDevice.StateCallback() {
|
||||
|
||||
@Override
|
||||
public void onOpened(@NonNull CameraDevice cameraDevice) {
|
||||
// This method is called when the camera is opened. We start camera preview here.
|
||||
mCameraOpenCloseLock.release();
|
||||
mCameraDevice = cameraDevice;
|
||||
createCameraPreviewSession();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDisconnected(@NonNull CameraDevice cameraDevice) {
|
||||
mCameraOpenCloseLock.release();
|
||||
cameraDevice.close();
|
||||
mCameraDevice = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(@NonNull CameraDevice cameraDevice, int error) {
|
||||
mCameraOpenCloseLock.release();
|
||||
cameraDevice.close();
|
||||
mCameraDevice = null;
|
||||
Activity activity = getActivity();
|
||||
if (null != activity) {
|
||||
activity.finish();
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* An additional thread for running tasks that shouldn't block the UI.
|
||||
*/
|
||||
private HandlerThread mBackgroundThread;
|
||||
|
||||
/**
|
||||
* A {@link Handler} for running tasks in the background.
|
||||
*/
|
||||
private Handler mBackgroundHandler;
|
||||
|
||||
/**
|
||||
* An {@link ImageReader} that handles still image capture.
|
||||
*/
|
||||
private ImageReader mImageReader;
|
||||
|
||||
/**
|
||||
* This a callback object for the {@link ImageReader}. "onImageAvailable" will be called when a
|
||||
* still image is ready to be saved.
|
||||
*/
|
||||
private final ImageReader.OnImageAvailableListener mOnImageAvailableListener = new ImageReader.OnImageAvailableListener() {
|
||||
@Override
|
||||
public void onImageAvailable(ImageReader reader) {
|
||||
|
||||
Image image = reader.acquireNextImage();
|
||||
Bitmap bitmap = YUV2Bitmap(image);
|
||||
|
||||
// final Bitmap bitmap = invertBitmap(YUV2Bitmap(image));
|
||||
|
||||
if (bitmap != null) {
|
||||
|
||||
if (readQrEnabled) {
|
||||
|
||||
Frame frame = new Frame.Builder().setBitmap(bitmap).build();
|
||||
SparseArray<Barcode> barcodes = barcodeDetector.detect(frame);
|
||||
|
||||
if (barcodes.size() > 0) {
|
||||
if (currentScanMode == ScanMode.PUBLIC_KEY) {
|
||||
returnPublicKey(barcodes.valueAt(0).rawValue);
|
||||
} else {
|
||||
returnSyncInformation(barcodes.valueAt(0).rawValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (image != null) {
|
||||
image.close();
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
* {@link CaptureRequest.Builder} for the camera preview
|
||||
*/
|
||||
private CaptureRequest.Builder mPreviewRequestBuilder;
|
||||
|
||||
/**
|
||||
* {@link CaptureRequest} generated by {@link #mPreviewRequestBuilder}
|
||||
*/
|
||||
private CaptureRequest mPreviewRequest;
|
||||
|
||||
/**
|
||||
* A {@link Semaphore} to prevent the app from exiting before closing the camera.
|
||||
*/
|
||||
private Semaphore mCameraOpenCloseLock = new Semaphore(1);
|
||||
|
||||
/**
|
||||
* Shows a {@link Toast} on the UI thread.
|
||||
*
|
||||
* @param text The message to show
|
||||
*/
|
||||
private void showToast(final String text) {
|
||||
final Activity activity = getActivity();
|
||||
if (activity != null) {
|
||||
activity.runOnUiThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
Toast.makeText(activity, text, Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Given {@code choices} of {@code Size}s supported by a camera, choose the smallest one that
|
||||
* is at least as large as the respective texture view size, and that is at most as large as the
|
||||
* respective max size, and whose aspect ratio matches with the specified value. If such size
|
||||
* doesn't exist, choose the largest one that is at most as large as the respective max size,
|
||||
* and whose aspect ratio matches with the specified value.
|
||||
*
|
||||
* @param choices The list of sizes that the camera supports for the intended output
|
||||
* class
|
||||
* @param textureViewWidth The width of the texture view relative to sensor coordinate
|
||||
* @param textureViewHeight The height of the texture view relative to sensor coordinate
|
||||
* @param maxWidth The maximum width that can be chosen
|
||||
* @param maxHeight The maximum height that can be chosen
|
||||
* @param aspectRatio The aspect ratio
|
||||
* @return The optimal {@code Size}, or an arbitrary one if none were big enough
|
||||
*/
|
||||
private static Size chooseOptimalSize(Size[] choices, int textureViewWidth, int textureViewHeight, int maxWidth, int maxHeight, Size aspectRatio) {
|
||||
|
||||
// Collect the supported resolutions that are at least as big as the preview Surface
|
||||
List<Size> bigEnough = new ArrayList<>();
|
||||
// Collect the supported resolutions that are smaller than the preview Surface
|
||||
List<Size> notBigEnough = new ArrayList<>();
|
||||
int w = aspectRatio.getWidth();
|
||||
int h = aspectRatio.getHeight();
|
||||
for (Size option : choices) {
|
||||
if (option.getWidth() <= maxWidth && option.getHeight() <= maxHeight && option.getHeight() == option.getWidth() * h / w) {
|
||||
if (option.getWidth() >= textureViewWidth && option.getHeight() >= textureViewHeight) {
|
||||
bigEnough.add(option);
|
||||
} else {
|
||||
notBigEnough.add(option);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Pick the smallest of those big enough. If there is no one big enough, pick the
|
||||
// largest of those not big enough.
|
||||
if (bigEnough.size() > 0) {
|
||||
return Collections.min(bigEnough, new CompareSizesByArea());
|
||||
} else if (notBigEnough.size() > 0) {
|
||||
return Collections.max(notBigEnough, new CompareSizesByArea());
|
||||
} else {
|
||||
Log.e(TAG, "Couldn't find any suitable preview size");
|
||||
return choices[0];
|
||||
}
|
||||
}
|
||||
|
||||
public static CameraFragment newInstance(ScanMode mode) {
|
||||
|
||||
CameraFragment f = new CameraFragment();
|
||||
|
||||
Bundle args = new Bundle();
|
||||
args.putSerializable(BUNDLE_MODE_KEY, mode);
|
||||
f.setArguments(args);
|
||||
|
||||
return f;
|
||||
}
|
||||
|
||||
@Override
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
||||
|
||||
View v = inflater.inflate(R.layout.fragment_camera, container, false);
|
||||
|
||||
initRenderScript();
|
||||
|
||||
setUpBarcodeDetector();
|
||||
checkBundle();
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewCreated(final View view, Bundle savedInstanceState) {
|
||||
mTextureView = view.findViewById(R.id.texture);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onActivityCreated(Bundle savedInstanceState) {
|
||||
super.onActivityCreated(savedInstanceState);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
startBackgroundThread();
|
||||
|
||||
// When the screen is turned off and turned back on, the SurfaceTexture is already
|
||||
// available, and "onSurfaceTextureAvailable" will not be called. In that case, we can open
|
||||
// a camera and start preview from here (otherwise, we wait until the surface is ready in
|
||||
// the SurfaceTextureListener).
|
||||
if (mTextureView.isAvailable()) {
|
||||
openCamera(mTextureView.getWidth(), mTextureView.getHeight());
|
||||
} else {
|
||||
mTextureView.setSurfaceTextureListener(mSurfaceTextureListener);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPause() {
|
||||
closeCamera();
|
||||
stopBackgroundThread();
|
||||
super.onPause();
|
||||
}
|
||||
|
||||
private void requestCameraPermission() {
|
||||
if (shouldShowRequestPermissionRationale(Manifest.permission.CAMERA)) {
|
||||
new ConfirmationDialog().show(getChildFragmentManager(), FRAGMENT_DIALOG);
|
||||
} else {
|
||||
requestPermissions(new String[]{Manifest.permission.CAMERA}, REQUEST_CAMERA_PERMISSION);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
|
||||
if (requestCode == REQUEST_CAMERA_PERMISSION) {
|
||||
if (grantResults.length != 1 || grantResults[0] != PackageManager.PERMISSION_GRANTED) {
|
||||
ErrorDialog.newInstance("REQUEST PERMISSION").show(getChildFragmentManager(), FRAGMENT_DIALOG);
|
||||
}
|
||||
} else {
|
||||
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets up member variables related to camera.
|
||||
*
|
||||
* @param width The width of available size for camera preview
|
||||
* @param height The height of available size for camera preview
|
||||
*/
|
||||
@SuppressWarnings("SuspiciousNameCombination")
|
||||
private void setUpCameraOutputs(int width, int height) {
|
||||
Activity activity = getActivity();
|
||||
CameraManager manager = (CameraManager) activity.getSystemService(Context.CAMERA_SERVICE);
|
||||
|
||||
try {
|
||||
for (String cameraId : manager.getCameraIdList()) {
|
||||
CameraCharacteristics characteristics = manager.getCameraCharacteristics(cameraId);
|
||||
|
||||
// We don't use a front facing camera in this sample.
|
||||
Integer facing = characteristics.get(CameraCharacteristics.LENS_FACING);
|
||||
if (facing != null && facing == CameraCharacteristics.LENS_FACING_FRONT) {
|
||||
continue;
|
||||
}
|
||||
|
||||
StreamConfigurationMap map = characteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
|
||||
if (map == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// For still image captures, we use the largest available size.
|
||||
Size largest = Collections.max(Arrays.asList(map.getOutputSizes(ImageFormat.YUV_420_888)), new CompareSizesByArea());
|
||||
|
||||
mImageReader = ImageReader.newInstance(largest.getWidth() / 16, largest.getHeight() / 16, ImageFormat.YUV_420_888, 2);
|
||||
mImageReader.setOnImageAvailableListener(mOnImageAvailableListener, mBackgroundHandler);
|
||||
|
||||
// Find out if we need to swap dimension to get the preview size relative to sensor coordinate.
|
||||
int displayRotation = activity.getWindowManager().getDefaultDisplay().getRotation();
|
||||
//noinspection ConstantConditions
|
||||
int mSensorOrientation = characteristics.get(CameraCharacteristics.SENSOR_ORIENTATION);
|
||||
boolean swappedDimensions = false;
|
||||
switch (displayRotation) {
|
||||
case Surface.ROTATION_0:
|
||||
case Surface.ROTATION_180:
|
||||
if (mSensorOrientation == 90 || mSensorOrientation == 270) {
|
||||
swappedDimensions = true;
|
||||
}
|
||||
break;
|
||||
case Surface.ROTATION_90:
|
||||
case Surface.ROTATION_270:
|
||||
if (mSensorOrientation == 0 || mSensorOrientation == 180) {
|
||||
swappedDimensions = true;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
Log.e(TAG, "Display rotation is invalid: " + displayRotation);
|
||||
}
|
||||
|
||||
Point displaySize = new Point();
|
||||
activity.getWindowManager().getDefaultDisplay().getSize(displaySize);
|
||||
|
||||
int rotatedPreviewWidth = width;
|
||||
int rotatedPreviewHeight = height;
|
||||
int maxPreviewWidth = displaySize.x;
|
||||
int maxPreviewHeight = displaySize.y;
|
||||
|
||||
if (swappedDimensions) {
|
||||
rotatedPreviewWidth = height;
|
||||
rotatedPreviewHeight = width;
|
||||
maxPreviewWidth = displaySize.y;
|
||||
maxPreviewHeight = displaySize.x;
|
||||
}
|
||||
|
||||
if (maxPreviewWidth > MAX_PREVIEW_WIDTH) {
|
||||
maxPreviewWidth = MAX_PREVIEW_WIDTH;
|
||||
}
|
||||
|
||||
if (maxPreviewHeight > MAX_PREVIEW_HEIGHT) {
|
||||
maxPreviewHeight = MAX_PREVIEW_HEIGHT;
|
||||
}
|
||||
|
||||
// Danger, W.R.! Attempting to use too large a preview size could exceed the camera
|
||||
// bus' bandwidth limitation, resulting in gorgeous previews but the storage of
|
||||
// garbage capture data.
|
||||
mPreviewSize = chooseOptimalSize(map.getOutputSizes(SurfaceTexture.class),
|
||||
rotatedPreviewWidth, rotatedPreviewHeight, maxPreviewWidth,
|
||||
maxPreviewHeight, largest);
|
||||
|
||||
// We fit the aspect ratio of TextureView to the size of preview we picked.
|
||||
int orientation = getResources().getConfiguration().orientation;
|
||||
if (orientation == Configuration.ORIENTATION_LANDSCAPE) {
|
||||
mTextureView.setAspectRatio(mPreviewSize.getWidth(), mPreviewSize.getHeight());
|
||||
} else {
|
||||
mTextureView.setAspectRatio(mPreviewSize.getHeight(), mPreviewSize.getWidth());
|
||||
}
|
||||
|
||||
mCameraId = cameraId;
|
||||
return;
|
||||
}
|
||||
} catch (CameraAccessException e) {
|
||||
e.printStackTrace();
|
||||
} catch (NullPointerException e) {
|
||||
// Currently an NPE is thrown when the Camera2API is used but not supported on the
|
||||
// device this code runs.
|
||||
ErrorDialog.newInstance("CAMERA ERROR").show(getChildFragmentManager(), FRAGMENT_DIALOG);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Opens the camera specified by {@link CameraFragment#mCameraId}.
|
||||
*/
|
||||
private void openCamera(int width, int height) {
|
||||
|
||||
if (ContextCompat.checkSelfPermission(getActivity(), Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
|
||||
requestCameraPermission();
|
||||
return;
|
||||
}
|
||||
|
||||
setUpCameraOutputs(width, height);
|
||||
configureTransform(width, height);
|
||||
|
||||
Activity activity = getActivity();
|
||||
CameraManager manager = (CameraManager) activity.getSystemService(Context.CAMERA_SERVICE);
|
||||
|
||||
try {
|
||||
|
||||
if (!mCameraOpenCloseLock.tryAcquire(2500, TimeUnit.MILLISECONDS)) {
|
||||
throw new RuntimeException("Time out waiting to lock camera opening.");
|
||||
}
|
||||
|
||||
manager.openCamera(mCameraId, mStateCallback, mBackgroundHandler);
|
||||
} catch (CameraAccessException e) {
|
||||
e.printStackTrace();
|
||||
} catch (InterruptedException e) {
|
||||
throw new RuntimeException("Interrupted while trying to lock camera opening.", e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes the current {@link CameraDevice}.
|
||||
*/
|
||||
private void closeCamera() {
|
||||
try {
|
||||
mCameraOpenCloseLock.acquire();
|
||||
|
||||
if (null != mCaptureSession) {
|
||||
mCaptureSession.close();
|
||||
mCaptureSession = null;
|
||||
}
|
||||
|
||||
if (null != mCameraDevice) {
|
||||
mCameraDevice.close();
|
||||
mCameraDevice = null;
|
||||
}
|
||||
|
||||
if (null != mImageReader) {
|
||||
mImageReader.close();
|
||||
mImageReader = null;
|
||||
}
|
||||
|
||||
} catch (InterruptedException e) {
|
||||
throw new RuntimeException("Interrupted while trying to lock camera closing.", e);
|
||||
} finally {
|
||||
mCameraOpenCloseLock.release();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Starts a background thread and its {@link Handler}.
|
||||
*/
|
||||
private void startBackgroundThread() {
|
||||
mBackgroundThread = new HandlerThread("CameraBackground");
|
||||
mBackgroundThread.start();
|
||||
mBackgroundHandler = new Handler(mBackgroundThread.getLooper());
|
||||
}
|
||||
|
||||
/**
|
||||
* Stops the background thread and its {@link Handler}.
|
||||
*/
|
||||
private void stopBackgroundThread() {
|
||||
mBackgroundThread.quitSafely();
|
||||
try {
|
||||
mBackgroundThread.join();
|
||||
mBackgroundThread = null;
|
||||
mBackgroundHandler = null;
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new {@link CameraCaptureSession} for camera preview.
|
||||
*/
|
||||
private void createCameraPreviewSession() {
|
||||
try {
|
||||
SurfaceTexture texture = mTextureView.getSurfaceTexture();
|
||||
assert texture != null;
|
||||
|
||||
// We configure the size of default buffer to be the size of camera preview we want.
|
||||
texture.setDefaultBufferSize(mPreviewSize.getWidth(), mPreviewSize.getHeight());
|
||||
|
||||
// This is the output Surface we need to start preview.
|
||||
Surface surface = new Surface(texture);
|
||||
Surface mImageSurface = mImageReader.getSurface();
|
||||
|
||||
// We set up a CaptureRequest.Builder with the output Surface.
|
||||
mPreviewRequestBuilder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
|
||||
mPreviewRequestBuilder.addTarget(surface);
|
||||
mPreviewRequestBuilder.addTarget(mImageSurface);
|
||||
|
||||
// Here, we create a CameraCaptureSession for camera preview.
|
||||
mCameraDevice.createCaptureSession(Arrays.asList(surface, mImageReader.getSurface()),
|
||||
new CameraCaptureSession.StateCallback() {
|
||||
|
||||
@Override
|
||||
public void onConfigured(@NonNull CameraCaptureSession cameraCaptureSession) {
|
||||
// The camera is already closed
|
||||
if (null == mCameraDevice) {
|
||||
return;
|
||||
}
|
||||
|
||||
// When the session is ready, we start displaying the preview.
|
||||
mCaptureSession = cameraCaptureSession;
|
||||
try {
|
||||
// Auto focus should be continuous for camera preview.
|
||||
mPreviewRequestBuilder.set(CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE);
|
||||
|
||||
// Finally, we start displaying the camera preview.
|
||||
mPreviewRequest = mPreviewRequestBuilder.build();
|
||||
mCaptureSession.setRepeatingRequest(mPreviewRequest, null, mBackgroundHandler);
|
||||
} catch (CameraAccessException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onConfigureFailed(@NonNull CameraCaptureSession cameraCaptureSession) {
|
||||
showToast("Failed");
|
||||
}
|
||||
}, null
|
||||
);
|
||||
} catch (CameraAccessException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Configures the necessary {@link android.graphics.Matrix} transformation to `mTextureView`.
|
||||
* This method should be called after the camera preview size is determined in
|
||||
* setUpCameraOutputs and also the size of `mTextureView` is fixed.
|
||||
*
|
||||
* @param viewWidth The width of `mTextureView`
|
||||
* @param viewHeight The height of `mTextureView`
|
||||
*/
|
||||
private void configureTransform(int viewWidth, int viewHeight) {
|
||||
Activity activity = getActivity();
|
||||
|
||||
if (null == mTextureView || null == mPreviewSize || null == activity) {
|
||||
return;
|
||||
}
|
||||
|
||||
int rotation = activity.getWindowManager().getDefaultDisplay().getRotation();
|
||||
Matrix matrix = new Matrix();
|
||||
RectF viewRect = new RectF(0, 0, viewWidth, viewHeight);
|
||||
RectF bufferRect = new RectF(0, 0, mPreviewSize.getHeight(), mPreviewSize.getWidth());
|
||||
float centerX = viewRect.centerX();
|
||||
float centerY = viewRect.centerY();
|
||||
if (Surface.ROTATION_90 == rotation || Surface.ROTATION_270 == rotation) {
|
||||
bufferRect.offset(centerX - bufferRect.centerX(), centerY - bufferRect.centerY());
|
||||
matrix.setRectToRect(viewRect, bufferRect, Matrix.ScaleToFit.FILL);
|
||||
float scale = Math.max(
|
||||
(float) viewHeight / mPreviewSize.getHeight(),
|
||||
(float) viewWidth / mPreviewSize.getWidth());
|
||||
matrix.postScale(scale, scale, centerX, centerY);
|
||||
matrix.postRotate(90 * (rotation - 2), centerX, centerY);
|
||||
} else if (Surface.ROTATION_180 == rotation) {
|
||||
matrix.postRotate(180, centerX, centerY);
|
||||
}
|
||||
mTextureView.setTransform(matrix);
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares two {@code Size}s based on their areas.
|
||||
*/
|
||||
static class CompareSizesByArea implements Comparator<Size> {
|
||||
|
||||
@Override
|
||||
public int compare(Size lhs, Size rhs) {
|
||||
// We cast here to ensure the multiplications won't overflow
|
||||
return Long.signum((long) lhs.getWidth() * lhs.getHeight() - (long) rhs.getWidth() * rhs.getHeight());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Shows an error message dialog.
|
||||
*/
|
||||
public static class ErrorDialog extends DialogFragment {
|
||||
|
||||
private static final String ARG_MESSAGE = "message";
|
||||
|
||||
public static ErrorDialog newInstance(String message) {
|
||||
ErrorDialog dialog = new ErrorDialog();
|
||||
Bundle args = new Bundle();
|
||||
args.putString(ARG_MESSAGE, message);
|
||||
dialog.setArguments(args);
|
||||
return dialog;
|
||||
}
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public Dialog onCreateDialog(Bundle savedInstanceState) {
|
||||
final Activity activity = getActivity();
|
||||
return new AlertDialog.Builder(activity)
|
||||
.setMessage(getArguments().getString(ARG_MESSAGE))
|
||||
.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialogInterface, int i) {
|
||||
activity.finish();
|
||||
}
|
||||
})
|
||||
.create();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Shows OK/Cancel confirmation dialog about camera permission.
|
||||
*/
|
||||
public static class ConfirmationDialog extends DialogFragment {
|
||||
|
||||
@NonNull
|
||||
@Override
|
||||
public Dialog onCreateDialog(Bundle savedInstanceState) {
|
||||
final Fragment parent = getParentFragment();
|
||||
return new AlertDialog.Builder(getActivity())
|
||||
.setMessage("REQUEST PERMISSION")
|
||||
.setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
parent.requestPermissions(new String[]{Manifest.permission.CAMERA}, REQUEST_CAMERA_PERMISSION);
|
||||
}
|
||||
})
|
||||
.setNegativeButton(android.R.string.cancel, new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
Activity activity = parent.getActivity();
|
||||
if (activity != null) {
|
||||
activity.finish();
|
||||
}
|
||||
}
|
||||
})
|
||||
.create();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private static final String BUNDLE_MODE_KEY = "mode";
|
||||
|
||||
public enum ScanMode {
|
||||
PUBLIC_KEY,
|
||||
INFO
|
||||
}
|
||||
|
||||
private ScanMode currentScanMode;
|
||||
private boolean readQrEnabled = true;
|
||||
private BarcodeDetector barcodeDetector;
|
||||
|
||||
private RenderScript renderScript;
|
||||
private static final Matrix4f TRANSFORMATION_MATRIX = new Matrix4f(new float[]{
|
||||
-0.33f, -0.33f, -0.33f, 1.0f,
|
||||
-0.59f, -0.59f, -0.59f, 1.0f,
|
||||
-0.11f, -0.11f, -0.11f, 1.0f,
|
||||
1.0f, 1.0f, 1.0f, 1.0f
|
||||
});
|
||||
|
||||
private void initRenderScript() {
|
||||
renderScript = RenderScript.create(getActivity());
|
||||
}
|
||||
|
||||
private Bitmap YUV2Bitmap(Image image) {
|
||||
|
||||
if (image == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
ScriptIntrinsicYuvToRGB yuvToRgbIntrinsic = ScriptIntrinsicYuvToRGB.create(renderScript, Element.U8_4(renderScript));
|
||||
|
||||
int W = image.getWidth();
|
||||
int H = image.getHeight();
|
||||
|
||||
Image.Plane Y = image.getPlanes()[0];
|
||||
Image.Plane U = image.getPlanes()[1];
|
||||
Image.Plane V = image.getPlanes()[2];
|
||||
|
||||
int Yb = Y.getBuffer().remaining();
|
||||
int Ub = U.getBuffer().remaining();
|
||||
int Vb = V.getBuffer().remaining();
|
||||
|
||||
byte[] data = new byte[Yb + Ub + Vb];
|
||||
|
||||
Y.getBuffer().get(data, 0, Yb);
|
||||
V.getBuffer().get(data, Yb, Vb);
|
||||
U.getBuffer().get(data, Yb + Vb, Ub);
|
||||
|
||||
Type.Builder yuvType = new Type.Builder(renderScript, Element.U8(renderScript)).setX(data.length);
|
||||
Allocation in = Allocation.createTyped(renderScript, yuvType.create(), Allocation.USAGE_SCRIPT);
|
||||
|
||||
Type.Builder rgbaType = new Type.Builder(renderScript, Element.RGBA_8888(renderScript)).setX(W).setY(H);
|
||||
Allocation out = Allocation.createTyped(renderScript, rgbaType.create(), Allocation.USAGE_SCRIPT);
|
||||
|
||||
final Bitmap bmpout = Bitmap.createBitmap(W, H, Bitmap.Config.ARGB_8888);
|
||||
|
||||
in.copyFromUnchecked(data);
|
||||
|
||||
yuvToRgbIntrinsic.setInput(in);
|
||||
yuvToRgbIntrinsic.forEach(out);
|
||||
|
||||
out.copyTo(bmpout);
|
||||
image.close();
|
||||
|
||||
return bmpout;
|
||||
}
|
||||
|
||||
private Bitmap invertBitmap(Bitmap source) {
|
||||
|
||||
final Bitmap result = source.copy(source.getConfig(), true);
|
||||
Allocation input = Allocation.createFromBitmap(renderScript, source, Allocation.MipmapControl.MIPMAP_NONE, Allocation.USAGE_SCRIPT);
|
||||
Allocation output = Allocation.createTyped(renderScript, input.getType());
|
||||
|
||||
final ScriptIntrinsicColorMatrix inverter = ScriptIntrinsicColorMatrix.create(renderScript);
|
||||
inverter.setColorMatrix(TRANSFORMATION_MATRIX);
|
||||
inverter.forEach(input, output);
|
||||
output.copyTo(result);
|
||||
|
||||
source.recycle();
|
||||
renderScript.destroy();
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private void setReadQrEnabled(boolean enabled) {
|
||||
readQrEnabled = enabled;
|
||||
}
|
||||
|
||||
private void checkBundle() {
|
||||
Bundle args = getArguments();
|
||||
|
||||
if (args != null) {
|
||||
currentScanMode = (ScanMode) args.getSerializable(BUNDLE_MODE_KEY);
|
||||
}
|
||||
}
|
||||
|
||||
private void returnPublicKey(String qrData) {
|
||||
|
||||
setReadQrEnabled(false);
|
||||
|
||||
try {
|
||||
final PublicKeyQr pkqr = new PublicKeyQr(qrData);
|
||||
// parentActivity.qrVisible(false, 300);
|
||||
|
||||
DialogInterface.OnClickListener positive = new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
|
||||
parentActivity.onPublicKeyResult(pkqr);
|
||||
// parentActivity.qrVisible(true, 800);
|
||||
|
||||
closeCamera();
|
||||
|
||||
parentActivity.runOnUiThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
mTextureView.setVisibility(View.GONE);
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
DialogInterface.OnClickListener negative = new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
// parentActivity.qrVisible(true, 800);
|
||||
setReadQrEnabled(true);
|
||||
}
|
||||
};
|
||||
|
||||
DialogFactory diaFac = new DialogFactory(parentActivity);
|
||||
diaFac.createKeyDialog(pkqr, positive, negative).show();
|
||||
|
||||
} catch (JSONException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private void returnSyncInformation(String qrData) {
|
||||
|
||||
setReadQrEnabled(false);
|
||||
|
||||
AESSecurity aesSecurity = AESSecurity.getInstance();
|
||||
String decryptedQrData = aesSecurity.decrypt(qrData);
|
||||
|
||||
final SyncInformationQr siqr;
|
||||
|
||||
try {
|
||||
siqr = new SyncInformationQr(decryptedQrData);
|
||||
|
||||
DialogInterface.OnClickListener positive = new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
parentActivity.onSyncInfoResult(siqr);
|
||||
|
||||
closeCamera();
|
||||
|
||||
parentActivity.runOnUiThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
mTextureView.setVisibility(View.GONE);
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
DialogInterface.OnClickListener negative = new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface dialog, int which) {
|
||||
setReadQrEnabled(true);
|
||||
}
|
||||
};
|
||||
|
||||
DialogFactory diaFac = new DialogFactory(parentActivity);
|
||||
diaFac.createInformationDialog(siqr, positive, negative).show();
|
||||
|
||||
} catch (JSONException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void setUpBarcodeDetector() {
|
||||
barcodeDetector = new BarcodeDetector.Builder(getActivity())
|
||||
.setBarcodeFormats(Barcode.QR_CODE)
|
||||
.build();
|
||||
|
||||
if (!barcodeDetector.isOperational()) {
|
||||
Toast.makeText(getActivity(), "Could not setup QR-Code scanner!", Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,136 @@
|
|||
package de.overview.wg.its.mispauth.cam;
|
||||
|
||||
import android.app.AlertDialog;
|
||||
import android.app.Dialog;
|
||||
import android.content.*;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.widget.TextView;
|
||||
import de.overview.wg.its.mispauth.R;
|
||||
import de.overview.wg.its.mispauth.model.PublicKeyQr;
|
||||
import de.overview.wg.its.mispauth.model.SyncInformationQr;
|
||||
|
||||
public class DialogFactory {
|
||||
|
||||
private Context context;
|
||||
|
||||
private AlertDialog.Builder adb;
|
||||
private LayoutInflater inflater;
|
||||
|
||||
|
||||
public DialogFactory(Context context) {
|
||||
this.context = context;
|
||||
adb = new AlertDialog.Builder(context);
|
||||
inflater = LayoutInflater.from(context);
|
||||
}
|
||||
|
||||
|
||||
public Dialog createKeyDialog(PublicKeyQr pkqr,
|
||||
DialogInterface.OnClickListener positiveListener,
|
||||
DialogInterface.OnClickListener negativeListener) {
|
||||
|
||||
View title = inflater.inflate(R.layout.dialog_public_key, null);
|
||||
adb.setCustomTitle(title);
|
||||
|
||||
adb.setMessage("\nYou received a Public Key from " + pkqr.getOrganisation() + " (" + pkqr.getUser() + ")");
|
||||
|
||||
adb.setPositiveButton(context.getResources().getString(R.string.accept), positiveListener);
|
||||
adb.setNegativeButton(context.getResources().getString(R.string.reject), negativeListener);
|
||||
|
||||
adb.setCancelable(false);
|
||||
|
||||
Dialog d = adb.create();
|
||||
d.getWindow().setWindowAnimations(R.style.DialogAnimation);
|
||||
d.getWindow().setDimAmount(0.8f);
|
||||
return d;
|
||||
}
|
||||
|
||||
|
||||
public Dialog createInformationDialog(SyncInformationQr siqr,
|
||||
DialogInterface.OnClickListener positiv,
|
||||
DialogInterface.OnClickListener negativ) {
|
||||
|
||||
View title = inflater.inflate(R.layout.dialog_sync_info, null);
|
||||
adb.setCustomTitle(title);
|
||||
|
||||
View orgView = inflater.inflate(R.layout.view_organisation, null);
|
||||
|
||||
TextView orgTitle = orgView.findViewById(R.id.organisation_title);
|
||||
orgTitle.setText(siqr.getOrganisation().getName());
|
||||
|
||||
TextView orgUuid = orgView.findViewById(R.id.organisation_uuid);
|
||||
orgUuid.setText(siqr.getOrganisation().getUuid());
|
||||
|
||||
TextView orgDesc = orgView.findViewById(R.id.organisation_description);
|
||||
orgDesc.setText(siqr.getOrganisation().getDescription());
|
||||
|
||||
TextView orgNat = orgView.findViewById(R.id.organisation_nationality);
|
||||
orgNat.setText(siqr.getOrganisation().getNationality());
|
||||
|
||||
TextView orgSec = orgView.findViewById(R.id.organisation_sector);
|
||||
orgSec.setText(siqr.getOrganisation().getSector());
|
||||
|
||||
TextView orgUser = orgView.findViewById(R.id.organisation_user_count);
|
||||
orgUser.setText("" + siqr.getOrganisation().getUserCount());
|
||||
|
||||
adb.setView(orgView);
|
||||
|
||||
adb.setPositiveButton(context.getResources().getString(R.string.accept), positiv);
|
||||
adb.setNegativeButton(context.getResources().getString(R.string.reject), negativ);
|
||||
|
||||
Dialog d = adb.create();
|
||||
d.getWindow().setWindowAnimations(R.style.DialogAnimation);
|
||||
d.getWindow().setDimAmount(0.8f);
|
||||
return d;
|
||||
}
|
||||
|
||||
|
||||
public Dialog createDeleteDialog(DialogInterface.OnClickListener pos,
|
||||
DialogInterface.OnClickListener neg) {
|
||||
adb.setTitle(context.getResources().getString(R.string.delete_local_data));
|
||||
adb.setMessage(context.getResources().getString(R.string.delete_local_data_msg));
|
||||
|
||||
adb.setPositiveButton(context.getResources().getString(R.string.delete), pos);
|
||||
adb.setNegativeButton(android.R.string.cancel, neg);
|
||||
|
||||
adb.setCancelable(true);
|
||||
Dialog d = adb.create();
|
||||
d.getWindow().setWindowAnimations(R.style.DialogAnimation);
|
||||
return d;
|
||||
}
|
||||
|
||||
public Dialog createSelectDeleteDialog(DialogInterface.OnClickListener pos,
|
||||
DialogInterface.OnClickListener neg) {
|
||||
|
||||
adb.setTitle("Delete local data");
|
||||
adb.setMessage("");
|
||||
|
||||
adb.setPositiveButton(context.getResources().getString(R.string.delete), pos);
|
||||
adb.setNegativeButton(android.R.string.cancel, neg);
|
||||
|
||||
adb.setCancelable(true);
|
||||
Dialog d = adb.create();
|
||||
d.getWindow().setWindowAnimations(R.style.DialogAnimation);
|
||||
return d;
|
||||
}
|
||||
|
||||
|
||||
public Dialog createOverrideDialog(DialogInterface.OnClickListener pos,
|
||||
DialogInterface.OnClickListener neg) {
|
||||
|
||||
adb.setTitle(context.getResources().getString(R.string.override_local_data));
|
||||
adb.setMessage(context.getResources().getString(R.string.override_local_data_msg));
|
||||
|
||||
adb.setPositiveButton(context.getResources().getString(R.string.override), pos);
|
||||
adb.setNegativeButton(android.R.string.cancel, null);
|
||||
|
||||
Dialog d = adb.create();
|
||||
|
||||
d.setCancelable(false);
|
||||
d.getWindow().setWindowAnimations(R.style.DialogAnimation);
|
||||
|
||||
return d;
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -1,20 +0,0 @@
|
|||
package de.overview.wg.its.mispauth.fragment;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.annotation.Nullable;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import de.overview.wg.its.mispauth.R;
|
||||
|
||||
public class ReviewQrFragment extends Fragment {
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {
|
||||
View v = inflater.inflate(R.layout.fragment_review_qr, null);
|
||||
return v;
|
||||
}
|
||||
}
|
|
@ -1,361 +0,0 @@
|
|||
package de.overview.wg.its.mispauth.fragment;
|
||||
|
||||
import android.Manifest;
|
||||
import android.content.Context;
|
||||
import android.content.pm.PackageManager;
|
||||
import android.graphics.Bitmap;
|
||||
import android.graphics.ImageFormat;
|
||||
import android.graphics.SurfaceTexture;
|
||||
import android.hardware.camera2.*;
|
||||
import android.hardware.camera2.params.StreamConfigurationMap;
|
||||
import android.media.Image;
|
||||
import android.media.ImageReader;
|
||||
import android.os.Bundle;
|
||||
import android.os.Handler;
|
||||
import android.os.HandlerThread;
|
||||
import android.renderscript.*;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.support.v4.app.ActivityCompat;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.support.v4.content.ContextCompat;
|
||||
import android.util.Size;
|
||||
import android.util.SparseArray;
|
||||
import android.view.*;
|
||||
import android.widget.Toast;
|
||||
import com.google.android.gms.vision.Frame;
|
||||
import com.google.android.gms.vision.barcode.Barcode;
|
||||
import com.google.android.gms.vision.barcode.BarcodeDetector;
|
||||
import de.overview.wg.its.mispauth.R;
|
||||
import de.overview.wg.its.mispauth.activity.SyncActivity;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
public class ScanQrFragment extends Fragment {
|
||||
|
||||
private static final int CAMERA_REQUEST_CODE = 0;
|
||||
|
||||
private HandlerThread backgroundThread;
|
||||
private Handler backgroundHandler;
|
||||
|
||||
private CameraManager cameraManager;
|
||||
private CameraDevice cameraDevice;
|
||||
private String cameraID;
|
||||
private CameraCaptureSession cameraCaptureSession;
|
||||
|
||||
private SurfaceTexture previewSurfaceTexture;
|
||||
private Surface previewSurface, yuvSurface;
|
||||
private Size[] yuvSizes;
|
||||
|
||||
private BarcodeDetector barcodeDetector;
|
||||
private TextureView previewView;
|
||||
|
||||
private boolean readQr = true;
|
||||
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
||||
View v = inflater.inflate(R.layout.fragment_sync_scan, null);
|
||||
|
||||
previewView = v.findViewById(R.id.texture_scan_preview);
|
||||
|
||||
if (ContextCompat.checkSelfPermission(getActivity(), Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
|
||||
|
||||
if (ActivityCompat.shouldShowRequestPermissionRationale(getActivity(), Manifest.permission.CAMERA)) {
|
||||
|
||||
} else {
|
||||
ActivityCompat.requestPermissions(getActivity(), new String[]{Manifest.permission.CAMERA}, CAMERA_REQUEST_CODE);
|
||||
}
|
||||
|
||||
} else {
|
||||
setUpBarcodeDetector();
|
||||
setUpPreviewTexture();
|
||||
}
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
|
||||
switch (requestCode) {
|
||||
case CAMERA_REQUEST_CODE: {
|
||||
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
|
||||
setUpBarcodeDetector();
|
||||
setUpPreviewTexture();
|
||||
} else {
|
||||
Toast.makeText(getActivity(), "Camera permission needed!", Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onResume() {
|
||||
super.onResume();
|
||||
openBackgroundThread();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onStop() {
|
||||
super.onStop();
|
||||
closeCamera();
|
||||
closeBackgroundThread();
|
||||
}
|
||||
|
||||
|
||||
private void returnResult(String qrData) {
|
||||
((SyncActivity) getActivity()).setScannedQr(qrData);
|
||||
}
|
||||
|
||||
private void setUpPreviewTexture() {
|
||||
|
||||
previewView.setSurfaceTextureListener(new TextureView.SurfaceTextureListener() {
|
||||
@Override
|
||||
public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
|
||||
surface.setDefaultBufferSize(width, height);
|
||||
previewSurfaceTexture = surface;
|
||||
setUpCamera();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSurfaceTextureUpdated(SurfaceTexture surface) {
|
||||
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
private void setUpCamera() {
|
||||
cameraManager = (CameraManager) getActivity().getSystemService(Context.CAMERA_SERVICE);
|
||||
|
||||
try {
|
||||
for (String cameraId : cameraManager.getCameraIdList()) {
|
||||
|
||||
CameraCharacteristics cameraCharacteristics = cameraManager.getCameraCharacteristics(cameraId);
|
||||
Integer facing = cameraCharacteristics.get(CameraCharacteristics.LENS_FACING);
|
||||
|
||||
if (facing == CameraCharacteristics.LENS_FACING_BACK) {
|
||||
|
||||
cameraID = cameraId;
|
||||
|
||||
StreamConfigurationMap streamConfigurationMap = cameraCharacteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
|
||||
yuvSizes = streamConfigurationMap.getOutputSizes(ImageFormat.YUV_420_888);
|
||||
|
||||
setUpImageReader();
|
||||
}
|
||||
}
|
||||
} catch (CameraAccessException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private void setUpImageReader() {
|
||||
|
||||
Size yuvSize = yuvSizes[yuvSizes.length - 6];
|
||||
|
||||
ImageReader yuvImageReader = ImageReader.newInstance(yuvSize.getWidth(), yuvSize.getHeight(), ImageFormat.YUV_420_888, 5);
|
||||
ImageReader.OnImageAvailableListener yuvImageListener = new ImageReader.OnImageAvailableListener() {
|
||||
|
||||
@Override
|
||||
public void onImageAvailable(ImageReader reader) {
|
||||
|
||||
if (!readQr) {
|
||||
return;
|
||||
}
|
||||
|
||||
Image lastImage = reader.acquireLatestImage();
|
||||
Bitmap bitmap = YUV2Bitmap(lastImage);
|
||||
|
||||
if (bitmap != null) {
|
||||
|
||||
Frame frame = new Frame.Builder().setBitmap(bitmap).build();
|
||||
SparseArray<Barcode> barcodes = barcodeDetector.detect(frame);
|
||||
|
||||
if (barcodes.size() > 0) {
|
||||
returnResult(barcodes.valueAt(0).rawValue);
|
||||
}
|
||||
}
|
||||
|
||||
if (lastImage != null) {
|
||||
lastImage.close();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
yuvImageReader.setOnImageAvailableListener(yuvImageListener, backgroundHandler);
|
||||
|
||||
previewSurface = new Surface(previewSurfaceTexture);
|
||||
yuvSurface = yuvImageReader.getSurface();
|
||||
|
||||
openCamera();
|
||||
}
|
||||
|
||||
public void openCamera() {
|
||||
|
||||
CameraDevice.StateCallback stateCallback = new CameraDevice.StateCallback() {
|
||||
@Override
|
||||
public void onOpened(@NonNull CameraDevice camera) {
|
||||
cameraDevice = camera;
|
||||
createCaptureSession();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDisconnected(@NonNull CameraDevice camera) {
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(@NonNull CameraDevice camera, int error) {
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
try {
|
||||
if (ActivityCompat.checkSelfPermission(getActivity(), android.Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED) {
|
||||
cameraManager.openCamera(cameraID, stateCallback, backgroundHandler);
|
||||
}
|
||||
} catch (CameraAccessException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private void createCaptureSession() {
|
||||
List<Surface> surfaces = Arrays.asList(previewSurface, yuvSurface);
|
||||
|
||||
CameraCaptureSession.StateCallback captureStateCallback = new CameraCaptureSession.StateCallback() {
|
||||
@Override
|
||||
public void onConfigured(@NonNull CameraCaptureSession session) {
|
||||
cameraCaptureSession = session;
|
||||
createCaptureRequest();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onConfigureFailed(@NonNull CameraCaptureSession session) {
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
try {
|
||||
cameraDevice.createCaptureSession(surfaces, captureStateCallback, backgroundHandler);
|
||||
} catch (CameraAccessException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void createCaptureRequest() {
|
||||
try {
|
||||
|
||||
CaptureRequest.Builder requestBuilder = cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_ZERO_SHUTTER_LAG);
|
||||
requestBuilder.addTarget(previewSurface);
|
||||
requestBuilder.addTarget(yuvSurface);
|
||||
|
||||
CameraCaptureSession.CaptureCallback captureCallback = new CameraCaptureSession.CaptureCallback() {
|
||||
@Override
|
||||
public void onCaptureCompleted(@NonNull CameraCaptureSession session, @NonNull CaptureRequest request, @NonNull TotalCaptureResult result) {
|
||||
super.onCaptureCompleted(session, request, result);
|
||||
}
|
||||
};
|
||||
|
||||
cameraCaptureSession.setRepeatingRequest(requestBuilder.build(), captureCallback, backgroundHandler);
|
||||
|
||||
} catch (CameraAccessException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
private void openBackgroundThread() {
|
||||
backgroundThread = new HandlerThread("raw_image_available_listener_thread");
|
||||
backgroundThread.start();
|
||||
backgroundHandler = new Handler(backgroundThread.getLooper());
|
||||
}
|
||||
|
||||
private void closeBackgroundThread() {
|
||||
backgroundThread.quitSafely();
|
||||
try {
|
||||
backgroundThread.join();
|
||||
backgroundThread = null;
|
||||
backgroundHandler = null;
|
||||
} catch (InterruptedException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
public void closeCamera() {
|
||||
if (cameraCaptureSession != null) {
|
||||
cameraCaptureSession.close();
|
||||
cameraCaptureSession = null;
|
||||
}
|
||||
|
||||
if (cameraDevice != null) {
|
||||
cameraDevice.close();
|
||||
cameraDevice = null;
|
||||
}
|
||||
}
|
||||
|
||||
private void setUpBarcodeDetector() {
|
||||
barcodeDetector = new BarcodeDetector.Builder(getActivity())
|
||||
.setBarcodeFormats(Barcode.QR_CODE)
|
||||
.build();
|
||||
|
||||
if (!barcodeDetector.isOperational()) {
|
||||
Toast.makeText(getActivity(), "Could not setup QR-Code scanner!", Toast.LENGTH_SHORT).show();
|
||||
}
|
||||
}
|
||||
|
||||
private Bitmap YUV2Bitmap(Image image) {
|
||||
|
||||
if (image == null) return null;
|
||||
|
||||
int W = image.getWidth();
|
||||
int H = image.getHeight();
|
||||
|
||||
Image.Plane Y = image.getPlanes()[0];
|
||||
Image.Plane U = image.getPlanes()[1];
|
||||
Image.Plane V = image.getPlanes()[2];
|
||||
|
||||
int Yb = Y.getBuffer().remaining();
|
||||
int Ub = U.getBuffer().remaining();
|
||||
int Vb = V.getBuffer().remaining();
|
||||
|
||||
byte[] data = new byte[Yb + Ub + Vb];
|
||||
|
||||
Y.getBuffer().get(data, 0, Yb);
|
||||
V.getBuffer().get(data, Yb, Vb);
|
||||
U.getBuffer().get(data, Yb + Vb, Ub);
|
||||
|
||||
RenderScript rs = RenderScript.create(getActivity().getApplicationContext());
|
||||
|
||||
ScriptIntrinsicYuvToRGB yuvToRgbIntrinsic = ScriptIntrinsicYuvToRGB.create(rs, Element.U8_4(rs));
|
||||
|
||||
Type.Builder yuvType = new Type.Builder(rs, Element.U8(rs)).setX(data.length);
|
||||
Allocation in = Allocation.createTyped(rs, yuvType.create(), Allocation.USAGE_SCRIPT);
|
||||
|
||||
Type.Builder rgbaType = new Type.Builder(rs, Element.RGBA_8888(rs)).setX(W).setY(H);
|
||||
Allocation out = Allocation.createTyped(rs, rgbaType.create(), Allocation.USAGE_SCRIPT);
|
||||
|
||||
|
||||
final Bitmap bmpout = Bitmap.createBitmap(W, H, Bitmap.Config.ARGB_8888);
|
||||
|
||||
in.copyFromUnchecked(data);
|
||||
|
||||
yuvToRgbIntrinsic.setInput(in);
|
||||
yuvToRgbIntrinsic.forEach(out);
|
||||
out.copyTo(bmpout);
|
||||
image.close();
|
||||
return bmpout;
|
||||
}
|
||||
|
||||
public void setReadQr(boolean enabled) {
|
||||
readQr = enabled;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,52 +0,0 @@
|
|||
package de.overview.wg.its.mispauth.fragment;
|
||||
|
||||
import android.graphics.Point;
|
||||
import android.os.Bundle;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.util.DisplayMetrics;
|
||||
import android.view.Display;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.ImageView;
|
||||
import de.overview.wg.its.mispauth.R;
|
||||
import de.overview.wg.its.mispauth.auxiliary.PreferenceManager;
|
||||
import net.glxn.qrgen.android.QRCode;
|
||||
|
||||
public class ShowQrFragment extends Fragment {
|
||||
|
||||
private ImageView qrImageView;
|
||||
private int screenWidth, screenHeight;
|
||||
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
||||
View v = inflater.inflate(R.layout.fragment_sync_show, null);
|
||||
|
||||
// DisplayMetrics metrics = new DisplayMetrics();
|
||||
// getActivity().getWindowManager().getDefaultDisplay().getMetrics(metrics);
|
||||
//
|
||||
// screenWidth = (int)(metrics.widthPixels * metrics.density);
|
||||
// screenHeight = (int)(metrics.heightPixels * metrics.density);
|
||||
|
||||
// Display display = getActivity().getWindowManager().getDefaultDisplay();
|
||||
// Point size = new Point();
|
||||
// display.getSize(size);
|
||||
// screenWidth = size.x;
|
||||
// screenHeight = size.y;
|
||||
|
||||
screenHeight = getResources().getDisplayMetrics().heightPixels;
|
||||
screenWidth = getResources().getDisplayMetrics().widthPixels;
|
||||
|
||||
qrImageView = v.findViewById(R.id.image_view_qr);
|
||||
|
||||
PreferenceManager preferenceManager = PreferenceManager.Instance(getActivity());
|
||||
setQr(preferenceManager.getMyOrganisation().toJSON().toString());
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
private void setQr(String msg) {
|
||||
qrImageView.setImageBitmap(QRCode.from(msg)
|
||||
.withSize(screenHeight, screenHeight)
|
||||
.bitmap());
|
||||
}
|
||||
}
|
|
@ -1,33 +0,0 @@
|
|||
package de.overview.wg.its.mispauth.fragment;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.os.Bundle;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.RadioGroup;
|
||||
import de.overview.wg.its.mispauth.R;
|
||||
import de.overview.wg.its.mispauth.activity.SyncActivity;
|
||||
|
||||
|
||||
public class SyncStartFragment extends Fragment {
|
||||
|
||||
private static final String TAG = "DEBUG";
|
||||
private RadioGroup radioGroup;
|
||||
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
||||
View v = inflater.inflate(R.layout.fragment_sync_start, null);
|
||||
radioGroup = v.findViewById(R.id.radioGroup);
|
||||
|
||||
radioGroup.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
|
||||
@Override
|
||||
public void onCheckedChanged(RadioGroup group, int checkedId) {
|
||||
((SyncActivity)getActivity()).setPartnerChoice(checkedId % 2);
|
||||
}
|
||||
});
|
||||
|
||||
return v;
|
||||
}
|
||||
}
|
|
@ -1,17 +0,0 @@
|
|||
package de.overview.wg.its.mispauth.fragment;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.support.v4.app.Fragment;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import de.overview.wg.its.mispauth.R;
|
||||
|
||||
public class UploadFragment extends Fragment {
|
||||
|
||||
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
|
||||
View v = inflater.inflate(R.layout.fragment_sync_upload, null);
|
||||
return v;
|
||||
}
|
||||
|
||||
}
|
|
@ -1,5 +0,0 @@
|
|||
package de.overview.wg.its.mispauth.interfaces;
|
||||
|
||||
public interface IProcessable {
|
||||
boolean isDone();
|
||||
}
|
|
@ -1,6 +0,0 @@
|
|||
package de.overview.wg.its.mispauth.interfaces;
|
||||
|
||||
public interface ISyncCommunication {
|
||||
void setPartnerChoice(int choice);
|
||||
void setScannedQr(String qr);
|
||||
}
|
|
@ -5,6 +5,8 @@ import org.json.JSONObject;
|
|||
|
||||
public class Organisation {
|
||||
|
||||
public static final String ROOT_KEY = "Organisation";
|
||||
|
||||
private static String ID_KEY = "id";
|
||||
private static String NAME_KEY = "name";
|
||||
private static String DATE_CREATED_KEY = "date_created";
|
||||
|
@ -34,48 +36,57 @@ public class Organisation {
|
|||
private int createdBy;
|
||||
private int userCount;
|
||||
|
||||
public Organisation() {}
|
||||
|
||||
public void fromJSON(JSONObject org) {
|
||||
|
||||
try {
|
||||
id = org.getInt(ID_KEY);
|
||||
dateCreated = org.getString(DATE_CREATED_KEY);
|
||||
dateModified = org.getString(DATE_MODIFIED_KEY);
|
||||
name = org.getString(NAME_KEY);
|
||||
type = org.getString(TYPE_KEY);
|
||||
nationality = org.getString(NATIONALITY_KEY);
|
||||
sector = org.getString(SECTOR_KEY);
|
||||
contacts = org.getString(CONTACTS_KEY);
|
||||
description = org.getString(DESCRIPTION_KEY);
|
||||
local = org.getBoolean(LOCAL_KEY);
|
||||
uuid = org.getString(UUID_KEY);
|
||||
restrictedToDomain = org.getString(RESTRICTED_TO_DOMAIN_KEY);
|
||||
createdBy = org.getInt(CREATED_BY_KEY);
|
||||
userCount = org.getInt(USER_COUNT_KEY);
|
||||
|
||||
} catch (JSONException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
public Organisation() {
|
||||
}
|
||||
|
||||
public Organisation(JSONObject json) throws JSONException {
|
||||
fromJSON(json);
|
||||
}
|
||||
|
||||
public void fromJSON(JSONObject org) throws JSONException {
|
||||
|
||||
id = org.optInt(ID_KEY, -1);
|
||||
dateCreated = org.optString(DATE_CREATED_KEY);
|
||||
dateModified = org.optString(DATE_MODIFIED_KEY);
|
||||
name = org.optString(NAME_KEY);
|
||||
type = org.optString(TYPE_KEY);
|
||||
nationality = org.optString(NATIONALITY_KEY);
|
||||
sector = org.optString(SECTOR_KEY);
|
||||
contacts = org.optString(CONTACTS_KEY);
|
||||
description = org.optString(DESCRIPTION_KEY);
|
||||
local = org.optBoolean(LOCAL_KEY, true);
|
||||
uuid = org.optString(UUID_KEY);
|
||||
restrictedToDomain = org.optString(RESTRICTED_TO_DOMAIN_KEY);
|
||||
createdBy = org.optInt(CREATED_BY_KEY, -1);
|
||||
userCount = org.optInt(USER_COUNT_KEY);
|
||||
|
||||
}
|
||||
|
||||
public JSONObject toJSON() {
|
||||
return toJSON(false);
|
||||
}
|
||||
|
||||
public JSONObject toJSON(boolean minimal) {
|
||||
JSONObject org = new JSONObject();
|
||||
|
||||
try {
|
||||
org.put(ID_KEY, id);
|
||||
org.put(NAME_KEY, name);
|
||||
org.put(DATE_CREATED_KEY, dateCreated);
|
||||
org.put(DATE_MODIFIED_KEY, dateModified);
|
||||
org.put(TYPE_KEY, type);
|
||||
org.put(NATIONALITY_KEY, nationality);
|
||||
org.put(SECTOR_KEY, sector);
|
||||
org.put(CONTACTS_KEY, contacts);
|
||||
org.put(DESCRIPTION_KEY, description);
|
||||
org.put(LOCAL_KEY, local);
|
||||
org.put(UUID_KEY, uuid);
|
||||
org.put(RESTRICTED_TO_DOMAIN_KEY, restrictedToDomain);
|
||||
org.put(CREATED_BY_KEY, createdBy);
|
||||
org.put(USER_COUNT_KEY, userCount);
|
||||
org.putOpt(NAME_KEY, name);
|
||||
org.putOpt(DESCRIPTION_KEY, description);
|
||||
org.putOpt(NATIONALITY_KEY, nationality);
|
||||
org.putOpt(SECTOR_KEY, sector);
|
||||
org.putOpt(USER_COUNT_KEY, userCount);
|
||||
|
||||
if (!minimal) {
|
||||
org.putOpt(ID_KEY, id);
|
||||
org.putOpt(UUID_KEY, uuid);
|
||||
org.putOpt(TYPE_KEY, type);
|
||||
org.putOpt(CONTACTS_KEY, contacts);
|
||||
org.putOpt(DATE_CREATED_KEY, dateCreated);
|
||||
org.putOpt(DATE_MODIFIED_KEY, dateModified);
|
||||
org.putOpt(LOCAL_KEY, local);
|
||||
org.putOpt(RESTRICTED_TO_DOMAIN_KEY, restrictedToDomain);
|
||||
org.putOpt(CREATED_BY_KEY, createdBy);
|
||||
}
|
||||
|
||||
} catch (JSONException e) {
|
||||
e.printStackTrace();
|
||||
|
@ -88,13 +99,15 @@ public class Organisation {
|
|||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
public String getName(){
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
public void setDescription(String description) {
|
||||
this.description = description;
|
||||
}
|
||||
|
@ -102,6 +115,7 @@ public class Organisation {
|
|||
public String getSector() {
|
||||
return sector;
|
||||
}
|
||||
|
||||
public void setSector(String sector) {
|
||||
this.sector = sector;
|
||||
}
|
||||
|
@ -109,6 +123,7 @@ public class Organisation {
|
|||
public String getNationality() {
|
||||
return nationality;
|
||||
}
|
||||
|
||||
public void setNationality(String nationality) {
|
||||
this.nationality = nationality;
|
||||
}
|
||||
|
@ -116,6 +131,7 @@ public class Organisation {
|
|||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(int id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
@ -123,6 +139,7 @@ public class Organisation {
|
|||
public String getDateCreated() {
|
||||
return dateCreated;
|
||||
}
|
||||
|
||||
public void setDateCreated(String dateCreated) {
|
||||
this.dateCreated = dateCreated;
|
||||
}
|
||||
|
@ -130,6 +147,7 @@ public class Organisation {
|
|||
public String getDateModified() {
|
||||
return dateModified;
|
||||
}
|
||||
|
||||
public void setDateModified(String dateModified) {
|
||||
this.dateModified = dateModified;
|
||||
}
|
||||
|
@ -137,6 +155,7 @@ public class Organisation {
|
|||
public String getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public void setType(String type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
@ -144,6 +163,7 @@ public class Organisation {
|
|||
public String getContacts() {
|
||||
return contacts;
|
||||
}
|
||||
|
||||
public void setContacts(String contacts) {
|
||||
this.contacts = contacts;
|
||||
}
|
||||
|
@ -151,6 +171,7 @@ public class Organisation {
|
|||
public boolean isLocal() {
|
||||
return local;
|
||||
}
|
||||
|
||||
public void setLocal(boolean local) {
|
||||
this.local = local;
|
||||
}
|
||||
|
@ -158,6 +179,7 @@ public class Organisation {
|
|||
public String getUuid() {
|
||||
return uuid;
|
||||
}
|
||||
|
||||
public void setUuid(String uuid) {
|
||||
this.uuid = uuid;
|
||||
}
|
||||
|
@ -165,6 +187,7 @@ public class Organisation {
|
|||
public String getRestrictedToDomain() {
|
||||
return restrictedToDomain;
|
||||
}
|
||||
|
||||
public void setRestrictedToDomain(String restrictedToDomain) {
|
||||
this.restrictedToDomain = restrictedToDomain;
|
||||
}
|
||||
|
@ -172,6 +195,7 @@ public class Organisation {
|
|||
public int getCreatedBy() {
|
||||
return createdBy;
|
||||
}
|
||||
|
||||
public void setCreatedBy(int createdBy) {
|
||||
this.createdBy = createdBy;
|
||||
}
|
||||
|
@ -179,6 +203,7 @@ public class Organisation {
|
|||
public int getUserCount() {
|
||||
return userCount;
|
||||
}
|
||||
|
||||
public void setUserCount(int userCount) {
|
||||
this.userCount = userCount;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,61 @@
|
|||
package de.overview.wg.its.mispauth.model;
|
||||
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
public class PublicKeyQr {
|
||||
|
||||
private static final String KEY_ORG = "org";
|
||||
private static final String KEY_USER = "user";
|
||||
private static final String KEY_KEY = "key";
|
||||
|
||||
private String organisation, user, key;
|
||||
|
||||
public PublicKeyQr(JSONObject qr) throws JSONException {
|
||||
organisation = qr.getString(KEY_ORG);
|
||||
user = qr.getString(KEY_USER);
|
||||
key = qr.getString(KEY_KEY);
|
||||
}
|
||||
|
||||
public PublicKeyQr(String qr) throws JSONException{
|
||||
JSONObject json = new JSONObject(qr);
|
||||
|
||||
organisation = json.getString(KEY_ORG);
|
||||
user = json.getString(KEY_USER);
|
||||
key = json.getString(KEY_KEY);
|
||||
}
|
||||
|
||||
public PublicKeyQr(String organisation, String user, String key) {
|
||||
this.organisation = organisation;
|
||||
this.user = user;
|
||||
this.key = key;
|
||||
}
|
||||
|
||||
public JSONObject toJSON() {
|
||||
try {
|
||||
JSONObject json = new JSONObject();
|
||||
|
||||
json.put(KEY_ORG, organisation);
|
||||
json.put(KEY_USER, user);
|
||||
json.put(KEY_KEY, key);
|
||||
|
||||
return json;
|
||||
|
||||
} catch (JSONException e) {
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public String getOrganisation() {
|
||||
return organisation;
|
||||
}
|
||||
|
||||
public String getUser() {
|
||||
return user;
|
||||
}
|
||||
|
||||
public String getKey() {
|
||||
return key;
|
||||
}
|
||||
}
|
|
@ -1,5 +1,105 @@
|
|||
package de.overview.wg.its.mispauth.model;
|
||||
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
public class Server {
|
||||
|
||||
public static final String ROOT_KEY = "Server";
|
||||
|
||||
private static final String URL_KEY = "url";
|
||||
private static final String NAME_KEY = "name";
|
||||
private static final String REMOTE_ORG_ID_KEY = "remote_org_id";
|
||||
private static final String AUTHKEY_KEY = "authkey";
|
||||
private static final String PUSH_KEY = "push";
|
||||
private static final String PULL_KEY = "pull";
|
||||
|
||||
private String url;
|
||||
private String name;
|
||||
private int remoteOrgId;
|
||||
private String authkey;
|
||||
private boolean push, pull;
|
||||
|
||||
public Server() { }
|
||||
public Server(JSONObject json) throws JSONException {
|
||||
fromJSON(json);
|
||||
}
|
||||
|
||||
public void fromJSON(JSONObject server) throws JSONException {
|
||||
url = server.optString(URL_KEY);
|
||||
name = server.optString(NAME_KEY);
|
||||
remoteOrgId = server.optInt(REMOTE_ORG_ID_KEY, -1);
|
||||
authkey = server.optString(AUTHKEY_KEY);
|
||||
push = server.optBoolean(PUSH_KEY, false);
|
||||
pull = server.optBoolean(PULL_KEY, false);
|
||||
}
|
||||
|
||||
public JSONObject toJSON() {
|
||||
return toJSON(false);
|
||||
}
|
||||
public JSONObject toJSON(boolean minimal) {
|
||||
|
||||
JSONObject jsonObject = new JSONObject();
|
||||
|
||||
try {
|
||||
jsonObject.putOpt(URL_KEY, url);
|
||||
jsonObject.putOpt(NAME_KEY, name);
|
||||
jsonObject.putOpt(AUTHKEY_KEY, authkey);
|
||||
|
||||
if (!minimal) {
|
||||
jsonObject.putOpt(REMOTE_ORG_ID_KEY, remoteOrgId);
|
||||
jsonObject.putOpt(PUSH_KEY, push);
|
||||
jsonObject.putOpt(PULL_KEY, pull);
|
||||
}
|
||||
|
||||
} catch (JSONException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
return jsonObject;
|
||||
}
|
||||
|
||||
|
||||
public String getUrl() {
|
||||
return url;
|
||||
}
|
||||
public void setUrl(String url) {
|
||||
this.url = url;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public int getRemoteOrgId() {
|
||||
return remoteOrgId;
|
||||
}
|
||||
public void setRemoteOrgId(int remoteOrgId) {
|
||||
this.remoteOrgId = remoteOrgId;
|
||||
}
|
||||
|
||||
public String getAuthkey() {
|
||||
return authkey;
|
||||
}
|
||||
public void setAuthkey(String authkey) {
|
||||
this.authkey = authkey;
|
||||
}
|
||||
|
||||
public boolean isPush() {
|
||||
return push;
|
||||
}
|
||||
public void setPush(boolean push) {
|
||||
this.push = push;
|
||||
}
|
||||
|
||||
public boolean isPull() {
|
||||
return pull;
|
||||
}
|
||||
public void setPull(boolean pull) {
|
||||
this.pull = pull;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,50 @@
|
|||
package de.overview.wg.its.mispauth.model;
|
||||
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONException;
|
||||
|
||||
public class SyncInformationQr {
|
||||
|
||||
private Organisation organisation;
|
||||
private Server server;
|
||||
private User user;
|
||||
|
||||
public SyncInformationQr(Organisation organisation, Server server, User user) {
|
||||
this.organisation = organisation;
|
||||
this.server = server;
|
||||
this.user = user;
|
||||
}
|
||||
public SyncInformationQr(String stringArray) throws JSONException {
|
||||
fromJSON(new JSONArray(stringArray));
|
||||
}
|
||||
|
||||
private void fromJSON(JSONArray array) throws JSONException {
|
||||
int length = array.length();
|
||||
|
||||
if (length == 3) {
|
||||
organisation = new Organisation(array.getJSONObject(0));
|
||||
server = new Server(array.getJSONObject(1));
|
||||
user = new User(array.getJSONObject(2));
|
||||
}
|
||||
}
|
||||
|
||||
public JSONArray toJSON() {
|
||||
JSONArray array = new JSONArray();
|
||||
|
||||
array.put(organisation.toJSON(true));
|
||||
array.put(server.toJSON(true));
|
||||
array.put(user.toJSON(true));
|
||||
|
||||
return array;
|
||||
}
|
||||
|
||||
public Organisation getOrganisation() {
|
||||
return organisation;
|
||||
}
|
||||
public Server getServer() {
|
||||
return server;
|
||||
}
|
||||
public User getUser() {
|
||||
return user;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,48 @@
|
|||
package de.overview.wg.its.mispauth.model;
|
||||
|
||||
import android.annotation.SuppressLint;
|
||||
|
||||
import java.sql.Timestamp;
|
||||
import java.text.SimpleDateFormat;
|
||||
|
||||
public class SyncedPartner {
|
||||
|
||||
@SuppressLint("SimpleDateFormat")
|
||||
private static final SimpleDateFormat dateFormat = new SimpleDateFormat("dd.MM.yyyy");
|
||||
|
||||
private String name;
|
||||
private String url;
|
||||
private String syncDate;
|
||||
|
||||
public SyncedPartner(String name, String url) {
|
||||
this.name = name;
|
||||
this.url = url;
|
||||
}
|
||||
|
||||
public void generateTimeStamp() {
|
||||
syncDate = dateFormat.format(new Timestamp(System.currentTimeMillis()));
|
||||
}
|
||||
|
||||
// GETTER & SETTER
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getUrl() {
|
||||
return url;
|
||||
}
|
||||
public void setUrl(String url) {
|
||||
this.url = url;
|
||||
}
|
||||
|
||||
public String getSyncDate() {
|
||||
return syncDate;
|
||||
}
|
||||
public void setSyncDate(String syncDate) {
|
||||
this.syncDate = syncDate;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,41 @@
|
|||
package de.overview.wg.its.mispauth.model;
|
||||
|
||||
public class UploadState {
|
||||
|
||||
public enum State {
|
||||
PENDING,
|
||||
IN_PROGRESS,
|
||||
DONE,
|
||||
ERROR
|
||||
}
|
||||
private State currentState = State.PENDING;
|
||||
private String title, error;
|
||||
|
||||
|
||||
public UploadState(String title) {
|
||||
this.title = title;
|
||||
}
|
||||
|
||||
|
||||
public String getTitle() {
|
||||
return title;
|
||||
}
|
||||
public void setTitle(String title) {
|
||||
this.title = title;
|
||||
}
|
||||
|
||||
public String getError() {
|
||||
return error;
|
||||
}
|
||||
public void setError(String error) {
|
||||
this.error = error;
|
||||
}
|
||||
|
||||
public State getCurrentState() {
|
||||
return currentState;
|
||||
}
|
||||
public void setCurrentState(State currentState) {
|
||||
this.currentState = currentState;
|
||||
}
|
||||
|
||||
}
|
|
@ -5,6 +5,18 @@ import org.json.JSONObject;
|
|||
|
||||
public class User {
|
||||
|
||||
// todo: must be configable? Roles can be edited on instance
|
||||
public interface RoleId {
|
||||
int ADMIN = 1;
|
||||
int ORG_ADMIN = 2;
|
||||
int USER = 3;
|
||||
int PUBLISHER = 4;
|
||||
int SYNC_USER = 5;
|
||||
int READ_ONLY = 6;
|
||||
}
|
||||
|
||||
public static final String ROOT_KEY = "User";
|
||||
|
||||
private static String ID_KEY = "id";
|
||||
private static String PASSWORD_KEY = "password";
|
||||
private static String ORG_ID_KEY = "org_id";
|
||||
|
@ -51,79 +63,85 @@ public class User {
|
|||
private String dateCreated;
|
||||
private String dateModified;
|
||||
|
||||
public User() {}
|
||||
|
||||
public void fromJSON(JSONObject user) {
|
||||
try {
|
||||
|
||||
id = user.getInt(ID_KEY);
|
||||
password = user.getString(PASSWORD_KEY);
|
||||
orgId = user.getInt(ORG_ID_KEY);
|
||||
email = user.getString(EMAIL_KEY);
|
||||
autoAlert = user.getBoolean(AUTOALERT_KEY);
|
||||
authkey = user.getString(AUTHKEY_KEY);
|
||||
invitedBy = user.getInt(INVITED_BY_KEY);
|
||||
gpgKey = user.getString(GPGKEY_KEY);
|
||||
certifPublic = user.getString(CERTIF_PUBLIC);
|
||||
nidsSid = user.getInt(NIDS_SID);
|
||||
termsAccepted = user.getBoolean(TERMS_ACCEPTED_KEY);
|
||||
newsRead = user.getInt(NEWSREAD_KEY);
|
||||
roleId = user.getInt(ROLE_ID_KEY);
|
||||
changePw = user.getString(CHANGE_PW_KEY);
|
||||
contactAlert = user.getBoolean(CONTACT_ALERT_KEY);
|
||||
disabled = user.getBoolean(DISABLED_KEY);
|
||||
expiration = user.getString(EXPIRATION_KEY);
|
||||
currentLogin = user.getString(CURRENT_LOGIN_KEY);
|
||||
lastLogin = user.getString(LAST_LOGIN_KEY);
|
||||
forceLogout = user.getBoolean(FORCE_LOGOUT_KEY);
|
||||
dateCreated = user.getString(DATE_CREATED_KEY);
|
||||
dateModified = user.getString(DATE_MODIFIED_KEY);
|
||||
|
||||
} catch (JSONException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
public User() {
|
||||
}
|
||||
public User(JSONObject user) throws JSONException {
|
||||
fromJSON(user);
|
||||
}
|
||||
|
||||
public void fromJSON(JSONObject user) throws JSONException {
|
||||
|
||||
id = user.optInt(ID_KEY, -1);
|
||||
password = user.optString(PASSWORD_KEY);
|
||||
orgId = user.optInt(ORG_ID_KEY, -1);
|
||||
email = user.optString(EMAIL_KEY);
|
||||
autoAlert = user.optBoolean(AUTOALERT_KEY);
|
||||
authkey = user.optString(AUTHKEY_KEY);
|
||||
invitedBy = user.optInt(INVITED_BY_KEY, -1);
|
||||
gpgKey = user.optString(GPGKEY_KEY);
|
||||
certifPublic = user.optString(CERTIF_PUBLIC);
|
||||
nidsSid = user.optInt(NIDS_SID);
|
||||
termsAccepted = user.optBoolean(TERMS_ACCEPTED_KEY, false);
|
||||
newsRead = user.optInt(NEWSREAD_KEY);
|
||||
roleId = user.optInt(ROLE_ID_KEY, -1);
|
||||
changePw = user.optString(CHANGE_PW_KEY);
|
||||
contactAlert = user.optBoolean(CONTACT_ALERT_KEY, true);
|
||||
disabled = user.optBoolean(DISABLED_KEY, false);
|
||||
expiration = user.optString(EXPIRATION_KEY);
|
||||
currentLogin = user.optString(CURRENT_LOGIN_KEY);
|
||||
lastLogin = user.optString(LAST_LOGIN_KEY);
|
||||
forceLogout = user.optBoolean(FORCE_LOGOUT_KEY);
|
||||
dateCreated = user.optString(DATE_CREATED_KEY);
|
||||
dateModified = user.optString(DATE_MODIFIED_KEY);
|
||||
|
||||
}
|
||||
public JSONObject toJSON() {
|
||||
return toJSON(false);
|
||||
}
|
||||
public JSONObject toJSON(boolean forSyncQR) {
|
||||
JSONObject user = new JSONObject();
|
||||
|
||||
try {
|
||||
|
||||
user.put(ID_KEY, id);
|
||||
user.put(PASSWORD_KEY, password);
|
||||
user.put(ORG_ID_KEY, orgId);
|
||||
user.put(EMAIL_KEY, email);
|
||||
user.put(AUTOALERT_KEY, autoAlert);
|
||||
user.put(AUTHKEY_KEY, authkey);
|
||||
user.put(INVITED_BY_KEY, invitedBy);
|
||||
user.put(GPGKEY_KEY, gpgKey);
|
||||
user.put(CERTIF_PUBLIC, certifPublic);
|
||||
user.put(NIDS_SID, nidsSid);
|
||||
user.put(TERMS_ACCEPTED_KEY, termsAccepted);
|
||||
user.put(NEWSREAD_KEY, newsRead);
|
||||
user.put(ROLE_ID_KEY, roleId);
|
||||
user.put(CHANGE_PW_KEY, changePw);
|
||||
user.put(CONTACT_ALERT_KEY, contactAlert);
|
||||
user.put(DISABLED_KEY, disabled);
|
||||
user.put(EXPIRATION_KEY, expiration);
|
||||
user.put(CURRENT_LOGIN_KEY, currentLogin);
|
||||
user.put(LAST_LOGIN_KEY, lastLogin);
|
||||
user.put(FORCE_LOGOUT_KEY, forceLogout);
|
||||
user.put(DATE_CREATED_KEY, dateCreated);
|
||||
user.put(DATE_MODIFIED_KEY, dateModified);
|
||||
user.putOpt(EMAIL_KEY, email);
|
||||
|
||||
if (!forSyncQR) {
|
||||
|
||||
user.putOpt(ID_KEY, id);
|
||||
user.putOpt(ORG_ID_KEY, orgId);
|
||||
user.putOpt(AUTHKEY_KEY, authkey);
|
||||
user.putOpt(ROLE_ID_KEY, roleId);
|
||||
user.putOpt(PASSWORD_KEY, password);
|
||||
user.putOpt(CHANGE_PW_KEY, changePw);
|
||||
user.putOpt(TERMS_ACCEPTED_KEY, termsAccepted);
|
||||
user.putOpt(CERTIF_PUBLIC, certifPublic);
|
||||
user.putOpt(GPGKEY_KEY, gpgKey);
|
||||
user.putOpt(AUTOALERT_KEY, autoAlert);
|
||||
user.putOpt(INVITED_BY_KEY, invitedBy);
|
||||
user.putOpt(NIDS_SID, nidsSid);
|
||||
user.putOpt(NEWSREAD_KEY, newsRead);
|
||||
user.putOpt(CONTACT_ALERT_KEY, contactAlert);
|
||||
user.putOpt(DISABLED_KEY, disabled);
|
||||
user.putOpt(EXPIRATION_KEY, expiration);
|
||||
user.putOpt(CURRENT_LOGIN_KEY, currentLogin);
|
||||
user.putOpt(LAST_LOGIN_KEY, lastLogin);
|
||||
user.putOpt(FORCE_LOGOUT_KEY, forceLogout);
|
||||
user.putOpt(DATE_CREATED_KEY, dateCreated);
|
||||
user.putOpt(DATE_MODIFIED_KEY, dateModified);
|
||||
|
||||
}
|
||||
|
||||
} catch (JSONException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
return user;
|
||||
return user;
|
||||
}
|
||||
|
||||
|
||||
public int getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(int id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
@ -131,7 +149,6 @@ public class User {
|
|||
public String getPassword() {
|
||||
return password;
|
||||
}
|
||||
|
||||
public void setPassword(String password) {
|
||||
this.password = password;
|
||||
}
|
||||
|
@ -139,7 +156,6 @@ public class User {
|
|||
public int getOrgId() {
|
||||
return orgId;
|
||||
}
|
||||
|
||||
public void setOrgId(int orgId) {
|
||||
this.orgId = orgId;
|
||||
}
|
||||
|
@ -147,7 +163,6 @@ public class User {
|
|||
public String getEmail() {
|
||||
return email;
|
||||
}
|
||||
|
||||
public void setEmail(String email) {
|
||||
this.email = email;
|
||||
}
|
||||
|
@ -155,7 +170,6 @@ public class User {
|
|||
public boolean isAutoAlert() {
|
||||
return autoAlert;
|
||||
}
|
||||
|
||||
public void setAutoAlert(boolean autoAlert) {
|
||||
this.autoAlert = autoAlert;
|
||||
}
|
||||
|
@ -163,7 +177,6 @@ public class User {
|
|||
public String getAuthkey() {
|
||||
return authkey;
|
||||
}
|
||||
|
||||
public void setAuthkey(String authkey) {
|
||||
this.authkey = authkey;
|
||||
}
|
||||
|
@ -171,7 +184,6 @@ public class User {
|
|||
public int getInvitedBy() {
|
||||
return invitedBy;
|
||||
}
|
||||
|
||||
public void setInvitedBy(int invitedBy) {
|
||||
this.invitedBy = invitedBy;
|
||||
}
|
||||
|
@ -179,7 +191,6 @@ public class User {
|
|||
public String getGpgKey() {
|
||||
return gpgKey;
|
||||
}
|
||||
|
||||
public void setGpgKey(String gpgKey) {
|
||||
this.gpgKey = gpgKey;
|
||||
}
|
||||
|
@ -187,7 +198,6 @@ public class User {
|
|||
public String getCertifPublic() {
|
||||
return certifPublic;
|
||||
}
|
||||
|
||||
public void setCertifPublic(String certifPublic) {
|
||||
this.certifPublic = certifPublic;
|
||||
}
|
||||
|
@ -195,7 +205,6 @@ public class User {
|
|||
public int getNidsSid() {
|
||||
return nidsSid;
|
||||
}
|
||||
|
||||
public void setNidsSid(int nidsSid) {
|
||||
this.nidsSid = nidsSid;
|
||||
}
|
||||
|
@ -203,7 +212,6 @@ public class User {
|
|||
public boolean isTermsAccepted() {
|
||||
return termsAccepted;
|
||||
}
|
||||
|
||||
public void setTermsAccepted(boolean termsAccepted) {
|
||||
this.termsAccepted = termsAccepted;
|
||||
}
|
||||
|
@ -211,7 +219,6 @@ public class User {
|
|||
public int getNewsRead() {
|
||||
return newsRead;
|
||||
}
|
||||
|
||||
public void setNewsRead(int newsRead) {
|
||||
this.newsRead = newsRead;
|
||||
}
|
||||
|
@ -219,7 +226,6 @@ public class User {
|
|||
public int getRoleId() {
|
||||
return roleId;
|
||||
}
|
||||
|
||||
public void setRoleId(int roleId) {
|
||||
this.roleId = roleId;
|
||||
}
|
||||
|
@ -227,7 +233,6 @@ public class User {
|
|||
public String getChangePw() {
|
||||
return changePw;
|
||||
}
|
||||
|
||||
public void setChangePw(String changePw) {
|
||||
this.changePw = changePw;
|
||||
}
|
||||
|
@ -235,7 +240,6 @@ public class User {
|
|||
public boolean isContactAlert() {
|
||||
return contactAlert;
|
||||
}
|
||||
|
||||
public void setContactAlert(boolean contactAlert) {
|
||||
this.contactAlert = contactAlert;
|
||||
}
|
||||
|
@ -243,7 +247,6 @@ public class User {
|
|||
public boolean isDisabled() {
|
||||
return disabled;
|
||||
}
|
||||
|
||||
public void setDisabled(boolean disabled) {
|
||||
this.disabled = disabled;
|
||||
}
|
||||
|
@ -251,7 +254,6 @@ public class User {
|
|||
public String getExpiration() {
|
||||
return expiration;
|
||||
}
|
||||
|
||||
public void setExpiration(String expiration) {
|
||||
this.expiration = expiration;
|
||||
}
|
||||
|
@ -259,7 +261,6 @@ public class User {
|
|||
public String getCurrentLogin() {
|
||||
return currentLogin;
|
||||
}
|
||||
|
||||
public void setCurrentLogin(String currentLogin) {
|
||||
this.currentLogin = currentLogin;
|
||||
}
|
||||
|
@ -267,7 +268,6 @@ public class User {
|
|||
public String getLastLogin() {
|
||||
return lastLogin;
|
||||
}
|
||||
|
||||
public void setLastLogin(String lastLogin) {
|
||||
this.lastLogin = lastLogin;
|
||||
}
|
||||
|
@ -275,7 +275,6 @@ public class User {
|
|||
public boolean isForceLogout() {
|
||||
return forceLogout;
|
||||
}
|
||||
|
||||
public void setForceLogout(boolean forceLogout) {
|
||||
this.forceLogout = forceLogout;
|
||||
}
|
||||
|
@ -283,7 +282,6 @@ public class User {
|
|||
public String getDateCreated() {
|
||||
return dateCreated;
|
||||
}
|
||||
|
||||
public void setDateCreated(String dateCreated) {
|
||||
this.dateCreated = dateCreated;
|
||||
}
|
||||
|
@ -291,7 +289,6 @@ public class User {
|
|||
public String getDateModified() {
|
||||
return dateModified;
|
||||
}
|
||||
|
||||
public void setDateModified(String dateModified) {
|
||||
this.dateModified = dateModified;
|
||||
}
|
||||
|
|
|
@ -7,16 +7,31 @@ import com.android.volley.Request;
|
|||
import com.android.volley.RequestQueue;
|
||||
import com.android.volley.Response;
|
||||
import com.android.volley.VolleyError;
|
||||
import com.android.volley.toolbox.JsonArrayRequest;
|
||||
import com.android.volley.toolbox.HurlStack;
|
||||
import com.android.volley.toolbox.JsonObjectRequest;
|
||||
import com.android.volley.toolbox.Volley;
|
||||
import de.overview.wg.its.mispauth.R;
|
||||
import de.overview.wg.its.mispauth.auxiliary.PreferenceManager;
|
||||
import de.overview.wg.its.mispauth.auxiliary.ReadableError;
|
||||
import de.overview.wg.its.mispauth.model.Organisation;
|
||||
import de.overview.wg.its.mispauth.model.Server;
|
||||
import de.overview.wg.its.mispauth.model.User;
|
||||
import org.json.JSONArray;
|
||||
import org.json.JSONException;
|
||||
import org.json.JSONObject;
|
||||
|
||||
import javax.net.ssl.*;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.security.KeyManagementException;
|
||||
import java.security.KeyStore;
|
||||
import java.security.KeyStoreException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.cert.Certificate;
|
||||
import java.security.cert.CertificateException;
|
||||
import java.security.cert.CertificateFactory;
|
||||
import java.security.cert.X509Certificate;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
|
@ -38,6 +53,7 @@ public class MispRequest {
|
|||
private MispRequest(Context context) {
|
||||
requestQueue = Volley.newRequestQueue(context);
|
||||
preferenceManager = PreferenceManager.Instance(context);
|
||||
|
||||
loadSavedCredentials();
|
||||
}
|
||||
|
||||
|
@ -56,13 +72,10 @@ public class MispRequest {
|
|||
@Override
|
||||
public void onResponse(JSONObject response) {
|
||||
try {
|
||||
callback.onResult(response.getJSONObject("Organisation"));
|
||||
return;
|
||||
callback.onResult(response.getJSONObject(Organisation.ROOT_KEY));
|
||||
} catch (JSONException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
callback.onResult(response);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -88,14 +101,14 @@ public class MispRequest {
|
|||
*
|
||||
* @param callback return user associated with this API-Key
|
||||
*/
|
||||
public void myUserInformation(final UserCallback callback) {
|
||||
public void getMyUser(final UserCallback callback) {
|
||||
|
||||
Response.Listener<JSONObject> listener = new Response.Listener<JSONObject>() {
|
||||
@Override
|
||||
public void onResponse(JSONObject response) {
|
||||
|
||||
try {
|
||||
callback.onResult(response.getJSONObject("User"));
|
||||
callback.onResult(response.getJSONObject(User.ROOT_KEY));
|
||||
return;
|
||||
} catch (JSONException e) {
|
||||
e.printStackTrace();
|
||||
|
@ -114,7 +127,7 @@ public class MispRequest {
|
|||
};
|
||||
|
||||
if (serverUrl.isEmpty() || apiKey.isEmpty()) {
|
||||
Log.e(TAG, "myUserInformation: server or api key is empty!");
|
||||
Log.e(TAG, "getMyUser: server or api key is empty!");
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -137,13 +150,10 @@ public class MispRequest {
|
|||
@Override
|
||||
public void onResponse(JSONObject response) {
|
||||
try {
|
||||
callback.onResult(response.getJSONObject("Organisation"));
|
||||
return;
|
||||
callback.onResult(response.getJSONObject(Organisation.ROOT_KEY));
|
||||
} catch (JSONException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
callback.onResult(response);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -204,6 +214,73 @@ public class MispRequest {
|
|||
requestQueue.add(r);
|
||||
}
|
||||
|
||||
public void addUser(User user, final UserCallback callback) {
|
||||
Response.Listener<JSONObject> listener = new Response.Listener<JSONObject>() {
|
||||
@Override
|
||||
public void onResponse(JSONObject response) {
|
||||
try {
|
||||
callback.onResult(response.getJSONObject(User.ROOT_KEY));
|
||||
return;
|
||||
} catch (JSONException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
callback.onResult(response);
|
||||
}
|
||||
};
|
||||
|
||||
Response.ErrorListener errorListener = new Response.ErrorListener() {
|
||||
@Override
|
||||
public void onErrorResponse(VolleyError error) {
|
||||
callback.onError(error);
|
||||
}
|
||||
};
|
||||
|
||||
Request r = objectRequest(
|
||||
Request.Method.POST,
|
||||
serverUrl + "/admin/users/add",
|
||||
user.toJSON(),
|
||||
listener,
|
||||
errorListener
|
||||
);
|
||||
|
||||
requestQueue.add(r);
|
||||
}
|
||||
|
||||
public void addServer(Server server, final ServerCallback callback) {
|
||||
Response.Listener<JSONObject> listener = new Response.Listener<JSONObject>() {
|
||||
@Override
|
||||
public void onResponse(JSONObject response) {
|
||||
try {
|
||||
callback.onResult(response.getJSONObject(Server.ROOT_KEY));
|
||||
return;
|
||||
} catch (JSONException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
||||
callback.onResult(response);
|
||||
}
|
||||
};
|
||||
|
||||
Response.ErrorListener errorListener = new Response.ErrorListener() {
|
||||
@Override
|
||||
public void onErrorResponse(VolleyError error) {
|
||||
callback.onError(error);
|
||||
}
|
||||
};
|
||||
|
||||
Request r = objectRequest(
|
||||
Request.Method.POST,
|
||||
serverUrl + "/servers/add",
|
||||
server.toJSON(),
|
||||
listener,
|
||||
errorListener
|
||||
);
|
||||
|
||||
requestQueue.add(r);
|
||||
}
|
||||
|
||||
|
||||
private JsonArrayRequestWithJsonObject arrayRequestWithJsonObject(int method, String url,
|
||||
@Nullable JSONObject body,
|
||||
Response.Listener<JSONArray> listener,
|
||||
|
@ -247,6 +324,72 @@ public class MispRequest {
|
|||
this.apiKey = apiKey;
|
||||
}
|
||||
|
||||
// private SSLSocketFactory getSocketFactory(Context context) {
|
||||
//
|
||||
// CertificateFactory cf = null;
|
||||
// try {
|
||||
// cf = CertificateFactory.getInstance("X.509");
|
||||
// InputStream caInput = context.getResources().openRawResource(R.raw.server);
|
||||
// Certificate ca;
|
||||
// try {
|
||||
// ca = cf.generateCertificate(caInput);
|
||||
// Log.e("CERT", "ca=" + ((X509Certificate) ca).getSubjectDN());
|
||||
// } finally {
|
||||
// caInput.close();
|
||||
// }
|
||||
//
|
||||
//
|
||||
// String keyStoreType = KeyStore.getDefaultType();
|
||||
// KeyStore keyStore = KeyStore.getInstance(keyStoreType);
|
||||
// keyStore.load(null, null);
|
||||
// keyStore.setCertificateEntry("ca", ca);
|
||||
//
|
||||
//
|
||||
// String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm();
|
||||
// TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlgorithm);
|
||||
// tmf.init(keyStore);
|
||||
//
|
||||
//
|
||||
// HostnameVerifier hostnameVerifier = new HostnameVerifier() {
|
||||
// @Override
|
||||
// public boolean verify(String hostname, SSLSession session) {
|
||||
//
|
||||
// Log.e("CipherUsed", session.getCipherSuite());
|
||||
// return hostname.compareTo("192.168.1.10")==0; //The Hostname of your server
|
||||
//
|
||||
// }
|
||||
// };
|
||||
//
|
||||
//
|
||||
// HttpsURLConnection.setDefaultHostnameVerifier(hostnameVerifier);
|
||||
// SSLContext context = null;
|
||||
// context = SSLContext.getInstance("TLS");
|
||||
//
|
||||
// context.init(null, tmf.getTrustManagers(), null);
|
||||
// HttpsURLConnection.setDefaultSSLSocketFactory(context.getSocketFactory());
|
||||
//
|
||||
// SSLSocketFactory sf = context.getSocketFactory();
|
||||
//
|
||||
//
|
||||
// return sf;
|
||||
//
|
||||
// } catch (CertificateException e) {
|
||||
// e.printStackTrace();
|
||||
// } catch (NoSuchAlgorithmException e) {
|
||||
// e.printStackTrace();
|
||||
// } catch (KeyStoreException e) {
|
||||
// e.printStackTrace();
|
||||
// } catch (FileNotFoundException e) {
|
||||
// e.printStackTrace();
|
||||
// } catch (IOException e) {
|
||||
// e.printStackTrace();
|
||||
// } catch (KeyManagementException e) {
|
||||
// e.printStackTrace();
|
||||
// }
|
||||
//
|
||||
// return null;
|
||||
// }
|
||||
|
||||
public static MispRequest Instance(Context context) {
|
||||
if (instance == null) {
|
||||
instance = new MispRequest(context);
|
||||
|
@ -264,12 +407,12 @@ public class MispRequest {
|
|||
void onError(VolleyError volleyError);
|
||||
}
|
||||
public interface UserCallback {
|
||||
void onResult(JSONObject myOrganisationInformation);
|
||||
void onResult(JSONObject userInformation);
|
||||
|
||||
void onError(VolleyError volleyError);
|
||||
}
|
||||
public interface ServerCallback {
|
||||
void onResult(JSONObject servers);
|
||||
void onResult(JSONObject server);
|
||||
void onError(VolleyError volleyError);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,8 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<set xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:interpolator="@android:anim/decelerate_interpolator">
|
||||
<translate
|
||||
android:fromXDelta="-100%" android:toXDelta="0%"
|
||||
android:fromYDelta="0%" android:toYDelta="0%"
|
||||
android:duration="300"/>
|
||||
</set>
|
|
@ -1,8 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<set xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:interpolator="@android:anim/decelerate_interpolator">
|
||||
<translate
|
||||
android:fromXDelta="100%" android:toXDelta="0%"
|
||||
android:fromYDelta="0%" android:toYDelta="0%"
|
||||
android:duration="300" />
|
||||
</set>
|
|
@ -1,8 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<set xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:interpolator="@android:anim/decelerate_interpolator">
|
||||
<translate
|
||||
android:fromXDelta="0%" android:toXDelta="-100%"
|
||||
android:fromYDelta="0%" android:toYDelta="0%"
|
||||
android:duration="150"/>
|
||||
</set>
|
|
@ -1,8 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<set xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:interpolator="@android:anim/decelerate_interpolator">
|
||||
<translate
|
||||
android:fromXDelta="0%" android:toXDelta="100%"
|
||||
android:fromYDelta="0%" android:toYDelta="0%"
|
||||
android:duration="150" />
|
||||
</set>
|
|
@ -0,0 +1,16 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<set xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:shareInterpolator="true"
|
||||
android:interpolator="@android:anim/accelerate_interpolator">
|
||||
|
||||
<translate
|
||||
android:duration="150"
|
||||
android:fromYDelta="0%"
|
||||
android:toYDelta="15%"/>
|
||||
|
||||
<alpha
|
||||
android:duration="150"
|
||||
android:fromAlpha="1"
|
||||
android:toAlpha="0"/>
|
||||
</set>
|
|
@ -0,0 +1,21 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<set xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:shareInterpolator="false">
|
||||
|
||||
<translate
|
||||
android:interpolator="@android:anim/decelerate_interpolator"
|
||||
android:duration="200"
|
||||
android:fromYDelta="15%"
|
||||
android:toYDelta="0%"/>
|
||||
|
||||
<scale
|
||||
android:interpolator="@android:anim/decelerate_interpolator"
|
||||
android:duration="120"
|
||||
android:fromXScale="0.8"
|
||||
android:fromYScale="0.6"
|
||||
android:pivotX="50%"
|
||||
android:pivotY="100%"
|
||||
android:toXScale="1.0"
|
||||
android:toYScale="1.0"/>
|
||||
</set>
|
|
@ -1,9 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<objectAnimator
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:interpolator="@android:interpolator/accelerate_quad"
|
||||
android:valueFrom="0"
|
||||
android:valueTo="1"
|
||||
android:propertyName="alpha"
|
||||
android:duration="@android:integer/config_mediumAnimTime"/>
|
|
@ -1,34 +1,34 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:aapt="http://schemas.android.com/aapt"
|
||||
android:width="108dp"
|
||||
android:height="108dp"
|
||||
android:viewportHeight="108"
|
||||
android:viewportWidth="108">
|
||||
<path
|
||||
android:fillType="evenOdd"
|
||||
android:pathData="M32,64C32,64 38.39,52.99 44.13,50.95C51.37,48.37 70.14,49.57 70.14,49.57L108.26,87.69L108,109.01L75.97,107.97L32,64Z"
|
||||
android:strokeColor="#00000000"
|
||||
android:strokeWidth="1">
|
||||
<aapt:attr name="android:fillColor">
|
||||
<gradient
|
||||
android:endX="78.5885"
|
||||
android:endY="90.9159"
|
||||
android:startX="48.7653"
|
||||
android:startY="61.0927"
|
||||
android:type="linear">
|
||||
<item
|
||||
android:color="#44000000"
|
||||
android:offset="0.0" />
|
||||
<item
|
||||
android:color="#00000000"
|
||||
android:offset="1.0" />
|
||||
</gradient>
|
||||
</aapt:attr>
|
||||
</path>
|
||||
<path
|
||||
android:fillColor="#FFFFFF"
|
||||
android:fillType="nonZero"
|
||||
android:pathData="M66.94,46.02L66.94,46.02C72.44,50.07 76,56.61 76,64L32,64C32,56.61 35.56,50.11 40.98,46.06L36.18,41.19C35.45,40.45 35.45,39.3 36.18,38.56C36.91,37.81 38.05,37.81 38.78,38.56L44.25,44.05C47.18,42.57 50.48,41.71 54,41.71C57.48,41.71 60.78,42.57 63.68,44.05L69.11,38.56C69.84,37.81 70.98,37.81 71.71,38.56C72.44,39.3 72.44,40.45 71.71,41.19L66.94,46.02ZM62.94,56.92C64.08,56.92 65,56.01 65,54.88C65,53.76 64.08,52.85 62.94,52.85C61.8,52.85 60.88,53.76 60.88,54.88C60.88,56.01 61.8,56.92 62.94,56.92ZM45.06,56.92C46.2,56.92 47.13,56.01 47.13,54.88C47.13,53.76 46.2,52.85 45.06,52.85C43.92,52.85 43,53.76 43,54.88C43,56.01 43.92,56.92 45.06,56.92Z"
|
||||
android:strokeColor="#00000000"
|
||||
android:strokeWidth="1" />
|
||||
xmlns:aapt="http://schemas.android.com/aapt"
|
||||
android:width="108dp"
|
||||
android:height="108dp"
|
||||
android:viewportHeight="108"
|
||||
android:viewportWidth="108">
|
||||
<path
|
||||
android:fillType="evenOdd"
|
||||
android:pathData="M32,64C32,64 38.39,52.99 44.13,50.95C51.37,48.37 70.14,49.57 70.14,49.57L108.26,87.69L108,109.01L75.97,107.97L32,64Z"
|
||||
android:strokeColor="#00000000"
|
||||
android:strokeWidth="1">
|
||||
<aapt:attr name="android:fillColor">
|
||||
<gradient
|
||||
android:endX="78.5885"
|
||||
android:endY="90.9159"
|
||||
android:startX="48.7653"
|
||||
android:startY="61.0927"
|
||||
android:type="linear">
|
||||
<item
|
||||
android:color="#44000000"
|
||||
android:offset="0.0"/>
|
||||
<item
|
||||
android:color="#00000000"
|
||||
android:offset="1.0"/>
|
||||
</gradient>
|
||||
</aapt:attr>
|
||||
</path>
|
||||
<path
|
||||
android:fillColor="#FFFFFF"
|
||||
android:fillType="nonZero"
|
||||
android:pathData="M66.94,46.02L66.94,46.02C72.44,50.07 76,56.61 76,64L32,64C32,56.61 35.56,50.11 40.98,46.06L36.18,41.19C35.45,40.45 35.45,39.3 36.18,38.56C36.91,37.81 38.05,37.81 38.78,38.56L44.25,44.05C47.18,42.57 50.48,41.71 54,41.71C57.48,41.71 60.78,42.57 63.68,44.05L69.11,38.56C69.84,37.81 70.98,37.81 71.71,38.56C72.44,39.3 72.44,40.45 71.71,41.19L66.94,46.02ZM62.94,56.92C64.08,56.92 65,56.01 65,54.88C65,53.76 64.08,52.85 62.94,52.85C61.8,52.85 60.88,53.76 60.88,54.88C60.88,56.01 61.8,56.92 62.94,56.92ZM45.06,56.92C46.2,56.92 47.13,56.01 47.13,54.88C47.13,53.76 46.2,52.85 45.06,52.85C43.92,52.85 43,53.76 43,54.88C43,56.01 43.92,56.92 45.06,56.92Z"
|
||||
android:strokeColor="#00000000"
|
||||
android:strokeWidth="1"/>
|
||||
</vector>
|
||||
|
|
|
@ -1,13 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:shape="rectangle">
|
||||
|
||||
<solid
|
||||
android:color="#FFFFFF" />
|
||||
|
||||
<corners
|
||||
android:topLeftRadius="6dp"
|
||||
android:topRightRadius="6dp" />
|
||||
|
||||
</shape>
|
|
@ -1,5 +0,0 @@
|
|||
<vector android:height="24dp" android:tint="#FFFFFF"
|
||||
android:viewportHeight="24.0" android:viewportWidth="24.0"
|
||||
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<path android:fillColor="#FF000000" android:pathData="M19,13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z"/>
|
||||
</vector>
|
|
@ -1,5 +0,0 @@
|
|||
<vector android:height="24dp" android:tint="#FFFFFF"
|
||||
android:viewportHeight="24.0" android:viewportWidth="24.0"
|
||||
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<path android:fillColor="#FF000000" android:pathData="M20,11H7.83l5.59,-5.59L12,4l-8,8 8,8 1.41,-1.41L7.83,13H20v-2z"/>
|
||||
</vector>
|
|
@ -1,5 +0,0 @@
|
|||
<vector android:height="24dp" android:tint="#FFFFFF"
|
||||
android:viewportHeight="24.0" android:viewportWidth="24.0"
|
||||
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<path android:fillColor="#FF000000" android:pathData="M9,16.17L4.83,12l-1.42,1.41L9,19 21,7l-1.41,-1.41z"/>
|
||||
</vector>
|
|
@ -1,5 +0,0 @@
|
|||
<vector android:height="24dp" android:tint="#FFFFFF"
|
||||
android:viewportHeight="24.0" android:viewportWidth="24.0"
|
||||
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<path android:fillColor="#FF000000" android:pathData="M19.35,10.04C18.67,6.59 15.64,4 12,4 9.11,4 6.6,5.64 5.35,8.04 2.34,8.36 0,10.91 0,14c0,3.31 2.69,6 6,6h13c2.76,0 5,-2.24 5,-5 0,-2.64 -2.05,-4.78 -4.65,-4.96zM17,13l-5,5 -5,-5h3V9h4v4h3z"/>
|
||||
</vector>
|
|
@ -1,5 +0,0 @@
|
|||
<vector android:height="24dp" android:tint="#FFFFFF"
|
||||
android:viewportHeight="24.0" android:viewportWidth="24.0"
|
||||
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<path android:fillColor="#FF000000" android:pathData="M3,17.25V21h3.75L17.81,9.94l-3.75,-3.75L3,17.25zM20.71,7.04c0.39,-0.39 0.39,-1.02 0,-1.41l-2.34,-2.34c-0.39,-0.39 -1.02,-0.39 -1.41,0l-1.83,1.83 3.75,3.75 1.83,-1.83z"/>
|
||||
</vector>
|
|
@ -1,5 +0,0 @@
|
|||
<vector android:height="24dp" android:tint="#FFFFFF"
|
||||
android:viewportHeight="24.0" android:viewportWidth="24.0"
|
||||
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<path android:fillColor="#FF000000" android:pathData="M14.4,6L14,4H5v17h2v-7h5.6l0.4,2h7V6z"/>
|
||||
</vector>
|
|
@ -1,5 +0,0 @@
|
|||
<vector android:height="24dp" android:tint="#FFFFFF"
|
||||
android:viewportHeight="24.0" android:viewportWidth="24.0"
|
||||
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<path android:fillColor="#FF000000" android:pathData="M12,2C6.48,2 2,6.48 2,12s4.48,10 10,10 10,-4.48 10,-10S17.52,2 12,2zM13,17h-2v-6h2v6zM13,9h-2L11,7h2v2z"/>
|
||||
</vector>
|
|
@ -1,170 +1,74 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="108dp"
|
||||
android:height="108dp"
|
||||
android:viewportHeight="108"
|
||||
android:viewportWidth="108">
|
||||
<path
|
||||
android:fillColor="#26A69A"
|
||||
android:pathData="M0,0h108v108h-108z" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M9,0L9,108"
|
||||
android:strokeColor="#33FFFFFF"
|
||||
android:strokeWidth="0.8" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M19,0L19,108"
|
||||
android:strokeColor="#33FFFFFF"
|
||||
android:strokeWidth="0.8" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M29,0L29,108"
|
||||
android:strokeColor="#33FFFFFF"
|
||||
android:strokeWidth="0.8" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M39,0L39,108"
|
||||
android:strokeColor="#33FFFFFF"
|
||||
android:strokeWidth="0.8" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M49,0L49,108"
|
||||
android:strokeColor="#33FFFFFF"
|
||||
android:strokeWidth="0.8" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M59,0L59,108"
|
||||
android:strokeColor="#33FFFFFF"
|
||||
android:strokeWidth="0.8" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M69,0L69,108"
|
||||
android:strokeColor="#33FFFFFF"
|
||||
android:strokeWidth="0.8" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M79,0L79,108"
|
||||
android:strokeColor="#33FFFFFF"
|
||||
android:strokeWidth="0.8" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M89,0L89,108"
|
||||
android:strokeColor="#33FFFFFF"
|
||||
android:strokeWidth="0.8" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M99,0L99,108"
|
||||
android:strokeColor="#33FFFFFF"
|
||||
android:strokeWidth="0.8" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,9L108,9"
|
||||
android:strokeColor="#33FFFFFF"
|
||||
android:strokeWidth="0.8" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,19L108,19"
|
||||
android:strokeColor="#33FFFFFF"
|
||||
android:strokeWidth="0.8" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,29L108,29"
|
||||
android:strokeColor="#33FFFFFF"
|
||||
android:strokeWidth="0.8" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,39L108,39"
|
||||
android:strokeColor="#33FFFFFF"
|
||||
android:strokeWidth="0.8" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,49L108,49"
|
||||
android:strokeColor="#33FFFFFF"
|
||||
android:strokeWidth="0.8" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,59L108,59"
|
||||
android:strokeColor="#33FFFFFF"
|
||||
android:strokeWidth="0.8" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,69L108,69"
|
||||
android:strokeColor="#33FFFFFF"
|
||||
android:strokeWidth="0.8" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,79L108,79"
|
||||
android:strokeColor="#33FFFFFF"
|
||||
android:strokeWidth="0.8" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,89L108,89"
|
||||
android:strokeColor="#33FFFFFF"
|
||||
android:strokeWidth="0.8" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M0,99L108,99"
|
||||
android:strokeColor="#33FFFFFF"
|
||||
android:strokeWidth="0.8" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M19,29L89,29"
|
||||
android:strokeColor="#33FFFFFF"
|
||||
android:strokeWidth="0.8" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M19,39L89,39"
|
||||
android:strokeColor="#33FFFFFF"
|
||||
android:strokeWidth="0.8" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M19,49L89,49"
|
||||
android:strokeColor="#33FFFFFF"
|
||||
android:strokeWidth="0.8" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M19,59L89,59"
|
||||
android:strokeColor="#33FFFFFF"
|
||||
android:strokeWidth="0.8" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M19,69L89,69"
|
||||
android:strokeColor="#33FFFFFF"
|
||||
android:strokeWidth="0.8" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M19,79L89,79"
|
||||
android:strokeColor="#33FFFFFF"
|
||||
android:strokeWidth="0.8" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M29,19L29,89"
|
||||
android:strokeColor="#33FFFFFF"
|
||||
android:strokeWidth="0.8" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M39,19L39,89"
|
||||
android:strokeColor="#33FFFFFF"
|
||||
android:strokeWidth="0.8" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M49,19L49,89"
|
||||
android:strokeColor="#33FFFFFF"
|
||||
android:strokeWidth="0.8" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M59,19L59,89"
|
||||
android:strokeColor="#33FFFFFF"
|
||||
android:strokeWidth="0.8" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M69,19L69,89"
|
||||
android:strokeColor="#33FFFFFF"
|
||||
android:strokeWidth="0.8" />
|
||||
<path
|
||||
android:fillColor="#00000000"
|
||||
android:pathData="M79,19L79,89"
|
||||
android:strokeColor="#33FFFFFF"
|
||||
android:strokeWidth="0.8" />
|
||||
<vector
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:height="108dp"
|
||||
android:width="108dp"
|
||||
android:viewportHeight="108"
|
||||
android:viewportWidth="108">
|
||||
<path android:fillColor="#26A69A"
|
||||
android:pathData="M0,0h108v108h-108z"/>
|
||||
<path android:fillColor="#00000000" android:pathData="M9,0L9,108"
|
||||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||
<path android:fillColor="#00000000" android:pathData="M19,0L19,108"
|
||||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||
<path android:fillColor="#00000000" android:pathData="M29,0L29,108"
|
||||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||
<path android:fillColor="#00000000" android:pathData="M39,0L39,108"
|
||||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||
<path android:fillColor="#00000000" android:pathData="M49,0L49,108"
|
||||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||
<path android:fillColor="#00000000" android:pathData="M59,0L59,108"
|
||||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||
<path android:fillColor="#00000000" android:pathData="M69,0L69,108"
|
||||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||
<path android:fillColor="#00000000" android:pathData="M79,0L79,108"
|
||||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||
<path android:fillColor="#00000000" android:pathData="M89,0L89,108"
|
||||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||
<path android:fillColor="#00000000" android:pathData="M99,0L99,108"
|
||||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||
<path android:fillColor="#00000000" android:pathData="M0,9L108,9"
|
||||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||
<path android:fillColor="#00000000" android:pathData="M0,19L108,19"
|
||||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||
<path android:fillColor="#00000000" android:pathData="M0,29L108,29"
|
||||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||
<path android:fillColor="#00000000" android:pathData="M0,39L108,39"
|
||||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||
<path android:fillColor="#00000000" android:pathData="M0,49L108,49"
|
||||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||
<path android:fillColor="#00000000" android:pathData="M0,59L108,59"
|
||||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||
<path android:fillColor="#00000000" android:pathData="M0,69L108,69"
|
||||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||
<path android:fillColor="#00000000" android:pathData="M0,79L108,79"
|
||||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||
<path android:fillColor="#00000000" android:pathData="M0,89L108,89"
|
||||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||
<path android:fillColor="#00000000" android:pathData="M0,99L108,99"
|
||||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||
<path android:fillColor="#00000000" android:pathData="M19,29L89,29"
|
||||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||
<path android:fillColor="#00000000" android:pathData="M19,39L89,39"
|
||||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||
<path android:fillColor="#00000000" android:pathData="M19,49L89,49"
|
||||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||
<path android:fillColor="#00000000" android:pathData="M19,59L89,59"
|
||||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||
<path android:fillColor="#00000000" android:pathData="M19,69L89,69"
|
||||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||
<path android:fillColor="#00000000" android:pathData="M19,79L89,79"
|
||||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||
<path android:fillColor="#00000000" android:pathData="M29,19L29,89"
|
||||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||
<path android:fillColor="#00000000" android:pathData="M39,19L39,89"
|
||||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||
<path android:fillColor="#00000000" android:pathData="M49,19L49,89"
|
||||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||
<path android:fillColor="#00000000" android:pathData="M59,19L59,89"
|
||||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||
<path android:fillColor="#00000000" android:pathData="M69,19L69,89"
|
||||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||
<path android:fillColor="#00000000" android:pathData="M79,19L79,89"
|
||||
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||
</vector>
|
||||
|
|
|
@ -1,5 +0,0 @@
|
|||
<vector android:height="24dp" android:tint="#FFFFFF"
|
||||
android:viewportHeight="24.0" android:viewportWidth="24.0"
|
||||
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<path android:fillColor="#FF000000" android:pathData="M19,3h-1L18,1h-2v2L8,3L8,1L6,1v2L5,3c-1.11,0 -2,0.9 -2,2v14c0,1.1 0.89,2 2,2h14c1.1,0 2,-0.9 2,-2L21,5c0,-1.1 -0.9,-2 -2,-2zM12,6c1.66,0 3,1.34 3,3s-1.34,3 -3,3 -3,-1.34 -3,-3 1.34,-3 3,-3zM18,18L6,18v-1c0,-2 4,-3.1 6,-3.1s6,1.1 6,3.1v1z"/>
|
||||
</vector>
|
|
@ -1,5 +0,0 @@
|
|||
<vector android:height="256dp" android:tint="#FFFFFF"
|
||||
android:viewportHeight="24.0" android:viewportWidth="24.0"
|
||||
android:width="256dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<path android:fillColor="#FF000000" android:pathData="M3,5v4h2L5,5h4L9,3L5,3c-1.1,0 -2,0.9 -2,2zM5,15L3,15v4c0,1.1 0.9,2 2,2h4v-2L5,19v-4zM19,19h-4v2h4c1.1,0 2,-0.9 2,-2v-4h-2v4zM19,3h-4v2h4v4h2L21,5c0,-1.1 -0.9,-2 -2,-2z"/>
|
||||
</vector>
|
|
@ -1,5 +0,0 @@
|
|||
<vector android:height="24dp" android:tint="#FFFFFF"
|
||||
android:viewportHeight="24.0" android:viewportWidth="24.0"
|
||||
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<path android:fillColor="#FF000000" android:pathData="M4,10v7h3v-7L4,10zM10,10v7h3v-7h-3zM2,22h19v-3L2,19v3zM16,10v7h3v-7h-3zM11.5,1L2,6v2h19L21,6l-9.5,-5z"/>
|
||||
</vector>
|
|
@ -1,5 +0,0 @@
|
|||
<vector android:height="24dp" android:tint="#FFFFFF"
|
||||
android:viewportHeight="24.0" android:viewportWidth="24.0"
|
||||
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<path android:fillColor="#FF000000" android:pathData="M19.43,12.98c0.04,-0.32 0.07,-0.64 0.07,-0.98s-0.03,-0.66 -0.07,-0.98l2.11,-1.65c0.19,-0.15 0.24,-0.42 0.12,-0.64l-2,-3.46c-0.12,-0.22 -0.39,-0.3 -0.61,-0.22l-2.49,1c-0.52,-0.4 -1.08,-0.73 -1.69,-0.98l-0.38,-2.65C14.46,2.18 14.25,2 14,2h-4c-0.25,0 -0.46,0.18 -0.49,0.42l-0.38,2.65c-0.61,0.25 -1.17,0.59 -1.69,0.98l-2.49,-1c-0.23,-0.09 -0.49,0 -0.61,0.22l-2,3.46c-0.13,0.22 -0.07,0.49 0.12,0.64l2.11,1.65c-0.04,0.32 -0.07,0.65 -0.07,0.98s0.03,0.66 0.07,0.98l-2.11,1.65c-0.19,0.15 -0.24,0.42 -0.12,0.64l2,3.46c0.12,0.22 0.39,0.3 0.61,0.22l2.49,-1c0.52,0.4 1.08,0.73 1.69,0.98l0.38,2.65c0.03,0.24 0.24,0.42 0.49,0.42h4c0.25,0 0.46,-0.18 0.49,-0.42l0.38,-2.65c0.61,-0.25 1.17,-0.59 1.69,-0.98l2.49,1c0.23,0.09 0.49,0 0.61,-0.22l2,-3.46c0.12,-0.22 0.07,-0.49 -0.12,-0.64l-2.11,-1.65zM12,15.5c-1.93,0 -3.5,-1.57 -3.5,-3.5s1.57,-3.5 3.5,-3.5 3.5,1.57 3.5,3.5 -1.57,3.5 -3.5,3.5z"/>
|
||||
</vector>
|
|
@ -1,9 +0,0 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24.0"
|
||||
android:viewportHeight="24.0">
|
||||
<path
|
||||
android:fillColor="#11000000"
|
||||
android:pathData="M12,4L12,1L8,5l4,4L12,6c3.31,0 6,2.69 6,6 0,1.01 -0.25,1.97 -0.7,2.8l1.46,1.46C19.54,15.03 20,13.57 20,12c0,-4.42 -3.58,-8 -8,-8zM12,18c-3.31,0 -6,-2.69 -6,-6 0,-1.01 0.25,-1.97 0.7,-2.8L5.24,7.74C4.46,8.97 4,10.43 4,12c0,4.42 3.58,8 8,8v3l4,-4 -4,-4v3z"/>
|
||||
</vector>
|
|
@ -1,5 +0,0 @@
|
|||
<vector android:height="24dp" android:tint="#FFFFFF"
|
||||
android:viewportHeight="24.0" android:viewportWidth="24.0"
|
||||
android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<path android:fillColor="#FF000000" android:pathData="M12,4L12,1L8,5l4,4L12,6c3.31,0 6,2.69 6,6 0,1.01 -0.25,1.97 -0.7,2.8l1.46,1.46C19.54,15.03 20,13.57 20,12c0,-4.42 -3.58,-8 -8,-8zM12,18c-3.31,0 -6,-2.69 -6,-6 0,-1.01 0.25,-1.97 0.7,-2.8L5.24,7.74C4.46,8.97 4,10.43 4,12c0,4.42 3.58,8 8,8v3l4,-4 -4,-4v3z"/>
|
||||
</vector>
|
|
@ -0,0 +1,9 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24.0"
|
||||
android:viewportHeight="24.0">
|
||||
<path
|
||||
android:fillColor="#FF000000"
|
||||
android:pathData="M19,13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z"/>
|
||||
</vector>
|
|
@ -0,0 +1,9 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24.0"
|
||||
android:viewportHeight="24.0">
|
||||
<path
|
||||
android:fillColor="#FF000000"
|
||||
android:pathData="M9,16.17L5.53,12.7c-0.39,-0.39 -1.02,-0.39 -1.41,0l0,0c-0.39,0.39 -0.39,1.02 0,1.41l4.18,4.18c0.39,0.39 1.02,0.39 1.41,0L20.29,7.71c0.39,-0.39 0.39,-1.02 0,-1.41l0,0c-0.39,-0.39 -1.02,-0.39 -1.41,0L9,16.17z"/>
|
||||
</vector>
|
|
@ -0,0 +1,9 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24.0"
|
||||
android:viewportHeight="24.0">
|
||||
<path
|
||||
android:fillColor="#FF000000"
|
||||
android:pathData="M19,6.41L17.59,5 12,10.59 6.41,5 5,6.41 10.59,12 5,17.59 6.41,19 12,13.41 17.59,19 19,17.59 13.41,12z"/>
|
||||
</vector>
|
|
@ -0,0 +1,9 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24.0"
|
||||
android:viewportHeight="24.0">
|
||||
<path
|
||||
android:fillColor="#FF000000"
|
||||
android:pathData="M19.35,10.04C18.67,6.59 15.64,4 12,4 9.11,4 6.6,5.64 5.35,8.04 2.34,8.36 0,10.91 0,14c0,3.31 2.69,6 6,6h13c2.76,0 5,-2.24 5,-5 0,-2.64 -2.05,-4.78 -4.65,-4.96zM17,13l-5,5 -5,-5h3V9h4v4h3z"/>
|
||||
</vector>
|
|
@ -0,0 +1,9 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24.0"
|
||||
android:viewportHeight="24.0">
|
||||
<path
|
||||
android:fillColor="#FF000000"
|
||||
android:pathData="M19.35,10.04C18.67,6.59 15.64,4 12,4C9.11,4 6.6,5.64 5.35,8.04C2.34,8.36 0,10.91 0,14c0,3.31 2.69,6 6,6h13c2.76,0 5,-2.24 5,-5C24,12.36 21.95,10.22 19.35,10.04zM14,13v4h-4v-4H7l4.65,-4.65c0.2,-0.2 0.51,-0.2 0.71,0L17,13H14z"/>
|
||||
</vector>
|
|
@ -0,0 +1,9 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24.0"
|
||||
android:viewportHeight="24.0">
|
||||
<path
|
||||
android:fillColor="#FF000000"
|
||||
android:pathData="M19,3h-1L18,1h-2v2L8,3L8,1L6,1v2L5,3c-1.11,0 -2,0.9 -2,2v14c0,1.1 0.89,2 2,2h14c1.1,0 2,-0.9 2,-2L21,5c0,-1.1 -0.9,-2 -2,-2zM12,6c1.66,0 3,1.34 3,3s-1.34,3 -3,3 -3,-1.34 -3,-3 1.34,-3 3,-3zM18,18L6,18v-1c0,-2 4,-3.1 6,-3.1s6,1.1 6,3.1v1z"/>
|
||||
</vector>
|
|
@ -0,0 +1,9 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24.0"
|
||||
android:viewportHeight="24.0">
|
||||
<path
|
||||
android:fillColor="#FF000000"
|
||||
android:pathData="M12,4l-1.41,1.41L16.17,11H4v2h12.17l-5.58,5.59L12,20l8,-8z"/>
|
||||
</vector>
|
|
@ -0,0 +1,9 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24.0"
|
||||
android:viewportHeight="24.0">
|
||||
<path
|
||||
android:fillColor="#FF000000"
|
||||
android:pathData="M8,2C6.9,2 6,2.9 6,4v3.17C6,7.7 6.21,8.21 6.59,8.59L10,12l-3.42,3.42C6.21,15.8 6,16.31 6,16.84V20c0,1.1 0.9,2 2,2h8c1.1,0 2,-0.9 2,-2v-3.16c0,-0.53 -0.21,-1.04 -0.58,-1.41L14,12l3.41,-3.4C17.79,8.22 18,7.71 18,7.18V4c0,-1.1 -0.9,-2 -2,-2H8zM16,16.5V19c0,0.55 -0.45,1 -1,1H9c-0.55,0 -1,-0.45 -1,-1v-2.5l4,-4L16,16.5zM12,11.5l-4,-4V5c0,-0.55 0.45,-1 1,-1h6c0.55,0 1,0.45 1,1v2.5L12,11.5z"/>
|
||||
</vector>
|
|
@ -0,0 +1,9 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24.0"
|
||||
android:viewportHeight="24.0">
|
||||
<path
|
||||
android:fillColor="#FF000000"
|
||||
android:pathData="M12.65,10C11.83,7.67 9.61,6 7,6c-3.31,0 -6,2.69 -6,6s2.69,6 6,6c2.61,0 4.83,-1.67 5.65,-4H17v4h4v-4h2v-4H12.65zM7,14c-1.1,0 -2,-0.9 -2,-2s0.9,-2 2,-2 2,0.9 2,2 -0.9,2 -2,2z"/>
|
||||
</vector>
|
|
@ -0,0 +1,12 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24.0"
|
||||
android:viewportHeight="24.0">
|
||||
<path
|
||||
android:fillColor="#FF000000"
|
||||
android:pathData="M12,2C6.48,2 2,6.48 2,12s4.48,10 10,10c5.52,0 10,-4.48 10,-10S17.52,2 12,2zM12,20c-4.41,0 -8,-3.59 -8,-8s3.59,-8 8,-8c4.41,0 8,3.59 8,8S16.41,20 12,20z"/>
|
||||
<path
|
||||
android:fillColor="#FF000000"
|
||||
android:pathData="M15.88,8.29L10,14.17l-1.88,-1.88c-0.39,-0.39 -1.02,-0.39 -1.41,0l0,0c-0.39,0.39 -0.39,1.02 0,1.41l2.59,2.59c0.39,0.39 1.02,0.39 1.41,0L17.3,9.7c0.39,-0.39 0.39,-1.02 0,-1.41l0,0C16.91,7.9 16.27,7.9 15.88,8.29z"/>
|
||||
</vector>
|
|
@ -0,0 +1,9 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24.0"
|
||||
android:viewportHeight="24.0">
|
||||
<path
|
||||
android:fillColor="#FF000000"
|
||||
android:pathData="M13.89,8.7L12,10.59L10.11,8.7c-0.39,-0.39 -1.02,-0.39 -1.41,0l0,0c-0.39,0.39 -0.39,1.02 0,1.41L10.59,12L8.7,13.89c-0.39,0.39 -0.39,1.02 0,1.41l0,0c0.39,0.39 1.02,0.39 1.41,0L12,13.41l1.89,1.89c0.39,0.39 1.02,0.39 1.41,0l0,0c0.39,-0.39 0.39,-1.02 0,-1.41L13.41,12l1.89,-1.89c0.39,-0.39 0.39,-1.02 0,-1.41l0,0C14.91,8.32 14.27,8.32 13.89,8.7zM12,2C6.47,2 2,6.47 2,12s4.47,10 10,10s10,-4.47 10,-10S17.53,2 12,2zM12,20c-4.41,0 -8,-3.59 -8,-8s3.59,-8 8,-8s8,3.59 8,8S16.41,20 12,20z"/>
|
||||
</vector>
|
|
@ -0,0 +1,9 @@
|
|||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="24dp"
|
||||
android:height="24dp"
|
||||
android:viewportWidth="24.0"
|
||||
android:viewportHeight="24.0">
|
||||
<path
|
||||
android:fillColor="#FF000000"
|
||||
android:pathData="M19.43,12.98c0.04,-0.32 0.07,-0.64 0.07,-0.98s-0.03,-0.66 -0.07,-0.98l2.11,-1.65c0.19,-0.15 0.24,-0.42 0.12,-0.64l-2,-3.46c-0.12,-0.22 -0.39,-0.3 -0.61,-0.22l-2.49,1c-0.52,-0.4 -1.08,-0.73 -1.69,-0.98l-0.38,-2.65C14.46,2.18 14.25,2 14,2h-4c-0.25,0 -0.46,0.18 -0.49,0.42l-0.38,2.65c-0.61,0.25 -1.17,0.59 -1.69,0.98l-2.49,-1c-0.23,-0.09 -0.49,0 -0.61,0.22l-2,3.46c-0.13,0.22 -0.07,0.49 0.12,0.64l2.11,1.65c-0.04,0.32 -0.07,0.65 -0.07,0.98s0.03,0.66 0.07,0.98l-2.11,1.65c-0.19,0.15 -0.24,0.42 -0.12,0.64l2,3.46c0.12,0.22 0.39,0.3 0.61,0.22l2.49,-1c0.52,0.4 1.08,0.73 1.69,0.98l0.38,2.65c0.03,0.24 0.24,0.42 0.49,0.42h4c0.25,0 0.46,-0.18 0.49,-0.42l0.38,-2.65c0.61,-0.25 1.17,-0.59 1.69,-0.98l2.49,1c0.23,0.09 0.49,0 0.61,-0.22l2,-3.46c0.12,-0.22 0.07,-0.49 -0.12,-0.64l-2.11,-1.65zM12,15.5c-1.93,0 -3.5,-1.57 -3.5,-3.5s1.57,-3.5 3.5,-3.5 3.5,1.57 3.5,3.5 -1.57,3.5 -3.5,3.5z"/>
|
||||
</vector>
|
|
@ -0,0 +1,16 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:shape="rectangle">
|
||||
|
||||
<!--<stroke-->
|
||||
<!--android:color="#000"-->
|
||||
<!--android:width="4dp"/>-->
|
||||
|
||||
<solid
|
||||
android:color="@color/colorWhite"/>
|
||||
|
||||
<corners
|
||||
android:radius="10dp"/>
|
||||
|
||||
</shape>
|
|
@ -1,12 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item>
|
||||
<shape
|
||||
android:innerRadius="0dp"
|
||||
android:shape="ring"
|
||||
android:thickness="2dp"
|
||||
android:useLevel="false">
|
||||
<solid android:color="@android:color/darker_gray"/>
|
||||
</shape>
|
||||
</item>
|
||||
</layer-list>
|
|
@ -1,9 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:innerRadius="0dp"
|
||||
android:shape="ring"
|
||||
android:thickness="4dp"
|
||||
android:useLevel="false" >
|
||||
|
||||
<solid android:color="@color/colorAccent"/>
|
||||
</shape>
|
|
@ -1,8 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<selector xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<item android:drawable="@drawable/tab_indicator_selected"
|
||||
android:state_selected="true"/>
|
||||
|
||||
<item android:drawable="@drawable/tab_indicator_default"/>
|
||||
</selector>
|
|
@ -0,0 +1,121 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<android.support.design.widget.CoordinatorLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:animateLayoutChanges="true"
|
||||
android:id="@+id/coordinator"
|
||||
tools:context=".MainActivity"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:focusableInTouchMode="true">
|
||||
|
||||
<android.support.design.widget.AppBarLayout
|
||||
android:id="@+id/settings.appbar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:theme="@style/AppTheme.AppBarOverlay">
|
||||
|
||||
<android.support.v7.widget.Toolbar
|
||||
android:id="@+id/toolbar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="?android:attr/actionBarSize"
|
||||
app:popupTheme="@style/AppTheme.PopupOverlay"/>
|
||||
|
||||
<android.support.design.widget.TextInputLayout
|
||||
android:background="@color/colorPrimary"
|
||||
android:id="@+id/input_layout_server_url"
|
||||
android:paddingStart="16dp"
|
||||
android:paddingLeft="16dp"
|
||||
android:paddingRight="16dp"
|
||||
android:paddingEnd="16dp"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<EditText
|
||||
android:id="@+id/edit_server_url"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:hint="@string/server_url"
|
||||
android:inputType="textUri"/>
|
||||
|
||||
</android.support.design.widget.TextInputLayout>
|
||||
|
||||
<android.support.design.widget.TextInputLayout
|
||||
android:background="@color/colorPrimary"
|
||||
android:id="@+id/input_layout_api_key"
|
||||
android:paddingStart="16dp"
|
||||
android:paddingLeft="16dp"
|
||||
android:paddingRight="16dp"
|
||||
android:paddingEnd="16dp"
|
||||
android:paddingBottom="42dp"
|
||||
app:passwordToggleEnabled="true"
|
||||
app:passwordToggleTint="#FFF"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<EditText
|
||||
android:id="@+id/edit_api_key"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:hint="@string/authkey"
|
||||
android:inputType="textPassword"/>
|
||||
|
||||
</android.support.design.widget.TextInputLayout>
|
||||
|
||||
</android.support.design.widget.AppBarLayout>
|
||||
|
||||
<android.support.constraint.ConstraintLayout
|
||||
app:layout_behavior="@string/appbar_scrolling_view_behavior"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<include
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
layout="@layout/view_organisation"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
android:layout_marginStart="16dp"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
android:layout_marginTop="32dp"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
android:layout_marginEnd="16dp"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
android:layout_marginBottom="16dp"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/empty"
|
||||
android:text="@string/empty_my_org"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"/>
|
||||
|
||||
<ProgressBar
|
||||
android:id="@+id/progressBar"
|
||||
style="?android:attr/progressBarStyle"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:visibility="gone"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"/>
|
||||
|
||||
</android.support.constraint.ConstraintLayout>
|
||||
|
||||
<android.support.design.widget.FloatingActionButton
|
||||
android:id="@+id/fab_download_own_org_info"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="16dp"
|
||||
app:fabSize="normal"
|
||||
app:layout_anchor="@id/settings.appbar"
|
||||
app:layout_anchorGravity="bottom|right|end"
|
||||
android:tint="@color/colorWhite"
|
||||
app:srcCompat="@drawable/icon_cloud_download"/>
|
||||
|
||||
</android.support.design.widget.CoordinatorLayout>
|
|
@ -1,92 +1,61 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<android.support.design.widget.CoordinatorLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
tools:context=".MainActivity"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
<android.support.design.widget.AppBarLayout
|
||||
android:id="@+id/appbar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:theme="@style/AppTheme.AppBarOverlay">
|
||||
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
<android.support.v7.widget.Toolbar
|
||||
android:id="@+id/toolbar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="?android:attr/actionBarSize"
|
||||
app:popupTheme="@style/AppTheme.PopupOverlay"/>
|
||||
|
||||
tools:context=".activity.SettingsActivity"
|
||||
android:background="@color/colorPrimary">
|
||||
</android.support.design.widget.AppBarLayout>
|
||||
|
||||
<android.support.design.widget.AppBarLayout
|
||||
android:id="@+id/settings.appbar"
|
||||
app:elevation="0dp"
|
||||
android:background="@color/colorPrimaryDark"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:theme="@style/AppTheme.AppBarOverlay">
|
||||
<android.support.constraint.ConstraintLayout
|
||||
app:layout_behavior="@string/appbar_scrolling_view_behavior"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<android.support.v7.widget.Toolbar
|
||||
android:id="@+id/toolbar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="?attr/actionBarSize"
|
||||
android:backgroundTint="@color/colorPrimary"
|
||||
android:background="@drawable/background_rounded_main"
|
||||
app:popupTheme="@style/AppTheme.PopupOverlay"/>
|
||||
<android.support.v7.widget.RecyclerView
|
||||
android:id="@+id/recyclerView"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent"/>
|
||||
|
||||
</android.support.design.widget.AppBarLayout>
|
||||
<TextView
|
||||
android:id="@+id/empty"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/empty_sync_list" app:layout_constraintEnd_toEndOf="parent"
|
||||
android:layout_marginEnd="8dp" app:layout_constraintStart_toStartOf="parent"
|
||||
android:layout_marginStart="8dp" app:layout_constraintBottom_toBottomOf="parent"
|
||||
android:layout_marginBottom="8dp" app:layout_constraintTop_toTopOf="parent"
|
||||
android:layout_marginTop="8dp"/>
|
||||
|
||||
<android.support.constraint.ConstraintLayout
|
||||
android:id="@+id/constraintLayout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="@drawable/background_rounded_main"
|
||||
app:layout_behavior="@string/appbar_scrolling_view_behavior">
|
||||
</android.support.constraint.ConstraintLayout>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/empty_view"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="16dp"
|
||||
android:layout_marginEnd="16dp"
|
||||
android:layout_marginStart="16dp"
|
||||
android:layout_marginTop="16dp"
|
||||
android:text="@string/empty_ext_org_dataset"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"/>
|
||||
<android.support.design.widget.FloatingActionButton
|
||||
android:id="@+id/fab"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
app:fabSize="normal"
|
||||
android:tint="@color/colorWhite"
|
||||
android:src="@drawable/icon_add"
|
||||
android:layout_gravity="bottom|right|end"
|
||||
android:layout_margin="16dp"/>
|
||||
|
||||
<android.support.v4.widget.SwipeRefreshLayout
|
||||
android:id="@+id/recycler_refresh"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<android.support.v7.widget.RecyclerView
|
||||
android:id="@+id/orgRecyclerView"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent"/>
|
||||
|
||||
</android.support.v4.widget.SwipeRefreshLayout>
|
||||
|
||||
|
||||
</android.support.constraint.ConstraintLayout>
|
||||
|
||||
<android.support.design.widget.FloatingActionButton
|
||||
android:id="@+id/fab_add"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="@dimen/fab_margin"
|
||||
app:fabSize="normal"
|
||||
app:layout_anchor="@+id/constraintLayout"
|
||||
app:layout_anchorGravity="right|bottom"
|
||||
app:srcCompat="@drawable/ic_add_white"/>
|
||||
|
||||
<android.support.design.widget.FloatingActionButton
|
||||
android:id="@+id/fab_sync"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="100dp"
|
||||
android:visibility="gone"
|
||||
app:fabSize="mini"
|
||||
app:layout_anchor="@+id/fab_add"
|
||||
app:layout_anchorGravity="top|center_horizontal"
|
||||
app:srcCompat="@drawable/ic_sync_white"/>
|
||||
|
||||
</android.support.design.widget.CoordinatorLayout>
|
||||
</android.support.design.widget.CoordinatorLayout>
|
||||
|
|
|
@ -0,0 +1,81 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<android.support.design.widget.CoordinatorLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="#000"
|
||||
android:fitsSystemWindows="false">
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/fragment_container"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"/>
|
||||
|
||||
<RelativeLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="#96000000">
|
||||
|
||||
<LinearLayout
|
||||
android:visibility="visible"
|
||||
android:id="@+id/qr_background"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_centerInParent="true"
|
||||
android:background="@drawable/rounded_square">
|
||||
|
||||
<ImageView
|
||||
android:contentDescription="@string/qr_code"
|
||||
android:id="@+id/qr_imageView"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"/>
|
||||
</LinearLayout>
|
||||
|
||||
<TextView
|
||||
android:visibility="visible"
|
||||
android:id="@+id/forward_description"
|
||||
android:layout_below="@id/qr_background"
|
||||
android:layout_centerHorizontal="true"
|
||||
android:padding="32dp"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:textColor="@color/colorWhite"
|
||||
android:text="@string/sync_info_let_scan"/>
|
||||
|
||||
<ImageButton
|
||||
android:contentDescription="@string/nav_exit"
|
||||
android:id="@+id/close"
|
||||
android:padding="16dp"
|
||||
|
||||
android:layout_alignParentStart="true"
|
||||
android:layout_alignParentTop="true"
|
||||
|
||||
android:tint="@color/colorWhite"
|
||||
android:src="@drawable/icon_close"
|
||||
android:background="?android:selectableItemBackgroundBorderless"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"/>
|
||||
|
||||
<Button
|
||||
android:id="@+id/forward"
|
||||
android:visibility="visible"
|
||||
|
||||
android:padding="16dp"
|
||||
android:layout_marginTop="32dp"
|
||||
|
||||
android:layout_below="@id/forward_description"
|
||||
android:layout_centerHorizontal="true"
|
||||
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
|
||||
android:text="@string/str_continue"
|
||||
android:textColor="@color/colorWhite"
|
||||
android:textAllCaps="true"
|
||||
style="@style/Widget.AppCompat.Button.Colored"/>
|
||||
|
||||
</RelativeLayout>
|
||||
|
||||
</android.support.design.widget.CoordinatorLayout>
|
|
@ -1,112 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<android.support.design.widget.CoordinatorLayout
|
||||
|
||||
android:id="@+id/coordinator"
|
||||
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
|
||||
tools:context=".activity.SettingsActivity"
|
||||
android:background="@color/colorPrimary"
|
||||
android:focusableInTouchMode="true">
|
||||
|
||||
<android.support.design.widget.AppBarLayout
|
||||
android:id="@+id/settings.appbar"
|
||||
app:elevation="0dp"
|
||||
android:background="@color/colorPrimaryDark"
|
||||
android:theme="@style/AppTheme.AppBarOverlay"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<android.support.v7.widget.Toolbar
|
||||
android:id="@+id/toolbar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="?attr/actionBarSize"
|
||||
android:backgroundTint="@color/colorPrimary"
|
||||
android:background="@drawable/background_rounded_main"
|
||||
app:popupTheme="@style/AppTheme.PopupOverlay" />
|
||||
|
||||
<android.support.design.widget.TextInputLayout
|
||||
android:background="@color/colorPrimary"
|
||||
android:id="@+id/input_layout_server_url"
|
||||
android:paddingStart="16dp"
|
||||
android:paddingLeft="16dp"
|
||||
android:paddingRight="16dp"
|
||||
android:paddingEnd="16dp"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<EditText
|
||||
android:id="@+id/edit_server_url"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:hint="@string/settings_server_url"
|
||||
android:inputType="textUri"/>
|
||||
|
||||
</android.support.design.widget.TextInputLayout>
|
||||
|
||||
<android.support.design.widget.TextInputLayout
|
||||
android:background="@color/colorPrimary"
|
||||
android:id="@+id/input_layout_api_key"
|
||||
android:paddingStart="16dp"
|
||||
android:paddingLeft="16dp"
|
||||
android:paddingRight="16dp"
|
||||
android:paddingEnd="16dp"
|
||||
android:paddingBottom="42dp"
|
||||
app:passwordToggleEnabled="true"
|
||||
app:passwordToggleTint="#FFF"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<EditText
|
||||
android:id="@+id/edit_api_key"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:hint="@string/settings_api_key"
|
||||
android:inputType="textPassword"/>
|
||||
|
||||
</android.support.design.widget.TextInputLayout>
|
||||
|
||||
</android.support.design.widget.AppBarLayout>
|
||||
|
||||
<android.support.constraint.ConstraintLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="@drawable/background_rounded_main"
|
||||
app:layout_behavior="@string/appbar_scrolling_view_behavior">
|
||||
|
||||
<ProgressBar
|
||||
android:id="@+id/progressBar"
|
||||
style="?android:attr/progressBarStyle"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:visibility="gone"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" />
|
||||
|
||||
<include layout="@layout/view_holder_organisation"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
android:layout_width="0dp" android:layout_height="0dp" android:id="@+id/include"/>
|
||||
|
||||
</android.support.constraint.ConstraintLayout>
|
||||
|
||||
<android.support.design.widget.FloatingActionButton
|
||||
android:id="@+id/fab_download_own_org_info"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_margin="@dimen/fab_margin"
|
||||
app:fabSize="normal"
|
||||
app:layout_anchor="@id/settings.appbar"
|
||||
app:layout_anchorGravity="bottom|right|end"
|
||||
app:srcCompat="@drawable/ic_cloud_download_white"/>
|
||||
|
||||
</android.support.design.widget.CoordinatorLayout>
|
|
@ -1,90 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<android.support.design.widget.CoordinatorLayout
|
||||
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
|
||||
tools:context=".activity.SyncActivity"
|
||||
android:background="@color/colorPrimary">
|
||||
|
||||
<android.support.design.widget.AppBarLayout
|
||||
app:elevation="0dp"
|
||||
android:id="@+id/sync.appbar"
|
||||
android:background="@color/colorPrimaryDark"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:theme="@style/AppTheme.AppBarOverlay">
|
||||
|
||||
<android.support.v7.widget.Toolbar
|
||||
android:id="@+id/toolbar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="?attr/actionBarSize"
|
||||
android:backgroundTint="@color/colorPrimary"
|
||||
android:background="@drawable/background_rounded_main"
|
||||
app:popupTheme="@style/AppTheme.PopupOverlay"/>
|
||||
|
||||
</android.support.design.widget.AppBarLayout>
|
||||
|
||||
<android.support.constraint.ConstraintLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="@drawable/background_rounded_main"
|
||||
android:padding="0dp"
|
||||
app:layout_behavior="@string/appbar_scrolling_view_behavior">
|
||||
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/fragmentContainer"
|
||||
|
||||
app:layout_constraintBottom_toTopOf="@+id/linearLayout"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="0dp">
|
||||
|
||||
</FrameLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/linearLayout"
|
||||
android:background="@color/colorPrimary"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="56dp"
|
||||
android:orientation="horizontal"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent">
|
||||
|
||||
<Button style="@style/Widget.AppCompat.Button.Borderless.Colored"
|
||||
android:id="@+id/backButton"
|
||||
android:text="Back"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:enabled="false"/>
|
||||
|
||||
<android.support.design.widget.TabLayout
|
||||
android:id="@+id/tabLayout"
|
||||
android:layout_weight="1"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="match_parent"
|
||||
app:tabBackground="@drawable/tab_selector"
|
||||
app:tabGravity="center"
|
||||
app:tabIndicatorHeight="0dp">
|
||||
|
||||
</android.support.design.widget.TabLayout>
|
||||
|
||||
<Button style="@style/Widget.AppCompat.Button.Borderless.Colored"
|
||||
android:id="@+id/nextButton"
|
||||
android:text="Next"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="match_parent"
|
||||
android:enabled="false"/>
|
||||
</LinearLayout>
|
||||
|
||||
</android.support.constraint.ConstraintLayout>
|
||||
|
||||
</android.support.design.widget.CoordinatorLayout>
|
|
@ -0,0 +1,48 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<android.support.design.widget.CoordinatorLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
tools:context=".MainActivity"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<android.support.design.widget.AppBarLayout
|
||||
android:id="@+id/appbar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:theme="@style/AppTheme.AppBarOverlay">
|
||||
|
||||
<android.support.v7.widget.Toolbar
|
||||
android:id="@+id/toolbar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="?android:attr/actionBarSize"
|
||||
app:popupTheme="@style/AppTheme.PopupOverlay"/>
|
||||
|
||||
</android.support.design.widget.AppBarLayout>
|
||||
|
||||
<android.support.constraint.ConstraintLayout
|
||||
app:layout_behavior="@string/appbar_scrolling_view_behavior"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent" android:id="@+id/constraintLayout">
|
||||
|
||||
<android.support.v7.widget.RecyclerView
|
||||
android:id="@+id/recyclerView"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent" app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent" app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent"/>
|
||||
</android.support.constraint.ConstraintLayout>
|
||||
|
||||
<android.support.design.widget.FloatingActionButton
|
||||
android:id="@+id/fab"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
app:fabSize="normal"
|
||||
android:tint="@color/colorWhite"
|
||||
android:src="@drawable/icon_check"
|
||||
android:layout_gravity="bottom|right|end"
|
||||
android:layout_margin="16dp"/>
|
||||
|
||||
</android.support.design.widget.CoordinatorLayout>
|
|
@ -0,0 +1,27 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<LinearLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="60dp"
|
||||
android:orientation="horizontal"
|
||||
android:background="@color/colorGreen"
|
||||
android:padding="16dp">
|
||||
|
||||
<ImageView
|
||||
android:contentDescription="@string/qr_code"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:layout_width="32dp"
|
||||
android:layout_height="32dp"
|
||||
android:tint="#FFF"
|
||||
android:src="@drawable/icon_key"/>
|
||||
|
||||
<TextView
|
||||
android:text="@string/public_key"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_marginStart="16dp"
|
||||
android:gravity="center_vertical"
|
||||
android:textColor="#FFF"
|
||||
android:textSize="20sp"/>
|
||||
</LinearLayout>
|
|
@ -0,0 +1,14 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_width="wrap_content"
|
||||
android:padding="16dp">
|
||||
|
||||
<android.support.v7.widget.AppCompatCheckBox
|
||||
android:id="@+id/checkbox"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="@string/save_authkey"/>
|
||||
|
||||
</LinearLayout>
|
|
@ -0,0 +1,29 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_width="match_parent"
|
||||
android:orientation="vertical">
|
||||
|
||||
<android.support.v7.widget.AppCompatCheckBox
|
||||
android:layout_margin="16dp"
|
||||
android:id="@+id/check_synced_partner_list"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Clear synced partner list"/>
|
||||
|
||||
<android.support.v7.widget.AppCompatCheckBox
|
||||
android:layout_margin="16dp"
|
||||
android:id="@+id/check_credentials"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Clear credentials"/>
|
||||
|
||||
<android.support.v7.widget.AppCompatCheckBox
|
||||
android:layout_margin="16dp"
|
||||
android:id="@+id/check_user_preferences"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Clear app settings"/>
|
||||
|
||||
</LinearLayout>
|
|
@ -0,0 +1,27 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<LinearLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="60dp"
|
||||
android:orientation="horizontal"
|
||||
android:background="@color/colorAccent"
|
||||
android:padding="16dp">
|
||||
|
||||
<ImageView
|
||||
android:layout_gravity="center_vertical"
|
||||
android:layout_width="32dp"
|
||||
android:layout_height="32dp"
|
||||
android:tint="#FFF"
|
||||
android:src="@drawable/icon_contact"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/title"
|
||||
android:text="Sync Information"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:layout_marginStart="16dp"
|
||||
android:gravity="center_vertical"
|
||||
android:textColor="#FFF"
|
||||
android:textSize="20sp"/>
|
||||
</LinearLayout>
|
|
@ -1,22 +1,18 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<android.support.constraint.ConstraintLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/image_view_qr"
|
||||
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="0dp"
|
||||
|
||||
android:adjustViewBounds="true"
|
||||
android:scaleType="fitCenter"
|
||||
|
||||
<de.overview.wg.its.mispauth.cam.AutoFitTextureView
|
||||
android:id="@+id/texture"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent"/>
|
||||
|
||||
</android.support.constraint.ConstraintLayout>
|
|
@ -0,0 +1,32 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<android.support.constraint.ConstraintLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<ProgressBar
|
||||
android:id="@+id/progressBar"
|
||||
android:layout_width="50dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:indeterminate="true"
|
||||
|
||||
app:layout_constraintTop_toTopOf="parent" android:layout_marginTop="8dp"
|
||||
app:layout_constraintStart_toStartOf="parent" android:layout_marginStart="8dp"
|
||||
app:layout_constraintEnd_toEndOf="parent" android:layout_marginEnd="8dp"
|
||||
app:layout_constraintBottom_toBottomOf="parent" android:layout_marginBottom="8dp"/>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/textView"
|
||||
android:text="Generating safe primes. This may take a long time..."
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
android:layout_marginEnd="8dp"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
android:layout_marginBottom="8dp" android:layout_marginTop="8dp"
|
||||
app:layout_constraintTop_toBottomOf="@+id/progressBar" app:layout_constraintStart_toStartOf="parent"
|
||||
android:layout_marginStart="8dp" app:layout_constraintVertical_bias="0.0"/>
|
||||
|
||||
</android.support.constraint.ConstraintLayout>
|
|
@ -1,12 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<android.support.constraint.ConstraintLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="REVIEW QR"/>
|
||||
|
||||
</android.support.constraint.ConstraintLayout>
|
|
@ -1,12 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<android.support.constraint.ConstraintLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<TextureView
|
||||
android:id="@+id/texture_scan_preview"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"/>
|
||||
|
||||
</android.support.constraint.ConstraintLayout>
|
|
@ -1,73 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<android.support.constraint.ConstraintLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<RadioGroup
|
||||
android:id="@+id/radioGroup"
|
||||
android:padding="16dp"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content" android:layout_marginBottom="8dp"
|
||||
android:layout_marginTop="8dp"
|
||||
app:layout_constraintTop_toTopOf="parent" app:layout_constraintStart_toStartOf="parent"
|
||||
android:layout_marginStart="8dp" android:layout_marginEnd="8dp" app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent">
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="8dp"
|
||||
android:textSize="20sp"
|
||||
android:textStyle="bold"
|
||||
android:text="How would you like to start?"/>
|
||||
|
||||
<TextView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="16dp"
|
||||
android:textSize="17sp"
|
||||
android:text="Make sure your partner will choose the opposite option."/>
|
||||
|
||||
<RadioButton
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="56dp"
|
||||
android:text="Scan QR-Code first"/>
|
||||
|
||||
<RadioButton
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="56dp"
|
||||
android:text="Share QR-Code first"/>
|
||||
</RadioGroup>
|
||||
|
||||
|
||||
<!--<ImageView-->
|
||||
<!--android:id="@+id/sync_image"-->
|
||||
<!--android:src="@drawable/ic_sync_alpha"-->
|
||||
<!--android:layout_width="match_parent"-->
|
||||
<!--android:layout_height="128dp"/>-->
|
||||
|
||||
<!--<TextView-->
|
||||
<!--android:gravity="center"-->
|
||||
<!--android:id="@+id/help_text_sync"-->
|
||||
<!--android:text="I am partner"-->
|
||||
<!--android:layout_width="match_parent"-->
|
||||
<!--android:layout_height="wrap_content"-->
|
||||
<!--app:layout_constraintTop_toBottomOf="@+id/sync_image"/>-->
|
||||
|
||||
<!--<Button style="@style/CustomButton"-->
|
||||
<!--android:id="@+id/button_scan"-->
|
||||
<!--android:text="Scan"-->
|
||||
<!--android:layout_width="match_parent"-->
|
||||
<!--android:layout_height="wrap_content" android:layout_marginBottom="8dp"-->
|
||||
<!--app:layout_constraintBottom_toTopOf="@+id/button_share"/>-->
|
||||
|
||||
<!--<Button style="@style/CustomButton"-->
|
||||
<!--android:id="@+id/button_share"-->
|
||||
<!--android:text="Share"-->
|
||||
<!--android:layout_width="match_parent"-->
|
||||
<!--android:layout_height="wrap_content" android:layout_marginBottom="8dp"-->
|
||||
<!--app:layout_constraintBottom_toBottomOf="parent"/>-->
|
||||
|
||||
</android.support.constraint.ConstraintLayout>
|
|
@ -1,17 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<android.support.constraint.ConstraintLayout
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<TextView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:text="Upload"
|
||||
app:layout_constraintEnd_toEndOf="parent" android:layout_marginEnd="8dp"
|
||||
app:layout_constraintStart_toStartOf="parent" android:layout_marginStart="8dp"
|
||||
app:layout_constraintBottom_toBottomOf="parent" android:layout_marginBottom="8dp"
|
||||
app:layout_constraintTop_toTopOf="parent" android:layout_marginTop="8dp"/>
|
||||
|
||||
</android.support.constraint.ConstraintLayout>
|
|
@ -0,0 +1,55 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<android.support.v7.widget.CardView
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="16dp"
|
||||
app:cardBackgroundColor="@color/colorWhite"
|
||||
app:cardElevation="3dp"
|
||||
app:cardCornerRadius="0dp"
|
||||
app:cardPreventCornerOverlap="true"
|
||||
app:contentPadding="16dp">
|
||||
|
||||
<RelativeLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/titleView"
|
||||
android:background="@color/colorWhite"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/title"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:textSize="18sp"
|
||||
android:textStyle="bold"
|
||||
android:text="Title"/>
|
||||
|
||||
<TextView
|
||||
android:layout_weight="1"
|
||||
android:text="28.08.2018"
|
||||
android:textColor="#FFAAAAAA"
|
||||
android:id="@+id/dateSynced"
|
||||
android:layout_gravity="center_vertical"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:textAlignment="viewEnd"/>
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<TextView
|
||||
android:layout_below="@id/titleView"
|
||||
android:text="https://vwx.yz"
|
||||
android:id="@+id/url"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"/>
|
||||
|
||||
</RelativeLayout>
|
||||
|
||||
</android.support.v7.widget.CardView>
|
|
@ -0,0 +1,79 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
<android.support.v7.widget.CardView
|
||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginBottom="16dp"
|
||||
app:cardBackgroundColor="@color/colorWhite"
|
||||
app:cardElevation="3dp"
|
||||
app:cardCornerRadius="0dp"
|
||||
app:cardPreventCornerOverlap="true"
|
||||
app:contentPadding="16dp">
|
||||
|
||||
<RelativeLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/title"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_centerVertical="true"
|
||||
android:textSize="18sp"
|
||||
android:textStyle="bold"
|
||||
android:text="Title"/>
|
||||
|
||||
<TextView
|
||||
android:visibility="gone"
|
||||
android:id="@+id/state_error_text"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="32dp"
|
||||
android:textColor="#FFCC0000"
|
||||
android:text="ERRROOOORRR"
|
||||
android:layout_below="@id/title"/>
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/state_pending"
|
||||
android:layout_centerVertical="true"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:tint="@color/colorPrimary"
|
||||
android:src="@drawable/icon_hour_glass"/>
|
||||
|
||||
<ImageView
|
||||
android:visibility="gone"
|
||||
android:id="@+id/state_in_progress"
|
||||
android:layout_centerVertical="true"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:tint="@color/colorPrimary"
|
||||
android:src="@drawable/icon_cloud_upload"/>
|
||||
|
||||
<ImageView
|
||||
android:visibility="gone"
|
||||
android:id="@+id/state_done"
|
||||
android:layout_centerVertical="true"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:tint="@color/colorPrimary"
|
||||
android:src="@drawable/icon_round_check"/>
|
||||
|
||||
<ImageView
|
||||
android:visibility="gone"
|
||||
android:id="@+id/state_error"
|
||||
android:layout_centerVertical="true"
|
||||
android:layout_alignParentEnd="true"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:tint="@color/colorPrimary"
|
||||
android:src="@drawable/icon_round_error"/>
|
||||
|
||||
</RelativeLayout>
|
||||
|
||||
</android.support.v7.widget.CardView>
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue