mirror of https://github.com/MISP/misp-bump
Renamed to MISPBump
parent
617a0a6c61
commit
cde59784b1
|
@ -2,8 +2,8 @@
|
||||||
<project version="4">
|
<project version="4">
|
||||||
<component name="ProjectModuleManager">
|
<component name="ProjectModuleManager">
|
||||||
<modules>
|
<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$/app/app.iml" filepath="$PROJECT_DIR$/app/app.iml" />
|
||||||
|
<module fileurl="file://$PROJECT_DIR$/misp-auth.iml" filepath="$PROJECT_DIR$/misp-auth.iml" />
|
||||||
</modules>
|
</modules>
|
||||||
</component>
|
</component>
|
||||||
</project>
|
</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 {
|
android {
|
||||||
compileSdkVersion 27
|
compileSdkVersion 27
|
||||||
buildToolsVersion "27.0.3"
|
buildToolsVersion "28.0.0"
|
||||||
defaultConfig {
|
defaultConfig {
|
||||||
applicationId "de.overview.wg.its.mispauth"
|
applicationId "de.overview.wg.its.mispauth"
|
||||||
minSdkVersion 21
|
minSdkVersion 23
|
||||||
targetSdkVersion 27
|
targetSdkVersion 27
|
||||||
versionCode 1
|
versionCode 1
|
||||||
versionName "1.0"
|
versionName "1.0"
|
||||||
|
@ -17,6 +17,9 @@ android {
|
||||||
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
|
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
packagingOptions {
|
||||||
|
exclude 'META-INF/DEPENDENCIES'
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
|
@ -30,6 +33,13 @@ dependencies {
|
||||||
implementation 'com.android.support:design:27.1.1'
|
implementation 'com.android.support:design:27.1.1'
|
||||||
|
|
||||||
implementation 'com.android.volley:volley:1.1.0'
|
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.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'
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,8 +12,9 @@
|
||||||
android:roundIcon="@mipmap/ic_launcher_round"
|
android:roundIcon="@mipmap/ic_launcher_round"
|
||||||
android:supportsRtl="true"
|
android:supportsRtl="true"
|
||||||
android:theme="@style/AppTheme">
|
android:theme="@style/AppTheme">
|
||||||
|
<activity
|
||||||
<activity android:name=".activity.MainActivity">
|
android:name=".MainActivity"
|
||||||
|
android:label="@string/app_name">
|
||||||
<intent-filter>
|
<intent-filter>
|
||||||
<action android:name="android.intent.action.MAIN"/>
|
<action android:name="android.intent.action.MAIN"/>
|
||||||
|
|
||||||
|
@ -22,15 +23,19 @@
|
||||||
</activity>
|
</activity>
|
||||||
|
|
||||||
<activity
|
<activity
|
||||||
android:name=".activity.SettingsActivity"
|
android:screenOrientation="portrait"
|
||||||
android:label="@string/title_activity_settings"
|
android:name=".SyncActivity"
|
||||||
android:parentActivityName=".activity.MainActivity"/>
|
android:label="Sync"
|
||||||
|
android:parentActivityName=".MainActivity"
|
||||||
|
android:theme="@style/AppTheme.Fullscreen">
|
||||||
|
</activity>
|
||||||
|
|
||||||
<activity
|
<activity
|
||||||
android:screenOrientation="portrait"
|
android:screenOrientation="portrait"
|
||||||
android:name=".activity.SyncActivity"
|
android:name=".CredentialsActivity"
|
||||||
android:label="@string/title_activity_sync"
|
android:label="@string/credentials_activity"
|
||||||
android:parentActivityName=".activity.MainActivity"/>
|
android:parentActivityName=".MainActivity"/>
|
||||||
|
<activity android:name=".UploadActivity"/>
|
||||||
</application>
|
</application>
|
||||||
|
|
||||||
</manifest>
|
</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,23 +2,64 @@ package de.overview.wg.its.mispauth.auxiliary;
|
||||||
|
|
||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.SharedPreferences;
|
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.Organisation;
|
||||||
|
import de.overview.wg.its.mispauth.model.SyncedPartner;
|
||||||
import de.overview.wg.its.mispauth.model.User;
|
import de.overview.wg.its.mispauth.model.User;
|
||||||
import org.json.JSONException;
|
import org.json.JSONException;
|
||||||
import org.json.JSONObject;
|
import org.json.JSONObject;
|
||||||
|
|
||||||
|
import java.lang.reflect.Type;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
public class PreferenceManager {
|
public class PreferenceManager {
|
||||||
|
|
||||||
private static PreferenceManager instance;
|
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_URL = "key_server_url";
|
||||||
private static String PREF_KEY_SERVER_API_KEY = "key_server_api_key";
|
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_ORGANISATION = "key_my_organisation";
|
||||||
private static String PREF_KEY_MY_USER = "key_my_user";
|
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) {
|
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();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -26,7 +67,7 @@ public class PreferenceManager {
|
||||||
*/
|
*/
|
||||||
public Organisation getMyOrganisation() {
|
public Organisation getMyOrganisation() {
|
||||||
try {
|
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();
|
Organisation org = new Organisation();
|
||||||
org.fromJSON(jsonObject);
|
org.fromJSON(jsonObject);
|
||||||
return org;
|
return org;
|
||||||
|
@ -37,14 +78,14 @@ public class PreferenceManager {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
public void setMyOrganisation(Organisation org) {
|
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.putString(PREF_KEY_MY_ORGANISATION, org.toJSON().toString());
|
||||||
editor.apply();
|
editor.apply();
|
||||||
}
|
}
|
||||||
|
|
||||||
public User getMyUser() {
|
public User getMyUser() {
|
||||||
try {
|
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 user = new User();
|
||||||
user.fromJSON(jsonObject);
|
user.fromJSON(jsonObject);
|
||||||
return user;
|
return user;
|
||||||
|
@ -55,34 +96,40 @@ public class PreferenceManager {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
public void setMyUser(User user) {
|
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.putString(PREF_KEY_MY_USER, user.toJSON().toString());
|
||||||
editor.apply();
|
editor.apply();
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getMyServerUrl() {
|
public String getMyServerUrl() {
|
||||||
return sharedPreferences.getString(PREF_KEY_SERVER_URL, "");
|
return credentialPreferences.getString(PREF_KEY_SERVER_URL, "");
|
||||||
}
|
}
|
||||||
public void setMyServerUrl(String serverUrl) {
|
public void setMyServerUrl(String serverUrl) {
|
||||||
SharedPreferences.Editor editor = sharedPreferences.edit();
|
SharedPreferences.Editor editor = credentialPreferences.edit();
|
||||||
editor.putString(PREF_KEY_SERVER_URL, serverUrl);
|
editor.putString(PREF_KEY_SERVER_URL, serverUrl);
|
||||||
editor.apply();
|
editor.apply();
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getMyServerApiKey() {
|
public String getMyServerApiKey() {
|
||||||
return sharedPreferences.getString(PREF_KEY_SERVER_API_KEY, "");
|
return credentialPreferences.getString(PREF_KEY_SERVER_API_KEY, "");
|
||||||
}
|
}
|
||||||
public void setMyServerApiKey(String apiKey) {
|
public void setMyServerApiKey(String apiKey) {
|
||||||
SharedPreferences.Editor editor = sharedPreferences.edit();
|
SharedPreferences.Editor editor = credentialPreferences.edit();
|
||||||
editor.putString(PREF_KEY_SERVER_API_KEY, apiKey);
|
editor.putString(PREF_KEY_SERVER_API_KEY, apiKey);
|
||||||
editor.apply();
|
editor.apply();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void deleteAllLocalData() {
|
|
||||||
SharedPreferences.Editor editor = sharedPreferences.edit();
|
public void clearUserPreferences() {
|
||||||
editor.clear();
|
userPreferences.edit().clear().apply();
|
||||||
editor.apply();
|
|
||||||
}
|
}
|
||||||
|
public void clearCredentialPreferences() {
|
||||||
|
credentialPreferences.edit().clear().apply();
|
||||||
|
}
|
||||||
|
public void clearSyncedInformationPreferences() {
|
||||||
|
syncedInstancesPreferences.edit().clear().apply();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public static PreferenceManager Instance(Context context) {
|
public static PreferenceManager Instance(Context context) {
|
||||||
if(instance == null) {
|
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 class Organisation {
|
||||||
|
|
||||||
|
public static final String ROOT_KEY = "Organisation";
|
||||||
|
|
||||||
private static String ID_KEY = "id";
|
private static String ID_KEY = "id";
|
||||||
private static String NAME_KEY = "name";
|
private static String NAME_KEY = "name";
|
||||||
private static String DATE_CREATED_KEY = "date_created";
|
private static String DATE_CREATED_KEY = "date_created";
|
||||||
|
@ -34,48 +36,57 @@ public class Organisation {
|
||||||
private int createdBy;
|
private int createdBy;
|
||||||
private int userCount;
|
private int userCount;
|
||||||
|
|
||||||
public Organisation() {}
|
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(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() {
|
public JSONObject toJSON() {
|
||||||
|
return toJSON(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public JSONObject toJSON(boolean minimal) {
|
||||||
JSONObject org = new JSONObject();
|
JSONObject org = new JSONObject();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
org.put(ID_KEY, id);
|
org.putOpt(NAME_KEY, name);
|
||||||
org.put(NAME_KEY, name);
|
org.putOpt(DESCRIPTION_KEY, description);
|
||||||
org.put(DATE_CREATED_KEY, dateCreated);
|
org.putOpt(NATIONALITY_KEY, nationality);
|
||||||
org.put(DATE_MODIFIED_KEY, dateModified);
|
org.putOpt(SECTOR_KEY, sector);
|
||||||
org.put(TYPE_KEY, type);
|
org.putOpt(USER_COUNT_KEY, userCount);
|
||||||
org.put(NATIONALITY_KEY, nationality);
|
|
||||||
org.put(SECTOR_KEY, sector);
|
if (!minimal) {
|
||||||
org.put(CONTACTS_KEY, contacts);
|
org.putOpt(ID_KEY, id);
|
||||||
org.put(DESCRIPTION_KEY, description);
|
org.putOpt(UUID_KEY, uuid);
|
||||||
org.put(LOCAL_KEY, local);
|
org.putOpt(TYPE_KEY, type);
|
||||||
org.put(UUID_KEY, uuid);
|
org.putOpt(CONTACTS_KEY, contacts);
|
||||||
org.put(RESTRICTED_TO_DOMAIN_KEY, restrictedToDomain);
|
org.putOpt(DATE_CREATED_KEY, dateCreated);
|
||||||
org.put(CREATED_BY_KEY, createdBy);
|
org.putOpt(DATE_MODIFIED_KEY, dateModified);
|
||||||
org.put(USER_COUNT_KEY, userCount);
|
org.putOpt(LOCAL_KEY, local);
|
||||||
|
org.putOpt(RESTRICTED_TO_DOMAIN_KEY, restrictedToDomain);
|
||||||
|
org.putOpt(CREATED_BY_KEY, createdBy);
|
||||||
|
}
|
||||||
|
|
||||||
} catch (JSONException e) {
|
} catch (JSONException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
|
@ -88,13 +99,15 @@ public class Organisation {
|
||||||
public void setName(String name) {
|
public void setName(String name) {
|
||||||
this.name = name;
|
this.name = name;
|
||||||
}
|
}
|
||||||
public String getName(){
|
|
||||||
|
public String getName() {
|
||||||
return name;
|
return name;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getDescription() {
|
public String getDescription() {
|
||||||
return description;
|
return description;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setDescription(String description) {
|
public void setDescription(String description) {
|
||||||
this.description = description;
|
this.description = description;
|
||||||
}
|
}
|
||||||
|
@ -102,6 +115,7 @@ public class Organisation {
|
||||||
public String getSector() {
|
public String getSector() {
|
||||||
return sector;
|
return sector;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setSector(String sector) {
|
public void setSector(String sector) {
|
||||||
this.sector = sector;
|
this.sector = sector;
|
||||||
}
|
}
|
||||||
|
@ -109,6 +123,7 @@ public class Organisation {
|
||||||
public String getNationality() {
|
public String getNationality() {
|
||||||
return nationality;
|
return nationality;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setNationality(String nationality) {
|
public void setNationality(String nationality) {
|
||||||
this.nationality = nationality;
|
this.nationality = nationality;
|
||||||
}
|
}
|
||||||
|
@ -116,6 +131,7 @@ public class Organisation {
|
||||||
public int getId() {
|
public int getId() {
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setId(int id) {
|
public void setId(int id) {
|
||||||
this.id = id;
|
this.id = id;
|
||||||
}
|
}
|
||||||
|
@ -123,6 +139,7 @@ public class Organisation {
|
||||||
public String getDateCreated() {
|
public String getDateCreated() {
|
||||||
return dateCreated;
|
return dateCreated;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setDateCreated(String dateCreated) {
|
public void setDateCreated(String dateCreated) {
|
||||||
this.dateCreated = dateCreated;
|
this.dateCreated = dateCreated;
|
||||||
}
|
}
|
||||||
|
@ -130,6 +147,7 @@ public class Organisation {
|
||||||
public String getDateModified() {
|
public String getDateModified() {
|
||||||
return dateModified;
|
return dateModified;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setDateModified(String dateModified) {
|
public void setDateModified(String dateModified) {
|
||||||
this.dateModified = dateModified;
|
this.dateModified = dateModified;
|
||||||
}
|
}
|
||||||
|
@ -137,6 +155,7 @@ public class Organisation {
|
||||||
public String getType() {
|
public String getType() {
|
||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setType(String type) {
|
public void setType(String type) {
|
||||||
this.type = type;
|
this.type = type;
|
||||||
}
|
}
|
||||||
|
@ -144,6 +163,7 @@ public class Organisation {
|
||||||
public String getContacts() {
|
public String getContacts() {
|
||||||
return contacts;
|
return contacts;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setContacts(String contacts) {
|
public void setContacts(String contacts) {
|
||||||
this.contacts = contacts;
|
this.contacts = contacts;
|
||||||
}
|
}
|
||||||
|
@ -151,6 +171,7 @@ public class Organisation {
|
||||||
public boolean isLocal() {
|
public boolean isLocal() {
|
||||||
return local;
|
return local;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setLocal(boolean local) {
|
public void setLocal(boolean local) {
|
||||||
this.local = local;
|
this.local = local;
|
||||||
}
|
}
|
||||||
|
@ -158,6 +179,7 @@ public class Organisation {
|
||||||
public String getUuid() {
|
public String getUuid() {
|
||||||
return uuid;
|
return uuid;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setUuid(String uuid) {
|
public void setUuid(String uuid) {
|
||||||
this.uuid = uuid;
|
this.uuid = uuid;
|
||||||
}
|
}
|
||||||
|
@ -165,6 +187,7 @@ public class Organisation {
|
||||||
public String getRestrictedToDomain() {
|
public String getRestrictedToDomain() {
|
||||||
return restrictedToDomain;
|
return restrictedToDomain;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setRestrictedToDomain(String restrictedToDomain) {
|
public void setRestrictedToDomain(String restrictedToDomain) {
|
||||||
this.restrictedToDomain = restrictedToDomain;
|
this.restrictedToDomain = restrictedToDomain;
|
||||||
}
|
}
|
||||||
|
@ -172,6 +195,7 @@ public class Organisation {
|
||||||
public int getCreatedBy() {
|
public int getCreatedBy() {
|
||||||
return createdBy;
|
return createdBy;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setCreatedBy(int createdBy) {
|
public void setCreatedBy(int createdBy) {
|
||||||
this.createdBy = createdBy;
|
this.createdBy = createdBy;
|
||||||
}
|
}
|
||||||
|
@ -179,6 +203,7 @@ public class Organisation {
|
||||||
public int getUserCount() {
|
public int getUserCount() {
|
||||||
return userCount;
|
return userCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setUserCount(int userCount) {
|
public void setUserCount(int userCount) {
|
||||||
this.userCount = 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;
|
package de.overview.wg.its.mispauth.model;
|
||||||
|
|
||||||
|
import org.json.JSONException;
|
||||||
|
import org.json.JSONObject;
|
||||||
|
|
||||||
public class Server {
|
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 {
|
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 ID_KEY = "id";
|
||||||
private static String PASSWORD_KEY = "password";
|
private static String PASSWORD_KEY = "password";
|
||||||
private static String ORG_ID_KEY = "org_id";
|
private static String ORG_ID_KEY = "org_id";
|
||||||
|
@ -51,67 +63,73 @@ public class User {
|
||||||
private String dateCreated;
|
private String dateCreated;
|
||||||
private String dateModified;
|
private String dateModified;
|
||||||
|
|
||||||
public User() {}
|
public User() {
|
||||||
|
}
|
||||||
public void fromJSON(JSONObject user) {
|
public User(JSONObject user) throws JSONException {
|
||||||
try {
|
fromJSON(user);
|
||||||
|
|
||||||
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 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() {
|
public JSONObject toJSON() {
|
||||||
|
return toJSON(false);
|
||||||
|
}
|
||||||
|
public JSONObject toJSON(boolean forSyncQR) {
|
||||||
JSONObject user = new JSONObject();
|
JSONObject user = new JSONObject();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
|
||||||
user.put(ID_KEY, id);
|
user.putOpt(EMAIL_KEY, email);
|
||||||
user.put(PASSWORD_KEY, password);
|
|
||||||
user.put(ORG_ID_KEY, orgId);
|
if (!forSyncQR) {
|
||||||
user.put(EMAIL_KEY, email);
|
|
||||||
user.put(AUTOALERT_KEY, autoAlert);
|
user.putOpt(ID_KEY, id);
|
||||||
user.put(AUTHKEY_KEY, authkey);
|
user.putOpt(ORG_ID_KEY, orgId);
|
||||||
user.put(INVITED_BY_KEY, invitedBy);
|
user.putOpt(AUTHKEY_KEY, authkey);
|
||||||
user.put(GPGKEY_KEY, gpgKey);
|
user.putOpt(ROLE_ID_KEY, roleId);
|
||||||
user.put(CERTIF_PUBLIC, certifPublic);
|
user.putOpt(PASSWORD_KEY, password);
|
||||||
user.put(NIDS_SID, nidsSid);
|
user.putOpt(CHANGE_PW_KEY, changePw);
|
||||||
user.put(TERMS_ACCEPTED_KEY, termsAccepted);
|
user.putOpt(TERMS_ACCEPTED_KEY, termsAccepted);
|
||||||
user.put(NEWSREAD_KEY, newsRead);
|
user.putOpt(CERTIF_PUBLIC, certifPublic);
|
||||||
user.put(ROLE_ID_KEY, roleId);
|
user.putOpt(GPGKEY_KEY, gpgKey);
|
||||||
user.put(CHANGE_PW_KEY, changePw);
|
user.putOpt(AUTOALERT_KEY, autoAlert);
|
||||||
user.put(CONTACT_ALERT_KEY, contactAlert);
|
user.putOpt(INVITED_BY_KEY, invitedBy);
|
||||||
user.put(DISABLED_KEY, disabled);
|
user.putOpt(NIDS_SID, nidsSid);
|
||||||
user.put(EXPIRATION_KEY, expiration);
|
user.putOpt(NEWSREAD_KEY, newsRead);
|
||||||
user.put(CURRENT_LOGIN_KEY, currentLogin);
|
user.putOpt(CONTACT_ALERT_KEY, contactAlert);
|
||||||
user.put(LAST_LOGIN_KEY, lastLogin);
|
user.putOpt(DISABLED_KEY, disabled);
|
||||||
user.put(FORCE_LOGOUT_KEY, forceLogout);
|
user.putOpt(EXPIRATION_KEY, expiration);
|
||||||
user.put(DATE_CREATED_KEY, dateCreated);
|
user.putOpt(CURRENT_LOGIN_KEY, currentLogin);
|
||||||
user.put(DATE_MODIFIED_KEY, dateModified);
|
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) {
|
} catch (JSONException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
|
@ -120,10 +138,10 @@ public class User {
|
||||||
return user;
|
return user;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public int getId() {
|
public int getId() {
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setId(int id) {
|
public void setId(int id) {
|
||||||
this.id = id;
|
this.id = id;
|
||||||
}
|
}
|
||||||
|
@ -131,7 +149,6 @@ public class User {
|
||||||
public String getPassword() {
|
public String getPassword() {
|
||||||
return password;
|
return password;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setPassword(String password) {
|
public void setPassword(String password) {
|
||||||
this.password = password;
|
this.password = password;
|
||||||
}
|
}
|
||||||
|
@ -139,7 +156,6 @@ public class User {
|
||||||
public int getOrgId() {
|
public int getOrgId() {
|
||||||
return orgId;
|
return orgId;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setOrgId(int orgId) {
|
public void setOrgId(int orgId) {
|
||||||
this.orgId = orgId;
|
this.orgId = orgId;
|
||||||
}
|
}
|
||||||
|
@ -147,7 +163,6 @@ public class User {
|
||||||
public String getEmail() {
|
public String getEmail() {
|
||||||
return email;
|
return email;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setEmail(String email) {
|
public void setEmail(String email) {
|
||||||
this.email = email;
|
this.email = email;
|
||||||
}
|
}
|
||||||
|
@ -155,7 +170,6 @@ public class User {
|
||||||
public boolean isAutoAlert() {
|
public boolean isAutoAlert() {
|
||||||
return autoAlert;
|
return autoAlert;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setAutoAlert(boolean autoAlert) {
|
public void setAutoAlert(boolean autoAlert) {
|
||||||
this.autoAlert = autoAlert;
|
this.autoAlert = autoAlert;
|
||||||
}
|
}
|
||||||
|
@ -163,7 +177,6 @@ public class User {
|
||||||
public String getAuthkey() {
|
public String getAuthkey() {
|
||||||
return authkey;
|
return authkey;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setAuthkey(String authkey) {
|
public void setAuthkey(String authkey) {
|
||||||
this.authkey = authkey;
|
this.authkey = authkey;
|
||||||
}
|
}
|
||||||
|
@ -171,7 +184,6 @@ public class User {
|
||||||
public int getInvitedBy() {
|
public int getInvitedBy() {
|
||||||
return invitedBy;
|
return invitedBy;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setInvitedBy(int invitedBy) {
|
public void setInvitedBy(int invitedBy) {
|
||||||
this.invitedBy = invitedBy;
|
this.invitedBy = invitedBy;
|
||||||
}
|
}
|
||||||
|
@ -179,7 +191,6 @@ public class User {
|
||||||
public String getGpgKey() {
|
public String getGpgKey() {
|
||||||
return gpgKey;
|
return gpgKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setGpgKey(String gpgKey) {
|
public void setGpgKey(String gpgKey) {
|
||||||
this.gpgKey = gpgKey;
|
this.gpgKey = gpgKey;
|
||||||
}
|
}
|
||||||
|
@ -187,7 +198,6 @@ public class User {
|
||||||
public String getCertifPublic() {
|
public String getCertifPublic() {
|
||||||
return certifPublic;
|
return certifPublic;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setCertifPublic(String certifPublic) {
|
public void setCertifPublic(String certifPublic) {
|
||||||
this.certifPublic = certifPublic;
|
this.certifPublic = certifPublic;
|
||||||
}
|
}
|
||||||
|
@ -195,7 +205,6 @@ public class User {
|
||||||
public int getNidsSid() {
|
public int getNidsSid() {
|
||||||
return nidsSid;
|
return nidsSid;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setNidsSid(int nidsSid) {
|
public void setNidsSid(int nidsSid) {
|
||||||
this.nidsSid = nidsSid;
|
this.nidsSid = nidsSid;
|
||||||
}
|
}
|
||||||
|
@ -203,7 +212,6 @@ public class User {
|
||||||
public boolean isTermsAccepted() {
|
public boolean isTermsAccepted() {
|
||||||
return termsAccepted;
|
return termsAccepted;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setTermsAccepted(boolean termsAccepted) {
|
public void setTermsAccepted(boolean termsAccepted) {
|
||||||
this.termsAccepted = termsAccepted;
|
this.termsAccepted = termsAccepted;
|
||||||
}
|
}
|
||||||
|
@ -211,7 +219,6 @@ public class User {
|
||||||
public int getNewsRead() {
|
public int getNewsRead() {
|
||||||
return newsRead;
|
return newsRead;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setNewsRead(int newsRead) {
|
public void setNewsRead(int newsRead) {
|
||||||
this.newsRead = newsRead;
|
this.newsRead = newsRead;
|
||||||
}
|
}
|
||||||
|
@ -219,7 +226,6 @@ public class User {
|
||||||
public int getRoleId() {
|
public int getRoleId() {
|
||||||
return roleId;
|
return roleId;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setRoleId(int roleId) {
|
public void setRoleId(int roleId) {
|
||||||
this.roleId = roleId;
|
this.roleId = roleId;
|
||||||
}
|
}
|
||||||
|
@ -227,7 +233,6 @@ public class User {
|
||||||
public String getChangePw() {
|
public String getChangePw() {
|
||||||
return changePw;
|
return changePw;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setChangePw(String changePw) {
|
public void setChangePw(String changePw) {
|
||||||
this.changePw = changePw;
|
this.changePw = changePw;
|
||||||
}
|
}
|
||||||
|
@ -235,7 +240,6 @@ public class User {
|
||||||
public boolean isContactAlert() {
|
public boolean isContactAlert() {
|
||||||
return contactAlert;
|
return contactAlert;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setContactAlert(boolean contactAlert) {
|
public void setContactAlert(boolean contactAlert) {
|
||||||
this.contactAlert = contactAlert;
|
this.contactAlert = contactAlert;
|
||||||
}
|
}
|
||||||
|
@ -243,7 +247,6 @@ public class User {
|
||||||
public boolean isDisabled() {
|
public boolean isDisabled() {
|
||||||
return disabled;
|
return disabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setDisabled(boolean disabled) {
|
public void setDisabled(boolean disabled) {
|
||||||
this.disabled = disabled;
|
this.disabled = disabled;
|
||||||
}
|
}
|
||||||
|
@ -251,7 +254,6 @@ public class User {
|
||||||
public String getExpiration() {
|
public String getExpiration() {
|
||||||
return expiration;
|
return expiration;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setExpiration(String expiration) {
|
public void setExpiration(String expiration) {
|
||||||
this.expiration = expiration;
|
this.expiration = expiration;
|
||||||
}
|
}
|
||||||
|
@ -259,7 +261,6 @@ public class User {
|
||||||
public String getCurrentLogin() {
|
public String getCurrentLogin() {
|
||||||
return currentLogin;
|
return currentLogin;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setCurrentLogin(String currentLogin) {
|
public void setCurrentLogin(String currentLogin) {
|
||||||
this.currentLogin = currentLogin;
|
this.currentLogin = currentLogin;
|
||||||
}
|
}
|
||||||
|
@ -267,7 +268,6 @@ public class User {
|
||||||
public String getLastLogin() {
|
public String getLastLogin() {
|
||||||
return lastLogin;
|
return lastLogin;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setLastLogin(String lastLogin) {
|
public void setLastLogin(String lastLogin) {
|
||||||
this.lastLogin = lastLogin;
|
this.lastLogin = lastLogin;
|
||||||
}
|
}
|
||||||
|
@ -275,7 +275,6 @@ public class User {
|
||||||
public boolean isForceLogout() {
|
public boolean isForceLogout() {
|
||||||
return forceLogout;
|
return forceLogout;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setForceLogout(boolean forceLogout) {
|
public void setForceLogout(boolean forceLogout) {
|
||||||
this.forceLogout = forceLogout;
|
this.forceLogout = forceLogout;
|
||||||
}
|
}
|
||||||
|
@ -283,7 +282,6 @@ public class User {
|
||||||
public String getDateCreated() {
|
public String getDateCreated() {
|
||||||
return dateCreated;
|
return dateCreated;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setDateCreated(String dateCreated) {
|
public void setDateCreated(String dateCreated) {
|
||||||
this.dateCreated = dateCreated;
|
this.dateCreated = dateCreated;
|
||||||
}
|
}
|
||||||
|
@ -291,7 +289,6 @@ public class User {
|
||||||
public String getDateModified() {
|
public String getDateModified() {
|
||||||
return dateModified;
|
return dateModified;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setDateModified(String dateModified) {
|
public void setDateModified(String dateModified) {
|
||||||
this.dateModified = dateModified;
|
this.dateModified = dateModified;
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,16 +7,31 @@ import com.android.volley.Request;
|
||||||
import com.android.volley.RequestQueue;
|
import com.android.volley.RequestQueue;
|
||||||
import com.android.volley.Response;
|
import com.android.volley.Response;
|
||||||
import com.android.volley.VolleyError;
|
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.JsonObjectRequest;
|
||||||
import com.android.volley.toolbox.Volley;
|
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.PreferenceManager;
|
||||||
import de.overview.wg.its.mispauth.auxiliary.ReadableError;
|
import de.overview.wg.its.mispauth.auxiliary.ReadableError;
|
||||||
import de.overview.wg.its.mispauth.model.Organisation;
|
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.JSONArray;
|
||||||
import org.json.JSONException;
|
import org.json.JSONException;
|
||||||
import org.json.JSONObject;
|
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.HashMap;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
|
@ -38,6 +53,7 @@ public class MispRequest {
|
||||||
private MispRequest(Context context) {
|
private MispRequest(Context context) {
|
||||||
requestQueue = Volley.newRequestQueue(context);
|
requestQueue = Volley.newRequestQueue(context);
|
||||||
preferenceManager = PreferenceManager.Instance(context);
|
preferenceManager = PreferenceManager.Instance(context);
|
||||||
|
|
||||||
loadSavedCredentials();
|
loadSavedCredentials();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -56,13 +72,10 @@ public class MispRequest {
|
||||||
@Override
|
@Override
|
||||||
public void onResponse(JSONObject response) {
|
public void onResponse(JSONObject response) {
|
||||||
try {
|
try {
|
||||||
callback.onResult(response.getJSONObject("Organisation"));
|
callback.onResult(response.getJSONObject(Organisation.ROOT_KEY));
|
||||||
return;
|
|
||||||
} catch (JSONException e) {
|
} catch (JSONException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
|
|
||||||
callback.onResult(response);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -88,14 +101,14 @@ public class MispRequest {
|
||||||
*
|
*
|
||||||
* @param callback return user associated with this API-Key
|
* @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>() {
|
Response.Listener<JSONObject> listener = new Response.Listener<JSONObject>() {
|
||||||
@Override
|
@Override
|
||||||
public void onResponse(JSONObject response) {
|
public void onResponse(JSONObject response) {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
callback.onResult(response.getJSONObject("User"));
|
callback.onResult(response.getJSONObject(User.ROOT_KEY));
|
||||||
return;
|
return;
|
||||||
} catch (JSONException e) {
|
} catch (JSONException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
|
@ -114,7 +127,7 @@ public class MispRequest {
|
||||||
};
|
};
|
||||||
|
|
||||||
if (serverUrl.isEmpty() || apiKey.isEmpty()) {
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -137,13 +150,10 @@ public class MispRequest {
|
||||||
@Override
|
@Override
|
||||||
public void onResponse(JSONObject response) {
|
public void onResponse(JSONObject response) {
|
||||||
try {
|
try {
|
||||||
callback.onResult(response.getJSONObject("Organisation"));
|
callback.onResult(response.getJSONObject(Organisation.ROOT_KEY));
|
||||||
return;
|
|
||||||
} catch (JSONException e) {
|
} catch (JSONException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
|
|
||||||
callback.onResult(response);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -204,6 +214,73 @@ public class MispRequest {
|
||||||
requestQueue.add(r);
|
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,
|
private JsonArrayRequestWithJsonObject arrayRequestWithJsonObject(int method, String url,
|
||||||
@Nullable JSONObject body,
|
@Nullable JSONObject body,
|
||||||
Response.Listener<JSONArray> listener,
|
Response.Listener<JSONArray> listener,
|
||||||
|
@ -247,6 +324,72 @@ public class MispRequest {
|
||||||
this.apiKey = apiKey;
|
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) {
|
public static MispRequest Instance(Context context) {
|
||||||
if (instance == null) {
|
if (instance == null) {
|
||||||
instance = new MispRequest(context);
|
instance = new MispRequest(context);
|
||||||
|
@ -264,12 +407,12 @@ public class MispRequest {
|
||||||
void onError(VolleyError volleyError);
|
void onError(VolleyError volleyError);
|
||||||
}
|
}
|
||||||
public interface UserCallback {
|
public interface UserCallback {
|
||||||
void onResult(JSONObject myOrganisationInformation);
|
void onResult(JSONObject userInformation);
|
||||||
|
|
||||||
void onError(VolleyError volleyError);
|
void onError(VolleyError volleyError);
|
||||||
}
|
}
|
||||||
public interface ServerCallback {
|
public interface ServerCallback {
|
||||||
void onResult(JSONObject servers);
|
void onResult(JSONObject server);
|
||||||
void onError(VolleyError volleyError);
|
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"/>
|
|
|
@ -18,10 +18,10 @@
|
||||||
android:type="linear">
|
android:type="linear">
|
||||||
<item
|
<item
|
||||||
android:color="#44000000"
|
android:color="#44000000"
|
||||||
android:offset="0.0" />
|
android:offset="0.0"/>
|
||||||
<item
|
<item
|
||||||
android:color="#00000000"
|
android:color="#00000000"
|
||||||
android:offset="1.0" />
|
android:offset="1.0"/>
|
||||||
</gradient>
|
</gradient>
|
||||||
</aapt:attr>
|
</aapt:attr>
|
||||||
</path>
|
</path>
|
||||||
|
@ -30,5 +30,5 @@
|
||||||
android:fillType="nonZero"
|
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: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:strokeColor="#00000000"
|
||||||
android:strokeWidth="1" />
|
android:strokeWidth="1"/>
|
||||||
</vector>
|
</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"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
<vector
|
||||||
android:width="108dp"
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
android:height="108dp"
|
android:height="108dp"
|
||||||
|
android:width="108dp"
|
||||||
android:viewportHeight="108"
|
android:viewportHeight="108"
|
||||||
android:viewportWidth="108">
|
android:viewportWidth="108">
|
||||||
<path
|
<path android:fillColor="#26A69A"
|
||||||
android:fillColor="#26A69A"
|
android:pathData="M0,0h108v108h-108z"/>
|
||||||
android:pathData="M0,0h108v108h-108z" />
|
<path android:fillColor="#00000000" android:pathData="M9,0L9,108"
|
||||||
<path
|
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||||
android:fillColor="#00000000"
|
<path android:fillColor="#00000000" android:pathData="M19,0L19,108"
|
||||||
android:pathData="M9,0L9,108"
|
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||||
android:strokeColor="#33FFFFFF"
|
<path android:fillColor="#00000000" android:pathData="M29,0L29,108"
|
||||||
android:strokeWidth="0.8" />
|
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||||
<path
|
<path android:fillColor="#00000000" android:pathData="M39,0L39,108"
|
||||||
android:fillColor="#00000000"
|
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||||
android:pathData="M19,0L19,108"
|
<path android:fillColor="#00000000" android:pathData="M49,0L49,108"
|
||||||
android:strokeColor="#33FFFFFF"
|
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||||
android:strokeWidth="0.8" />
|
<path android:fillColor="#00000000" android:pathData="M59,0L59,108"
|
||||||
<path
|
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||||
android:fillColor="#00000000"
|
<path android:fillColor="#00000000" android:pathData="M69,0L69,108"
|
||||||
android:pathData="M29,0L29,108"
|
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||||
android:strokeColor="#33FFFFFF"
|
<path android:fillColor="#00000000" android:pathData="M79,0L79,108"
|
||||||
android:strokeWidth="0.8" />
|
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||||
<path
|
<path android:fillColor="#00000000" android:pathData="M89,0L89,108"
|
||||||
android:fillColor="#00000000"
|
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||||
android:pathData="M39,0L39,108"
|
<path android:fillColor="#00000000" android:pathData="M99,0L99,108"
|
||||||
android:strokeColor="#33FFFFFF"
|
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||||
android:strokeWidth="0.8" />
|
<path android:fillColor="#00000000" android:pathData="M0,9L108,9"
|
||||||
<path
|
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||||
android:fillColor="#00000000"
|
<path android:fillColor="#00000000" android:pathData="M0,19L108,19"
|
||||||
android:pathData="M49,0L49,108"
|
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||||
android:strokeColor="#33FFFFFF"
|
<path android:fillColor="#00000000" android:pathData="M0,29L108,29"
|
||||||
android:strokeWidth="0.8" />
|
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||||
<path
|
<path android:fillColor="#00000000" android:pathData="M0,39L108,39"
|
||||||
android:fillColor="#00000000"
|
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||||
android:pathData="M59,0L59,108"
|
<path android:fillColor="#00000000" android:pathData="M0,49L108,49"
|
||||||
android:strokeColor="#33FFFFFF"
|
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||||
android:strokeWidth="0.8" />
|
<path android:fillColor="#00000000" android:pathData="M0,59L108,59"
|
||||||
<path
|
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||||
android:fillColor="#00000000"
|
<path android:fillColor="#00000000" android:pathData="M0,69L108,69"
|
||||||
android:pathData="M69,0L69,108"
|
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||||
android:strokeColor="#33FFFFFF"
|
<path android:fillColor="#00000000" android:pathData="M0,79L108,79"
|
||||||
android:strokeWidth="0.8" />
|
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||||
<path
|
<path android:fillColor="#00000000" android:pathData="M0,89L108,89"
|
||||||
android:fillColor="#00000000"
|
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||||
android:pathData="M79,0L79,108"
|
<path android:fillColor="#00000000" android:pathData="M0,99L108,99"
|
||||||
android:strokeColor="#33FFFFFF"
|
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||||
android:strokeWidth="0.8" />
|
<path android:fillColor="#00000000" android:pathData="M19,29L89,29"
|
||||||
<path
|
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||||
android:fillColor="#00000000"
|
<path android:fillColor="#00000000" android:pathData="M19,39L89,39"
|
||||||
android:pathData="M89,0L89,108"
|
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||||
android:strokeColor="#33FFFFFF"
|
<path android:fillColor="#00000000" android:pathData="M19,49L89,49"
|
||||||
android:strokeWidth="0.8" />
|
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||||
<path
|
<path android:fillColor="#00000000" android:pathData="M19,59L89,59"
|
||||||
android:fillColor="#00000000"
|
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||||
android:pathData="M99,0L99,108"
|
<path android:fillColor="#00000000" android:pathData="M19,69L89,69"
|
||||||
android:strokeColor="#33FFFFFF"
|
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||||
android:strokeWidth="0.8" />
|
<path android:fillColor="#00000000" android:pathData="M19,79L89,79"
|
||||||
<path
|
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||||
android:fillColor="#00000000"
|
<path android:fillColor="#00000000" android:pathData="M29,19L29,89"
|
||||||
android:pathData="M0,9L108,9"
|
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||||
android:strokeColor="#33FFFFFF"
|
<path android:fillColor="#00000000" android:pathData="M39,19L39,89"
|
||||||
android:strokeWidth="0.8" />
|
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||||
<path
|
<path android:fillColor="#00000000" android:pathData="M49,19L49,89"
|
||||||
android:fillColor="#00000000"
|
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||||
android:pathData="M0,19L108,19"
|
<path android:fillColor="#00000000" android:pathData="M59,19L59,89"
|
||||||
android:strokeColor="#33FFFFFF"
|
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||||
android:strokeWidth="0.8" />
|
<path android:fillColor="#00000000" android:pathData="M69,19L69,89"
|
||||||
<path
|
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||||
android:fillColor="#00000000"
|
<path android:fillColor="#00000000" android:pathData="M79,19L79,89"
|
||||||
android:pathData="M0,29L108,29"
|
android:strokeColor="#33FFFFFF" android:strokeWidth="0.8"/>
|
||||||
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>
|
</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,19 +1,15 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
|
||||||
<android.support.design.widget.CoordinatorLayout
|
<android.support.design.widget.CoordinatorLayout
|
||||||
|
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
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"
|
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_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent">
|
||||||
|
|
||||||
tools:context=".activity.SettingsActivity"
|
|
||||||
android:background="@color/colorPrimary">
|
|
||||||
|
|
||||||
<android.support.design.widget.AppBarLayout
|
<android.support.design.widget.AppBarLayout
|
||||||
android:id="@+id/settings.appbar"
|
android:id="@+id/appbar"
|
||||||
app:elevation="0dp"
|
|
||||||
android:background="@color/colorPrimaryDark"
|
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:theme="@style/AppTheme.AppBarOverlay">
|
android:theme="@style/AppTheme.AppBarOverlay">
|
||||||
|
@ -21,72 +17,45 @@
|
||||||
<android.support.v7.widget.Toolbar
|
<android.support.v7.widget.Toolbar
|
||||||
android:id="@+id/toolbar"
|
android:id="@+id/toolbar"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="?attr/actionBarSize"
|
android:layout_height="?android:attr/actionBarSize"
|
||||||
android:backgroundTint="@color/colorPrimary"
|
|
||||||
android:background="@drawable/background_rounded_main"
|
|
||||||
app:popupTheme="@style/AppTheme.PopupOverlay"/>
|
app:popupTheme="@style/AppTheme.PopupOverlay"/>
|
||||||
|
|
||||||
</android.support.design.widget.AppBarLayout>
|
</android.support.design.widget.AppBarLayout>
|
||||||
|
|
||||||
<android.support.constraint.ConstraintLayout
|
<android.support.constraint.ConstraintLayout
|
||||||
android:id="@+id/constraintLayout"
|
app:layout_behavior="@string/appbar_scrolling_view_behavior"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent"
|
android:layout_height="match_parent">
|
||||||
android:background="@drawable/background_rounded_main"
|
|
||||||
app:layout_behavior="@string/appbar_scrolling_view_behavior">
|
|
||||||
|
|
||||||
<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.v4.widget.SwipeRefreshLayout
|
|
||||||
android:id="@+id/recycler_refresh"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content">
|
|
||||||
|
|
||||||
<android.support.v7.widget.RecyclerView
|
<android.support.v7.widget.RecyclerView
|
||||||
android:id="@+id/orgRecyclerView"
|
android:id="@+id/recyclerView"
|
||||||
android:layout_width="0dp"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="0dp"
|
android:layout_height="match_parent"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintTop_toTopOf="parent"
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
app:layout_constraintBottom_toBottomOf="parent"/>
|
app:layout_constraintBottom_toBottomOf="parent"/>
|
||||||
|
|
||||||
</android.support.v4.widget.SwipeRefreshLayout>
|
<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.support.constraint.ConstraintLayout>
|
||||||
|
|
||||||
<android.support.design.widget.FloatingActionButton
|
<android.support.design.widget.FloatingActionButton
|
||||||
android:id="@+id/fab_add"
|
android:id="@+id/fab"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_margin="@dimen/fab_margin"
|
|
||||||
app:fabSize="normal"
|
app:fabSize="normal"
|
||||||
app:layout_anchor="@+id/constraintLayout"
|
android:tint="@color/colorWhite"
|
||||||
app:layout_anchorGravity="right|bottom"
|
android:src="@drawable/icon_add"
|
||||||
app:srcCompat="@drawable/ic_add_white"/>
|
android:layout_gravity="bottom|right|end"
|
||||||
|
android:layout_margin="16dp"/>
|
||||||
<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"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
|
||||||
<android.support.constraint.ConstraintLayout
|
<android.support.constraint.ConstraintLayout
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="match_parent">
|
android:layout_height="match_parent">
|
||||||
|
|
||||||
<ImageView
|
<de.overview.wg.its.mispauth.cam.AutoFitTextureView
|
||||||
android:id="@+id/image_view_qr"
|
android:id="@+id/texture"
|
||||||
|
android:layout_width="match_parent"
|
||||||
android:layout_width="wrap_content"
|
android:layout_height="match_parent"
|
||||||
android:layout_height="0dp"
|
|
||||||
|
|
||||||
android:adjustViewBounds="true"
|
|
||||||
android:scaleType="fitCenter"
|
|
||||||
|
|
||||||
app:layout_constraintTop_toTopOf="parent"
|
app:layout_constraintTop_toTopOf="parent"
|
||||||
app:layout_constraintStart_toStartOf="parent"
|
|
||||||
app:layout_constraintEnd_toEndOf="parent"
|
app:layout_constraintEnd_toEndOf="parent"
|
||||||
|
app:layout_constraintStart_toStartOf="parent"
|
||||||
app:layout_constraintBottom_toBottomOf="parent"/>
|
app:layout_constraintBottom_toBottomOf="parent"/>
|
||||||
|
|
||||||
</android.support.constraint.ConstraintLayout>
|
</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>
|
|
@ -1,29 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<RelativeLayout
|
|
||||||
xmlns:android="http://schemas.android.com/apk/res/android"
|
|
||||||
android:id="@+id/parent_layout"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:padding="16dp"
|
|
||||||
android:clickable="true"
|
|
||||||
android:focusable="true">
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/ext_org_title"
|
|
||||||
android:layout_marginEnd="40dp"
|
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_alignParentTop="true"
|
|
||||||
android:text="Title"
|
|
||||||
android:textSize="20sp"
|
|
||||||
android:textStyle="bold"/>
|
|
||||||
|
|
||||||
<TextView
|
|
||||||
android:id="@+id/ext_org_sub_title"
|
|
||||||
android:layout_width="wrap_content"
|
|
||||||
android:layout_height="wrap_content"
|
|
||||||
android:layout_below="@id/ext_org_title"
|
|
||||||
android:text="Short description describing the description ..."
|
|
||||||
android:textSize="15sp"/>
|
|
||||||
|
|
||||||
</RelativeLayout>
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue