2018-02-13 21:17:21 +01:00
|
|
|
package me.impy.aegis.ui;
|
2016-08-15 21:29:41 +02:00
|
|
|
|
2017-12-13 19:00:58 +01:00
|
|
|
import android.Manifest;
|
2016-08-21 22:32:07 +02:00
|
|
|
import android.content.ClipData;
|
|
|
|
import android.content.ClipboardManager;
|
2016-08-21 22:24:04 +02:00
|
|
|
import android.content.Context;
|
2016-08-15 22:31:28 +02:00
|
|
|
import android.content.Intent;
|
2018-01-01 21:11:40 +01:00
|
|
|
import android.graphics.Rect;
|
2016-11-01 22:16:54 +01:00
|
|
|
import android.support.design.widget.BottomSheetDialog;
|
2016-08-15 21:29:41 +02:00
|
|
|
import android.os.Bundle;
|
2016-08-16 14:14:17 +02:00
|
|
|
import android.view.Menu;
|
|
|
|
import android.view.MenuItem;
|
2018-01-01 21:11:40 +01:00
|
|
|
import android.view.MotionEvent;
|
2016-11-01 22:16:54 +01:00
|
|
|
import android.widget.LinearLayout;
|
2016-08-17 01:14:25 +02:00
|
|
|
import android.widget.Toast;
|
|
|
|
|
2017-12-30 00:26:16 +01:00
|
|
|
import com.getbase.floatingactionbutton.FloatingActionsMenu;
|
|
|
|
|
2017-05-03 21:08:38 +02:00
|
|
|
import java.lang.reflect.UndeclaredThrowableException;
|
2016-08-16 20:04:38 +02:00
|
|
|
|
2018-02-13 21:17:21 +01:00
|
|
|
import me.impy.aegis.AegisApplication;
|
|
|
|
import me.impy.aegis.R;
|
2017-05-03 21:08:38 +02:00
|
|
|
import me.impy.aegis.crypto.MasterKey;
|
2018-03-19 18:00:53 +01:00
|
|
|
import me.impy.aegis.db.DatabaseManagerException;
|
2017-08-26 21:15:53 +02:00
|
|
|
import me.impy.aegis.db.DatabaseEntry;
|
2017-08-06 16:03:36 +02:00
|
|
|
import me.impy.aegis.db.DatabaseManager;
|
2017-12-13 19:00:58 +01:00
|
|
|
import me.impy.aegis.helpers.PermissionHelper;
|
2018-05-10 23:11:21 +02:00
|
|
|
import me.impy.aegis.ui.dialogs.Dialogs;
|
2018-02-13 21:17:21 +01:00
|
|
|
import me.impy.aegis.ui.views.KeyProfile;
|
|
|
|
import me.impy.aegis.ui.views.KeyProfileView;
|
2016-08-15 21:29:41 +02:00
|
|
|
|
2017-12-25 15:36:29 +01:00
|
|
|
public class MainActivity extends AegisActivity implements KeyProfileView.Listener {
|
2017-12-13 19:00:58 +01:00
|
|
|
// activity request codes
|
2017-12-30 00:26:16 +01:00
|
|
|
private static final int CODE_SCAN_KEYINFO = 0;
|
2017-08-06 16:03:36 +02:00
|
|
|
private static final int CODE_ADD_KEYINFO = 1;
|
2017-12-27 13:08:02 +01:00
|
|
|
private static final int CODE_EDIT_KEYINFO = 2;
|
2017-12-30 00:26:16 +01:00
|
|
|
private static final int CODE_ENTER_KEYINFO = 3;
|
|
|
|
private static final int CODE_DO_INTRO = 4;
|
|
|
|
private static final int CODE_DECRYPT = 5;
|
2018-05-10 14:50:47 +02:00
|
|
|
private static final int CODE_PREFERENCES = 6;
|
2016-08-24 23:48:25 +02:00
|
|
|
|
2017-12-13 19:00:58 +01:00
|
|
|
// permission request codes
|
2018-05-10 19:34:42 +02:00
|
|
|
private static final int CODE_PERM_CAMERA = 0;
|
2017-12-13 19:00:58 +01:00
|
|
|
|
2017-12-23 22:33:32 +01:00
|
|
|
private AegisApplication _app;
|
2017-08-26 21:15:53 +02:00
|
|
|
private DatabaseManager _db;
|
2017-12-25 15:36:29 +01:00
|
|
|
private KeyProfileView _keyProfileView;
|
2016-09-30 01:08:03 +02:00
|
|
|
|
2017-08-26 21:15:53 +02:00
|
|
|
private Menu _menu;
|
2018-01-01 21:11:40 +01:00
|
|
|
private FloatingActionsMenu _fabMenu;
|
2016-08-16 14:14:17 +02:00
|
|
|
|
2016-08-15 21:29:41 +02:00
|
|
|
@Override
|
|
|
|
protected void onCreate(Bundle savedInstanceState) {
|
|
|
|
super.onCreate(savedInstanceState);
|
2017-12-23 22:33:32 +01:00
|
|
|
_app = (AegisApplication) getApplication();
|
|
|
|
_db = _app.getDatabaseManager();
|
2016-09-29 12:31:55 +02:00
|
|
|
|
2017-12-23 22:33:32 +01:00
|
|
|
// set up the main view
|
2016-08-15 21:29:41 +02:00
|
|
|
setContentView(R.layout.activity_main);
|
2017-12-03 16:47:27 +01:00
|
|
|
|
2017-12-25 15:36:29 +01:00
|
|
|
// set up the key profile view
|
|
|
|
_keyProfileView = (KeyProfileView) getSupportFragmentManager().findFragmentById(R.id.key_profiles);
|
|
|
|
_keyProfileView.setListener(this);
|
2018-05-11 20:08:51 +02:00
|
|
|
_keyProfileView.setShowIssuer(getPreferences().isIssuerVisible());
|
2017-12-25 15:36:29 +01:00
|
|
|
|
2017-12-23 22:33:32 +01:00
|
|
|
// set up the floating action button
|
2018-01-01 21:11:40 +01:00
|
|
|
_fabMenu = findViewById(R.id.fab);
|
2017-12-30 00:26:16 +01:00
|
|
|
findViewById(R.id.fab_enter).setOnClickListener(view -> {
|
2018-01-01 21:11:40 +01:00
|
|
|
_fabMenu.collapse();
|
2017-12-30 00:26:16 +01:00
|
|
|
onEnterKeyInfo();
|
|
|
|
});
|
|
|
|
findViewById(R.id.fab_scan).setOnClickListener(view -> {
|
2018-01-01 21:11:40 +01:00
|
|
|
_fabMenu.collapse();
|
2017-12-30 00:26:16 +01:00
|
|
|
onScanKeyInfo();
|
|
|
|
});
|
2016-08-16 14:14:17 +02:00
|
|
|
|
2017-12-25 00:16:24 +01:00
|
|
|
// skip this part if this is the not initial startup and the database has been unlocked
|
2017-12-24 22:29:32 +01:00
|
|
|
if (!_app.isRunning() && _db.isLocked()) {
|
2017-12-25 00:16:24 +01:00
|
|
|
if (!_db.fileExists()) {
|
|
|
|
// the db doesn't exist, start the intro
|
2018-05-11 20:08:51 +02:00
|
|
|
if (getPreferences().isIntroDone()) {
|
2017-12-25 00:16:24 +01:00
|
|
|
Toast.makeText(this, "Database file not found, starting over...", Toast.LENGTH_SHORT).show();
|
|
|
|
}
|
2017-12-23 22:33:32 +01:00
|
|
|
Intent intro = new Intent(this, IntroActivity.class);
|
|
|
|
startActivityForResult(intro, CODE_DO_INTRO);
|
|
|
|
} else {
|
2017-12-25 00:16:24 +01:00
|
|
|
// the db exists, load the database
|
|
|
|
// if the database is still encrypted, start the auth activity
|
2017-12-23 22:33:32 +01:00
|
|
|
try {
|
2017-12-25 19:02:46 +01:00
|
|
|
if (!_db.isLoaded()) {
|
|
|
|
_db.load();
|
|
|
|
}
|
2017-12-24 22:29:32 +01:00
|
|
|
if (_db.isLocked()) {
|
2017-12-24 21:42:08 +01:00
|
|
|
startAuthActivity();
|
2017-12-23 22:33:32 +01:00
|
|
|
}
|
2018-03-19 18:00:53 +01:00
|
|
|
} catch (DatabaseManagerException e) {
|
2017-12-23 22:33:32 +01:00
|
|
|
e.printStackTrace();
|
|
|
|
Toast.makeText(this, "An error occurred while trying to deserialize the database", Toast.LENGTH_LONG).show();
|
2018-03-19 18:00:53 +01:00
|
|
|
finish();
|
2017-12-23 22:33:32 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-12-25 00:16:24 +01:00
|
|
|
// if the database has been decrypted at this point, we can load the key profiles
|
2017-12-24 22:29:32 +01:00
|
|
|
if (!_db.isLocked()) {
|
2017-12-23 22:33:32 +01:00
|
|
|
loadKeyProfiles();
|
|
|
|
}
|
2016-08-15 21:29:41 +02:00
|
|
|
}
|
2016-08-16 00:08:01 +02:00
|
|
|
|
2018-01-01 21:11:40 +01:00
|
|
|
@Override
|
|
|
|
public boolean dispatchTouchEvent(MotionEvent event) {
|
|
|
|
// collapse the fab menu on touch
|
|
|
|
if (event.getAction() == MotionEvent.ACTION_DOWN) {
|
|
|
|
if (_fabMenu.isExpanded()) {
|
|
|
|
Rect rect = new Rect();
|
|
|
|
_fabMenu.getGlobalVisibleRect(rect);
|
|
|
|
|
|
|
|
if (!rect.contains((int) event.getRawX(), (int) event.getRawY())) {
|
|
|
|
_fabMenu.collapse();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return super.dispatchTouchEvent(event);
|
|
|
|
}
|
|
|
|
|
2017-12-25 20:01:58 +01:00
|
|
|
@Override
|
|
|
|
protected void onNewIntent(Intent intent) {
|
|
|
|
super.onNewIntent(intent);
|
|
|
|
setIntent(intent);
|
|
|
|
|
2017-12-26 19:29:47 +01:00
|
|
|
if (!doShortcutActions() || _db.isLocked()) {
|
2017-12-25 20:01:58 +01:00
|
|
|
startAuthActivity();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-12-24 21:42:08 +01:00
|
|
|
@Override
|
2016-08-16 00:08:01 +02:00
|
|
|
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
|
2017-12-25 20:01:58 +01:00
|
|
|
if (data == null) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2017-08-06 16:03:36 +02:00
|
|
|
switch (requestCode) {
|
2017-12-30 00:26:16 +01:00
|
|
|
case CODE_SCAN_KEYINFO:
|
|
|
|
onScanKeyInfoResult(resultCode, data);
|
2017-08-06 16:03:36 +02:00
|
|
|
break;
|
|
|
|
case CODE_ADD_KEYINFO:
|
|
|
|
onAddKeyInfoResult(resultCode, data);
|
|
|
|
break;
|
2017-12-27 22:04:22 +01:00
|
|
|
case CODE_EDIT_KEYINFO:
|
|
|
|
onEditKeyInfoResult(resultCode, data);
|
|
|
|
break;
|
2017-12-30 00:26:16 +01:00
|
|
|
case CODE_ENTER_KEYINFO:
|
|
|
|
onEnterKeyInfoResult(resultCode, data);
|
|
|
|
break;
|
2017-08-06 16:03:36 +02:00
|
|
|
case CODE_DO_INTRO:
|
|
|
|
onDoIntroResult(resultCode, data);
|
|
|
|
break;
|
2017-08-06 18:15:47 +02:00
|
|
|
case CODE_DECRYPT:
|
|
|
|
onDecryptResult(resultCode, data);
|
|
|
|
break;
|
2017-12-10 19:19:48 +01:00
|
|
|
case CODE_PREFERENCES:
|
|
|
|
onPreferencesResult(resultCode, data);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-12-13 19:00:58 +01:00
|
|
|
@Override
|
|
|
|
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
|
|
|
|
if (!PermissionHelper.checkResults(grantResults)) {
|
|
|
|
Toast.makeText(this, "Permission denied", Toast.LENGTH_SHORT).show();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
switch (requestCode) {
|
|
|
|
case CODE_PERM_CAMERA:
|
2017-12-30 00:26:16 +01:00
|
|
|
onScanKeyInfo();
|
2017-12-13 19:00:58 +01:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-12-10 19:19:48 +01:00
|
|
|
private void onPreferencesResult(int resultCode, Intent data) {
|
2017-12-12 21:55:34 +01:00
|
|
|
// refresh the entire key profile list if needed
|
2018-05-11 19:33:20 +02:00
|
|
|
if (data.getBooleanExtra("needsRecreate", false)) {
|
|
|
|
recreate();
|
|
|
|
} else if (data.getBooleanExtra("needsRefresh", false)) {
|
2018-05-11 20:08:51 +02:00
|
|
|
boolean showIssuer = getPreferences().isIssuerVisible();
|
2017-12-25 15:36:29 +01:00
|
|
|
_keyProfileView.setShowIssuer(showIssuer);
|
2017-12-10 19:19:48 +01:00
|
|
|
}
|
2017-08-06 16:03:36 +02:00
|
|
|
}
|
2016-08-16 00:08:01 +02:00
|
|
|
|
2018-01-02 21:50:07 +01:00
|
|
|
private void startEditProfileActivity(int requestCode, KeyProfile profile, boolean isNew) {
|
2017-12-30 00:26:16 +01:00
|
|
|
Intent intent = new Intent(this, EditProfileActivity.class);
|
2018-01-02 21:50:07 +01:00
|
|
|
if (profile != null) {
|
|
|
|
intent.putExtra("KeyProfile", profile);
|
|
|
|
}
|
|
|
|
intent.putExtra("isNew", isNew);
|
|
|
|
startActivityForResult(intent, requestCode);
|
|
|
|
}
|
|
|
|
|
|
|
|
private void onEnterKeyInfo() {
|
|
|
|
startEditProfileActivity(CODE_ENTER_KEYINFO, null, true);
|
2017-12-30 00:26:16 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
private void onScanKeyInfo() {
|
2017-12-13 19:00:58 +01:00
|
|
|
if (!PermissionHelper.request(this, CODE_PERM_CAMERA, Manifest.permission.CAMERA)) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2017-12-25 19:02:46 +01:00
|
|
|
startScanActivity();
|
2017-12-13 19:00:58 +01:00
|
|
|
}
|
|
|
|
|
2017-12-30 00:26:16 +01:00
|
|
|
private void onScanKeyInfoResult(int resultCode, Intent data) {
|
2017-12-03 16:47:27 +01:00
|
|
|
if (resultCode == RESULT_OK) {
|
2018-01-02 21:50:07 +01:00
|
|
|
KeyProfile profile = (KeyProfile)data.getSerializableExtra("KeyProfile");
|
|
|
|
startEditProfileActivity(CODE_ADD_KEYINFO, profile, true);
|
2016-08-16 00:08:01 +02:00
|
|
|
}
|
2017-08-06 16:03:36 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
private void onAddKeyInfoResult(int resultCode, Intent data) {
|
2017-12-03 16:47:27 +01:00
|
|
|
if (resultCode == RESULT_OK) {
|
|
|
|
KeyProfile profile = (KeyProfile) data.getSerializableExtra("KeyProfile");
|
|
|
|
addKey(profile);
|
|
|
|
saveDatabase();
|
2017-08-06 16:03:36 +02:00
|
|
|
}
|
2017-08-26 15:47:57 +02:00
|
|
|
}
|
|
|
|
|
2017-12-27 22:04:22 +01:00
|
|
|
private void onEditKeyInfoResult(int resultCode, Intent data) {
|
|
|
|
if (resultCode == RESULT_OK) {
|
|
|
|
KeyProfile profile = (KeyProfile) data.getSerializableExtra("KeyProfile");
|
2018-01-02 14:36:56 +01:00
|
|
|
if (!data.getBooleanExtra("delete", false)) {
|
|
|
|
// this profile has been serialized/deserialized and is no longer the same instance it once was
|
|
|
|
// to deal with this, the replaceKey functions are used
|
2018-03-19 18:00:53 +01:00
|
|
|
_db.replaceKey(profile.getEntry());
|
2018-01-02 14:36:56 +01:00
|
|
|
_keyProfileView.replaceKey(profile);
|
2018-01-01 22:53:10 +01:00
|
|
|
saveDatabase();
|
2018-01-02 14:36:56 +01:00
|
|
|
} else {
|
|
|
|
deleteProfile(profile);
|
2018-01-01 22:53:10 +01:00
|
|
|
}
|
2017-12-27 22:04:22 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-12-30 00:26:16 +01:00
|
|
|
private void onEnterKeyInfoResult(int resultCode, Intent data) {
|
|
|
|
if (resultCode == RESULT_OK) {
|
|
|
|
KeyProfile profile = (KeyProfile) data.getSerializableExtra("KeyProfile");
|
2018-01-01 21:52:56 +01:00
|
|
|
addKey(profile);
|
2017-12-30 00:26:16 +01:00
|
|
|
saveDatabase();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-08-26 15:47:57 +02:00
|
|
|
private void addKey(KeyProfile profile) {
|
2017-11-26 19:50:05 +01:00
|
|
|
DatabaseEntry entry = profile.getEntry();
|
2017-08-26 21:15:53 +02:00
|
|
|
entry.setName(entry.getInfo().getAccountName());
|
2018-03-19 18:00:53 +01:00
|
|
|
_db.addKey(entry);
|
2017-12-25 15:36:29 +01:00
|
|
|
_keyProfileView.addKey(profile);
|
2017-08-06 16:03:36 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
private void onDoIntroResult(int resultCode, Intent data) {
|
|
|
|
if (resultCode == IntroActivity.RESULT_EXCEPTION) {
|
|
|
|
// TODO: user feedback
|
|
|
|
Exception e = (Exception) data.getSerializableExtra("exception");
|
|
|
|
throw new UndeclaredThrowableException(e);
|
|
|
|
}
|
2016-11-13 18:21:00 +01:00
|
|
|
|
2017-08-06 16:03:36 +02:00
|
|
|
MasterKey key = (MasterKey) data.getSerializableExtra("key");
|
|
|
|
try {
|
2017-08-26 21:15:53 +02:00
|
|
|
_db.load();
|
2017-12-24 22:29:32 +01:00
|
|
|
if (_db.isLocked()) {
|
2017-12-23 22:33:32 +01:00
|
|
|
_db.unlock(key);
|
2016-08-24 23:48:25 +02:00
|
|
|
}
|
2018-03-19 18:00:53 +01:00
|
|
|
} catch (DatabaseManagerException e) {
|
2017-11-27 21:06:23 +01:00
|
|
|
e.printStackTrace();
|
|
|
|
Toast.makeText(this, "An error occurred while trying to load/decrypt the database", Toast.LENGTH_LONG).show();
|
2017-12-24 21:42:08 +01:00
|
|
|
startAuthActivity();
|
2017-11-27 21:06:23 +01:00
|
|
|
return;
|
2016-08-24 23:48:25 +02:00
|
|
|
}
|
2017-08-06 18:15:47 +02:00
|
|
|
|
|
|
|
loadKeyProfiles();
|
|
|
|
}
|
|
|
|
|
2017-12-25 19:02:46 +01:00
|
|
|
private void onDecryptResult(int resultCode, Intent intent) {
|
|
|
|
MasterKey key = (MasterKey) intent.getSerializableExtra("key");
|
2017-08-06 18:15:47 +02:00
|
|
|
try {
|
2017-12-23 22:33:32 +01:00
|
|
|
_db.unlock(key);
|
2018-03-19 18:00:53 +01:00
|
|
|
} catch (DatabaseManagerException e) {
|
2017-11-27 21:06:23 +01:00
|
|
|
e.printStackTrace();
|
|
|
|
Toast.makeText(this, "An error occurred while trying to decrypt the database", Toast.LENGTH_LONG).show();
|
2017-12-24 21:42:08 +01:00
|
|
|
startAuthActivity();
|
2017-11-27 21:06:23 +01:00
|
|
|
return;
|
2017-08-06 18:15:47 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
loadKeyProfiles();
|
2017-12-03 16:47:27 +01:00
|
|
|
doShortcutActions();
|
|
|
|
}
|
|
|
|
|
2017-12-25 19:02:46 +01:00
|
|
|
private void startScanActivity() {
|
|
|
|
Intent scannerActivity = new Intent(getApplicationContext(), ScannerActivity.class);
|
2017-12-30 00:26:16 +01:00
|
|
|
startActivityForResult(scannerActivity, CODE_SCAN_KEYINFO);
|
2017-12-25 19:02:46 +01:00
|
|
|
}
|
|
|
|
|
2017-12-25 20:01:58 +01:00
|
|
|
private boolean doShortcutActions() {
|
2017-12-26 14:18:00 +01:00
|
|
|
// return false if an action was blocked by a locked database
|
|
|
|
// otherwise, always return true
|
2017-12-03 16:47:27 +01:00
|
|
|
Intent intent = getIntent();
|
2017-12-25 19:02:46 +01:00
|
|
|
String action = intent.getStringExtra("action");
|
2017-12-26 14:18:00 +01:00
|
|
|
if (action == null) {
|
|
|
|
return true;
|
|
|
|
} else if (_db.isLocked()) {
|
2017-12-25 20:01:58 +01:00
|
|
|
return false;
|
2017-12-03 16:47:27 +01:00
|
|
|
}
|
|
|
|
|
2017-12-25 19:02:46 +01:00
|
|
|
switch (action) {
|
|
|
|
case "scan":
|
|
|
|
startScanActivity();
|
2017-12-03 16:47:27 +01:00
|
|
|
break;
|
|
|
|
}
|
2017-12-25 20:01:58 +01:00
|
|
|
|
|
|
|
intent.removeExtra("action");
|
|
|
|
return true;
|
2016-08-16 00:08:01 +02:00
|
|
|
}
|
2016-08-16 14:14:17 +02:00
|
|
|
|
2017-12-13 16:39:03 +01:00
|
|
|
public void startActivityForResult(Intent intent, int requestCode) {
|
|
|
|
intent.addFlags(Intent.FLAG_ACTIVITY_REORDER_TO_FRONT);
|
|
|
|
super.startActivityForResult(intent, requestCode);
|
|
|
|
}
|
|
|
|
|
2016-09-30 01:08:03 +02:00
|
|
|
@Override
|
|
|
|
protected void onResume() {
|
|
|
|
super.onResume();
|
2018-05-14 16:53:27 +02:00
|
|
|
updateLockIcon();
|
2017-12-24 21:42:08 +01:00
|
|
|
|
2018-02-09 19:28:31 +01:00
|
|
|
// refresh all codes to prevent showing old ones
|
|
|
|
_keyProfileView.refresh();
|
2016-09-30 01:08:03 +02:00
|
|
|
}
|
|
|
|
|
2017-12-27 13:08:02 +01:00
|
|
|
private BottomSheetDialog createBottomSheet(final KeyProfile profile) {
|
2018-05-11 15:12:36 +02:00
|
|
|
BottomSheetDialog dialog = new BottomSheetDialog(this);
|
|
|
|
dialog.setContentView(R.layout.bottom_sheet_edit_profile);
|
|
|
|
dialog.setCancelable(true);
|
|
|
|
dialog.getWindow().setLayout(LinearLayout.LayoutParams.MATCH_PARENT,
|
2016-11-01 22:16:54 +01:00
|
|
|
LinearLayout.LayoutParams.WRAP_CONTENT);
|
2018-05-11 15:12:36 +02:00
|
|
|
dialog.show();
|
2016-11-01 22:16:54 +01:00
|
|
|
|
2018-05-11 15:12:36 +02:00
|
|
|
dialog.findViewById(R.id.copy_button).setOnClickListener(view -> {
|
|
|
|
dialog.dismiss();
|
2016-11-01 22:16:54 +01:00
|
|
|
ClipboardManager clipboard = (ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE);
|
2017-12-12 01:50:00 +01:00
|
|
|
ClipData clip = ClipData.newPlainText("text/plain", profile.getCode());
|
2016-11-01 22:16:54 +01:00
|
|
|
clipboard.setPrimaryClip(clip);
|
2018-05-11 15:12:36 +02:00
|
|
|
Toast.makeText(this, "Code copied to the clipboard", Toast.LENGTH_SHORT).show();
|
2016-11-01 22:16:54 +01:00
|
|
|
});
|
2016-11-01 22:57:21 +01:00
|
|
|
|
2018-05-11 15:12:36 +02:00
|
|
|
dialog.findViewById(R.id.delete_button).setOnClickListener(view -> {
|
|
|
|
dialog.dismiss();
|
|
|
|
Dialogs.showDeleteEntryDialog(this, (d, which) -> {
|
2018-05-10 23:11:21 +02:00
|
|
|
deleteProfile(profile);
|
|
|
|
});
|
2016-11-01 22:57:21 +01:00
|
|
|
});
|
|
|
|
|
2018-05-11 15:12:36 +02:00
|
|
|
dialog.findViewById(R.id.edit_button).setOnClickListener(view -> {
|
|
|
|
dialog.dismiss();
|
2018-01-02 21:50:07 +01:00
|
|
|
startEditProfileActivity(CODE_EDIT_KEYINFO, profile, false);
|
2016-11-01 22:57:21 +01:00
|
|
|
});
|
|
|
|
|
2018-05-11 15:12:36 +02:00
|
|
|
return dialog;
|
2016-11-01 22:57:21 +01:00
|
|
|
}
|
2016-11-01 22:16:54 +01:00
|
|
|
|
2017-12-12 01:50:00 +01:00
|
|
|
private void deleteProfile(KeyProfile profile) {
|
2018-05-10 23:11:21 +02:00
|
|
|
_db.removeKey(profile.getEntry());
|
|
|
|
saveDatabase();
|
2017-12-12 21:08:30 +01:00
|
|
|
|
2018-05-10 23:11:21 +02:00
|
|
|
_keyProfileView.removeKey(profile);
|
2016-11-01 22:16:54 +01:00
|
|
|
}
|
|
|
|
|
2016-08-16 14:14:17 +02:00
|
|
|
@Override
|
|
|
|
public boolean onCreateOptionsMenu(Menu menu) {
|
2017-08-26 21:15:53 +02:00
|
|
|
_menu = menu;
|
2016-08-16 14:14:17 +02:00
|
|
|
getMenuInflater().inflate(R.menu.menu_main, menu);
|
2017-08-26 21:15:53 +02:00
|
|
|
updateLockIcon();
|
2016-08-16 14:14:17 +02:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
|
|
|
public boolean onOptionsItemSelected(MenuItem item) {
|
2017-08-14 00:04:06 +02:00
|
|
|
switch (item.getItemId()) {
|
|
|
|
case R.id.action_settings:
|
2018-02-09 17:31:07 +01:00
|
|
|
Intent intent = new Intent(this, PreferencesActivity.class);
|
|
|
|
startActivityForResult(intent, CODE_PREFERENCES);
|
2017-08-14 00:04:06 +02:00
|
|
|
return true;
|
|
|
|
case R.id.action_lock:
|
2017-12-25 15:36:29 +01:00
|
|
|
_keyProfileView.clearKeys();
|
2018-03-19 18:00:53 +01:00
|
|
|
_db.lock();
|
2017-12-24 21:42:08 +01:00
|
|
|
startAuthActivity();
|
2017-08-14 00:04:06 +02:00
|
|
|
return true;
|
|
|
|
default:
|
|
|
|
return super.onOptionsItemSelected(item);
|
2016-08-16 14:14:17 +02:00
|
|
|
}
|
|
|
|
}
|
2016-09-30 01:08:03 +02:00
|
|
|
|
2017-12-24 21:42:08 +01:00
|
|
|
private void startAuthActivity() {
|
|
|
|
Intent intent = new Intent(this, AuthActivity.class);
|
|
|
|
intent.putExtra("slots", _db.getFile().getSlots());
|
|
|
|
startActivityForResult(intent, CODE_DECRYPT);
|
|
|
|
}
|
|
|
|
|
2017-08-06 18:15:47 +02:00
|
|
|
private void saveDatabase() {
|
2017-05-03 21:08:38 +02:00
|
|
|
try {
|
2017-08-26 21:15:53 +02:00
|
|
|
_db.save();
|
2018-03-19 18:00:53 +01:00
|
|
|
} catch (DatabaseManagerException e) {
|
2017-11-27 21:06:23 +01:00
|
|
|
e.printStackTrace();
|
|
|
|
Toast.makeText(this, "An error occurred while trying to save the database", Toast.LENGTH_LONG).show();
|
2016-11-13 18:21:00 +01:00
|
|
|
}
|
2017-08-06 18:15:47 +02:00
|
|
|
}
|
2016-11-13 18:21:00 +01:00
|
|
|
|
2017-08-06 18:15:47 +02:00
|
|
|
private void loadKeyProfiles() {
|
2017-08-26 21:15:53 +02:00
|
|
|
updateLockIcon();
|
|
|
|
|
2018-03-19 18:00:53 +01:00
|
|
|
for (DatabaseEntry entry : _db.getKeys()) {
|
|
|
|
_keyProfileView.addKey(new KeyProfile(entry));
|
2017-08-06 16:03:36 +02:00
|
|
|
}
|
2016-11-13 18:21:00 +01:00
|
|
|
}
|
2017-08-26 21:15:53 +02:00
|
|
|
|
|
|
|
private void updateLockIcon() {
|
2017-12-24 21:42:08 +01:00
|
|
|
// hide the lock icon if the database is not unlocked
|
2017-12-24 22:29:32 +01:00
|
|
|
if (_menu != null && !_db.isLocked()) {
|
2017-08-26 21:15:53 +02:00
|
|
|
MenuItem item = _menu.findItem(R.id.action_lock);
|
|
|
|
item.setVisible(_db.getFile().isEncrypted());
|
|
|
|
}
|
|
|
|
}
|
2017-12-12 01:50:00 +01:00
|
|
|
|
|
|
|
@Override
|
2017-12-25 15:36:29 +01:00
|
|
|
public void onEntryClick(KeyProfile profile) {
|
2017-12-12 01:50:00 +01:00
|
|
|
createBottomSheet(profile).show();
|
|
|
|
}
|
|
|
|
|
|
|
|
@Override
|
2017-12-25 15:36:29 +01:00
|
|
|
public void onEntryMove(DatabaseEntry entry1, DatabaseEntry entry2) {
|
2018-03-19 18:00:53 +01:00
|
|
|
_db.swapKeys(entry1, entry2);
|
2017-12-12 01:50:00 +01:00
|
|
|
}
|
2017-12-12 03:14:26 +01:00
|
|
|
|
|
|
|
@Override
|
2017-12-25 15:36:29 +01:00
|
|
|
public void onEntryDrop(DatabaseEntry entry) {
|
2017-12-12 03:14:26 +01:00
|
|
|
saveDatabase();
|
|
|
|
}
|
2016-08-15 21:29:41 +02:00
|
|
|
}
|