From 57e3574693bf89235497eb21fc1de2116360c432 Mon Sep 17 00:00:00 2001 From: Alexander Bakker Date: Sun, 12 May 2019 17:12:09 +0200 Subject: [PATCH] Fix a bug where Aegis would forcibly pop up after unlocking the device --- .../aegis/AegisApplication.java | 36 ++++++++++++++----- .../aegis/ui/AegisActivity.java | 32 +++++++++++++++-- .../aegis/ui/MainActivity.java | 29 +++++++-------- 3 files changed, 72 insertions(+), 25 deletions(-) diff --git a/app/src/main/java/com/beemdevelopment/aegis/AegisApplication.java b/app/src/main/java/com/beemdevelopment/aegis/AegisApplication.java index d5be4670..bab3bca6 100644 --- a/app/src/main/java/com/beemdevelopment/aegis/AegisApplication.java +++ b/app/src/main/java/com/beemdevelopment/aegis/AegisApplication.java @@ -13,19 +13,23 @@ import android.os.Build; import com.beemdevelopment.aegis.db.DatabaseManager; import com.beemdevelopment.aegis.ui.MainActivity; +import java.util.ArrayList; import java.util.Collections; +import java.util.List; import androidx.annotation.RequiresApi; public class AegisApplication extends Application { private DatabaseManager _manager; private Preferences _prefs; + private List _lockListeners; @Override public void onCreate() { super.onCreate(); _manager = new DatabaseManager(this); _prefs = new Preferences(this); + _lockListeners = new ArrayList<>(); // listen for SCREEN_OFF events ScreenOffReceiver receiver = new ScreenOffReceiver(); @@ -44,6 +48,25 @@ public class AegisApplication extends Application { return _prefs; } + public boolean isAutoLockEnabled() { + return _prefs.isAutoLockEnabled() && _manager.isLoaded() && _manager.isEncryptionEnabled() && !_manager.isLocked(); + } + + public void registerLockListener(LockListener listener) { + _lockListeners.add(listener); + } + + public void unregisterLockListener(LockListener listener) { + _lockListeners.remove(listener); + } + + public void lock() { + _manager.lock(); + for (LockListener listener : _lockListeners) { + listener.onLocked(); + } + } + @RequiresApi(api = Build.VERSION_CODES.N_MR1) private void initAppShortcuts() { ShortcutManager shortcutManager = getSystemService(ShortcutManager.class); @@ -65,19 +88,16 @@ public class AegisApplication extends Application { shortcutManager.setDynamicShortcuts(Collections.singletonList(shortcut)); } - public boolean isAutoLockEnabled() { - return _prefs.isAutoLockEnabled() && _manager.isLoaded() && _manager.isEncryptionEnabled() && !_manager.isLocked(); - } - private class ScreenOffReceiver extends BroadcastReceiver { @Override public void onReceive(Context context, Intent intent) { if (isAutoLockEnabled()) { - _manager.lock(); - Intent newIntent = new Intent(getApplicationContext(), MainActivity.class); - newIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK); - startActivity(newIntent); + lock(); } } } + + public interface LockListener { + void onLocked(); + } } diff --git a/app/src/main/java/com/beemdevelopment/aegis/ui/AegisActivity.java b/app/src/main/java/com/beemdevelopment/aegis/ui/AegisActivity.java index 6797f5ad..acc254da 100644 --- a/app/src/main/java/com/beemdevelopment/aegis/ui/AegisActivity.java +++ b/app/src/main/java/com/beemdevelopment/aegis/ui/AegisActivity.java @@ -13,9 +13,10 @@ import com.beemdevelopment.aegis.Preferences; import com.beemdevelopment.aegis.R; import com.beemdevelopment.aegis.Theme; +import androidx.annotation.CallSuper; import androidx.appcompat.app.AppCompatActivity; -public abstract class AegisActivity extends AppCompatActivity { +public abstract class AegisActivity extends AppCompatActivity implements AegisApplication.LockListener { private AegisApplication _app; @Override @@ -27,11 +28,10 @@ public abstract class AegisActivity extends AppCompatActivity { super.onCreate(savedInstanceState); // if the app was killed, relaunch MainActivity and close everything else - if (!(this instanceof MainActivity) && !(this instanceof AuthActivity) && _app.getDatabaseManager().isLocked()) { + if (savedInstanceState != null && isOrphan()) { Intent intent = new Intent(this, MainActivity.class); intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); startActivity(intent); - finish(); return; } @@ -42,6 +42,24 @@ public abstract class AegisActivity extends AppCompatActivity { // apply a dirty hack to make progress bars work even if animations are disabled setGlobalAnimationDurationScale(); + + // register a callback to listen for lock events + _app.registerLockListener(this); + } + + @Override + protected void onDestroy() { + _app.unregisterLockListener(this); + super.onDestroy(); + } + + @CallSuper + @Override + public void onLocked() { + if (isOrphan()) { + setResult(RESULT_CANCELED, null); + finish(); + } } protected AegisApplication getApp() { @@ -66,6 +84,14 @@ public abstract class AegisActivity extends AppCompatActivity { } } + /** + * Reports whether this Activity instance has become an orphan. This can happen if + * the vault was locked by an external trigger while the Activity was still open. + */ + private boolean isOrphan() { + return !(this instanceof MainActivity) && _app.getDatabaseManager().isLocked(); + } + private void setGlobalAnimationDurationScale() { float durationScale = Settings.Global.getFloat(getContentResolver(), Settings.Global.ANIMATOR_DURATION_SCALE, 0); if (durationScale != 1) { diff --git a/app/src/main/java/com/beemdevelopment/aegis/ui/MainActivity.java b/app/src/main/java/com/beemdevelopment/aegis/ui/MainActivity.java index 07067b07..667b32fb 100644 --- a/app/src/main/java/com/beemdevelopment/aegis/ui/MainActivity.java +++ b/app/src/main/java/com/beemdevelopment/aegis/ui/MainActivity.java @@ -147,6 +147,11 @@ public class MainActivity extends AegisActivity implements EntryListView.Listene return; } + // don't process any activity results if the vault is locked + if (requestCode != CODE_DECRYPT && _db.isLocked()) { + return; + } + switch (requestCode) { case CODE_SCAN: onScanResult(resultCode, data); @@ -371,10 +376,6 @@ public class MainActivity extends AegisActivity implements EntryListView.Listene intent.removeExtra("action"); } - public void startActivityForResult(Intent intent, int requestCode) { - super.startActivityForResult(intent, requestCode); - } - @Override protected void onResume() { super.onResume(); @@ -411,7 +412,7 @@ public class MainActivity extends AegisActivity implements EntryListView.Listene @Override public void onBackPressed() { if (_app.isAutoLockEnabled()) { - lockDatabase(); + _app.lock(); } super.onBackPressed(); @@ -481,7 +482,7 @@ public class MainActivity extends AegisActivity implements EntryListView.Listene startActivityForResult(intent, CODE_PREFERENCES); return true; case R.id.action_lock: - lockDatabase(); + _app.lock(); startAuthActivity(); return true; default: @@ -525,14 +526,6 @@ public class MainActivity extends AegisActivity implements EntryListView.Listene } } - private void lockDatabase() { - if (_loaded) { - _entryListView.clearEntries(); - _db.lock(); - _loaded = false; - } - } - private void unlockDatabase(DatabaseFileCredentials creds) { if (_loaded) { return; @@ -570,6 +563,7 @@ public class MainActivity extends AegisActivity implements EntryListView.Listene private void startAuthActivity() { Intent intent = new Intent(this, AuthActivity.class); intent.putExtra("slots", _db.getFileHeader().getSlots()); + intent.putExtra("requiresUnlock", false); startActivityForResult(intent, CODE_DECRYPT); } @@ -613,4 +607,11 @@ public class MainActivity extends AegisActivity implements EntryListView.Listene public void onScroll(int dx, int dy) { _fabScrollHelper.onScroll(dx, dy); } + + @Override + public void onLocked() { + _entryListView.clearEntries(); + _loaded = false; + super.onLocked(); + } }