Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve auto lock and make it more customizable #564

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 @@ -182,11 +178,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