Skip to content

Commit

Permalink
Merge pull request beemdevelopment#564 from alexbakker/improve-auto-lock
Browse files Browse the repository at this point in the history
Improve auto lock and make it more customizable
  • Loading branch information
michaelschattgen committed Aug 26, 2020
2 parents 0cdb882 + d875cb6 commit 52d2713
Show file tree
Hide file tree
Showing 28 changed files with 146 additions and 88 deletions.
1 change: 1 addition & 0 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ dependencies {
implementation 'androidx.cardview:cardview:1.0.0'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
implementation 'androidx.documentfile:documentfile:1.0.1'
implementation "androidx.lifecycle:lifecycle-process:2.2.0"
implementation 'androidx.preference:preference:1.1.1'
implementation 'androidx.recyclerview:recyclerview:1.1.0'
implementation "androidx.viewpager2:viewpager2:1.0.0"
Expand Down
41 changes: 33 additions & 8 deletions app/src/main/java/com/beemdevelopment/aegis/AegisApplication.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,12 @@
import android.graphics.drawable.Icon;
import android.os.Build;

import androidx.annotation.NonNull;
import androidx.annotation.RequiresApi;
import androidx.lifecycle.Lifecycle;
import androidx.lifecycle.LifecycleEventObserver;
import androidx.lifecycle.LifecycleOwner;
import androidx.lifecycle.ProcessLifecycleOwner;

import com.beemdevelopment.aegis.services.NotificationService;
import com.beemdevelopment.aegis.ui.MainActivity;
Expand Down Expand Up @@ -53,6 +58,9 @@ public void onCreate() {
intentFilter.addAction(CODE_LOCK_VAULT_ACTION);
registerReceiver(receiver, intentFilter);

// lock the app if the user moves the application to the background
ProcessLifecycleOwner.get().getLifecycle().addObserver(new AppLifecycleObserver());

if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.N_MR1) {
initAppShortcuts();
}
Expand Down Expand Up @@ -111,8 +119,8 @@ public Preferences getPreferences() {
return _prefs;
}

public boolean isAutoLockEnabled() {
return _prefs.isAutoLockEnabled() && !isVaultLocked() && _manager.isEncryptionEnabled() ;
public boolean isAutoLockEnabled(int autoLockType) {
return _prefs.isAutoLockTypeEnabled(autoLockType) && !isVaultLocked() && _manager.isEncryptionEnabled();
}

public void registerLockListener(LockListener listener) {
Expand All @@ -123,10 +131,14 @@ public void unregisterLockListener(LockListener listener) {
_lockListeners.remove(listener);
}

public void lock() {
/**
* Locks the vault and the app.
* @param userInitiated whether or not the user initiated the lock in MainActivity.
*/
public void lock(boolean userInitiated) {
_manager = null;
for (LockListener listener : _lockListeners) {
listener.onLocked();
listener.onLocked(userInitiated);
}

stopService(new Intent(AegisApplication.this, NotificationService.class));
Expand Down Expand Up @@ -168,16 +180,29 @@ private void initNotificationChannels() {
}
}

public class ScreenOffReceiver extends BroadcastReceiver {
private class AppLifecycleObserver implements LifecycleEventObserver {
@Override
public void onStateChanged(@NonNull LifecycleOwner source, @NonNull Lifecycle.Event event) {
if (event == Lifecycle.Event.ON_STOP && isAutoLockEnabled(Preferences.AUTO_LOCK_ON_MINIMIZE)) {
lock(false);
}
}
}

private class ScreenOffReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
if (isAutoLockEnabled()) {
lock();
if (isAutoLockEnabled(Preferences.AUTO_LOCK_ON_DEVICE_LOCK)) {
lock(false);
}
}
}

public interface LockListener {
void onLocked();
/**
* When called, the app/vault has been locked and the listener should perform its cleanup operations.
* @param userInitiated whether or not the user initiated the lock in MainActivity.
*/
void onLocked(boolean userInitiated);
}
}
7 changes: 0 additions & 7 deletions app/src/main/java/com/beemdevelopment/aegis/CancelAction.java

This file was deleted.

30 changes: 29 additions & 1 deletion app/src/main/java/com/beemdevelopment/aegis/Preferences.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,17 @@
import java.util.concurrent.TimeUnit;

public class Preferences {
public static final int AUTO_LOCK_OFF = 1 << 0;
public static final int AUTO_LOCK_ON_BACK_BUTTON = 1 << 1;
public static final int AUTO_LOCK_ON_MINIMIZE = 1 << 2;
public static final int AUTO_LOCK_ON_DEVICE_LOCK = 1 << 3;

public static final int[] AUTO_LOCK_SETTINGS = {
AUTO_LOCK_ON_BACK_BUTTON,
AUTO_LOCK_ON_MINIMIZE,
AUTO_LOCK_ON_DEVICE_LOCK
};

private SharedPreferences _prefs;

public Preferences(Context context) {
Expand Down Expand Up @@ -73,8 +84,25 @@ public boolean isIntroDone() {
return _prefs.getBoolean("pref_intro", false);
}

private int getAutoLockMask() {
final int def = AUTO_LOCK_ON_BACK_BUTTON | AUTO_LOCK_ON_DEVICE_LOCK;
if (!_prefs.contains("pref_auto_lock_mask")) {
return _prefs.getBoolean("pref_auto_lock", true) ? def : AUTO_LOCK_OFF;
}

return _prefs.getInt("pref_auto_lock_mask", def);
}

public boolean isAutoLockEnabled() {
return _prefs.getBoolean("pref_auto_lock", true);
return getAutoLockMask() != AUTO_LOCK_OFF;
}

public boolean isAutoLockTypeEnabled(int autoLockType) {
return (getAutoLockMask() & autoLockType) == autoLockType;
}

public void setAutoLockMask(int autoLock) {
_prefs.edit().putInt("pref_auto_lock_mask", autoLock).apply();
}

public void setIntroDone(boolean done) {
Expand Down
32 changes: 4 additions & 28 deletions app/src/main/java/com/beemdevelopment/aegis/ui/AegisActivity.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
import android.view.WindowManager;
import android.widget.Toast;

import androidx.annotation.CallSuper;
import androidx.appcompat.app.AppCompatActivity;

import com.beemdevelopment.aegis.AegisApplication;
Expand All @@ -20,9 +19,7 @@
import java.util.Map;

public abstract class AegisActivity extends AppCompatActivity implements AegisApplication.LockListener {
private boolean _resumed;
private AegisApplication _app;
private Theme _configuredTheme;

@Override
protected void onCreate(Bundle savedInstanceState) {
Expand All @@ -39,6 +36,7 @@ protected void onCreate(Bundle savedInstanceState) {
Intent intent = new Intent(this, MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
startActivity(intent);
finish();
return;
}

Expand All @@ -58,24 +56,9 @@ protected void onDestroy() {
}

@Override
protected void onResume() {
super.onResume();
_resumed = true;
}

@Override
protected void onPause() {
super.onPause();
_resumed = false;
}

@CallSuper
@Override
public void onLocked() {
if (isOrphan()) {
setResult(RESULT_CANCELED, null);
finish();
}
public void onLocked(boolean userInitiated) {
setResult(RESULT_CANCELED, null);
finishAndRemoveTask();
}

protected AegisApplication getApp() {
Expand Down Expand Up @@ -139,13 +122,6 @@ protected boolean saveVault(boolean backup) {
}
}

/**
* Reports whether this Activity has been resumed. (i.e. onResume was called)
*/
protected boolean isOpen() {
return _resumed;
}

/**
* 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.
Expand Down
15 changes: 5 additions & 10 deletions app/src/main/java/com/beemdevelopment/aegis/ui/AuthActivity.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@
import androidx.biometric.BiometricPrompt;

import com.beemdevelopment.aegis.AegisApplication;
import com.beemdevelopment.aegis.CancelAction;
import com.beemdevelopment.aegis.Preferences;
import com.beemdevelopment.aegis.R;
import com.beemdevelopment.aegis.ThemeMap;
Expand Down Expand Up @@ -52,17 +51,15 @@
public class AuthActivity extends AegisActivity {
private EditText _textPassword;

private CancelAction _cancelAction;
private SlotList _slots;

private SecretKey _bioKey;
private BiometricSlot _bioSlot;
private BiometricPrompt _bioPrompt;

private int _failedUnlockAttempts;

// the first time this activity is resumed after creation, it's possible to inhibit showing the
// biometric prompt by setting 'inhibitBioPrompt' to false through the intent
// biometric prompt by setting 'inhibitBioPrompt' to true through the intent
private boolean _inhibitBioPrompt;

private Preferences _prefs;
Expand Down Expand Up @@ -95,7 +92,6 @@ protected void onCreate(Bundle savedInstanceState) {
} else {
_inhibitBioPrompt = savedInstanceState.getBoolean("inhibitBioPrompt", false);
}
_cancelAction = (CancelAction) intent.getSerializableExtra("cancelAction");
_slots = (SlotList) intent.getSerializableExtra("slots");
_stateless = _slots != null;
if (!_stateless) {
Expand Down Expand Up @@ -183,11 +179,10 @@ private void selectPassword() {

@Override
public void onBackPressed() {
switch (_cancelAction) {
case KILL:
finishAffinity();
case CLOSE:
finish();
if (_stateless) {
super.onBackPressed();
} else {
finishAffinity();
}
}

Expand Down
17 changes: 8 additions & 9 deletions app/src/main/java/com/beemdevelopment/aegis/ui/MainActivity.java
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
import androidx.appcompat.widget.SearchView;

import com.beemdevelopment.aegis.AegisApplication;
import com.beemdevelopment.aegis.CancelAction;
import com.beemdevelopment.aegis.Preferences;
import com.beemdevelopment.aegis.R;
import com.beemdevelopment.aegis.SortCategory;
import com.beemdevelopment.aegis.ViewMode;
Expand Down Expand Up @@ -523,8 +523,8 @@ public void onBackPressed() {
return;
}

if (_app.isAutoLockEnabled()) {
_app.lock();
if (_app.isAutoLockEnabled(Preferences.AUTO_LOCK_ON_BACK_BUTTON)) {
_app.lock(false);
return;
}

Expand Down Expand Up @@ -596,7 +596,7 @@ public boolean onOptionsItemSelected(MenuItem item) {
return true;
}
case R.id.action_lock:
_app.lock();
_app.lock(true);
return true;
default:
if (item.getGroupId() == R.id.action_filter_group) {
Expand Down Expand Up @@ -655,7 +655,6 @@ private void loadEntries() {
private void startAuthActivity(boolean inhibitBioPrompt) {
if (!_isAuthenticating) {
Intent intent = new Intent(this, AuthActivity.class);
intent.putExtra("cancelAction", CancelAction.KILL);
intent.putExtra("inhibitBioPrompt", inhibitBioPrompt);
startActivityForResult(intent, CODE_DECRYPT);
_isAuthenticating = true;
Expand Down Expand Up @@ -747,19 +746,19 @@ public void onScroll(int dx, int dy) {
public void onListChange() { _fabScrollHelper.setVisible(true); }

@Override
public void onLocked() {
public void onLocked(boolean userInitiated) {
if (_actionMode != null) {
_actionMode.finish();
}

_entryListView.clearEntries();
_loaded = false;

if (isOpen()) {
if (userInitiated) {
startAuthActivity(true);
} else {
super.onLocked(userInitiated);
}

super.onLocked();
}

private void copyEntryCode(VaultEntry entry) {
Expand Down
Loading

0 comments on commit 52d2713

Please sign in to comment.