diff --git a/app/src/main/java/se/ajpanton/notificationsmaster/MainActivity.kt b/app/src/main/java/se/ajpanton/notificationsmaster/MainActivity.kt index c4a1a4f..1324a5a 100644 --- a/app/src/main/java/se/ajpanton/notificationsmaster/MainActivity.kt +++ b/app/src/main/java/se/ajpanton/notificationsmaster/MainActivity.kt @@ -31,6 +31,7 @@ class MainActivity : AppCompatActivity(), NavigationView.OnNavigationItemSelecte private lateinit var drawerToggle: ActionBarDrawerToggle private var permanentSidebar = false private var needsUnlock = true + private var unlockInProgress = false private lateinit var appLockStore: AppLockStore private var currentItemId = R.id.nav_view_logs private var drawerNavigationBasePaddingLeft: Int? = null @@ -39,12 +40,10 @@ class MainActivity : AppCompatActivity(), NavigationView.OnNavigationItemSelecte override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) appLockStore = AppLockStore(this) - updateSensitiveWindowPolicy(appLockStore.enabled) // Keep every app surface below the system bars rather than relying on edge-to-edge drawing. WindowCompat.setDecorFitsSystemWindows(window, true) binding = ActivityMainBinding.inflate(layoutInflater) setContentView(binding.root) - showLockedOverlay(appLockStore.enabled) val isNightMode = resources.configuration.uiMode and Configuration.UI_MODE_NIGHT_MASK == Configuration.UI_MODE_NIGHT_YES WindowInsetsControllerCompat(window, binding.root).isAppearanceLightNavigationBars = !isNightMode @@ -90,33 +89,34 @@ class MainActivity : AppCompatActivity(), NavigationView.OnNavigationItemSelecte override fun onResume() { super.onResume() - if (needsUnlock && appLockStore.enabled) { - showLockedOverlay(true) - requestUnlock() - } else { - showLockedOverlay(false) - } + refreshLogProtection(requestUnlock = true) } override fun onStop() { super.onStop() - if (!isChangingConfigurations) { + if (!isChangingConfigurations && isProtectedLogPage()) { needsUnlock = true - if (appLockStore.enabled) showLockedOverlay(true) + showLockedOverlay(true) } } private fun requestUnlock() { + if (!isProtectedLogPage() || !needsUnlock || unlockInProgress) return + unlockInProgress = true BiometricPrompt.Builder(this) - .setTitle("Unlock Notifications Master") + .setTitle("Unlock notification logs") .setAllowedAuthenticators(Authenticators.BIOMETRIC_STRONG or Authenticators.DEVICE_CREDENTIAL) .build() .authenticate(CancellationSignal(), mainExecutor, object : BiometricPrompt.AuthenticationCallback() { override fun onAuthenticationSucceeded(result: BiometricPrompt.AuthenticationResult?) { needsUnlock = false - showLockedOverlay(false) + unlockInProgress = false + refreshLogProtection() + } + override fun onAuthenticationError(errorCode: Int, errString: CharSequence?) { + unlockInProgress = false + if (isProtectedLogPage()) navigateTo(R.id.nav_alerts) } - override fun onAuthenticationError(errorCode: Int, errString: CharSequence?) { finishAndRemoveTask() } }) } @@ -127,13 +127,19 @@ class MainActivity : AppCompatActivity(), NavigationView.OnNavigationItemSelecte /** Called immediately when the Settings switch changes, before a task snapshot can be captured. */ fun setAppLockEnabled(enabled: Boolean) { appLockStore.enabled = enabled - updateSensitiveWindowPolicy(enabled) + needsUnlock = enabled + refreshLogProtection(requestUnlock = true) } - private fun updateSensitiveWindowPolicy(locked: Boolean) { - setRecentsScreenshotEnabled(!locked) - if (locked) window.addFlags(WindowManager.LayoutParams.FLAG_SECURE) + private fun isProtectedLogPage() = appLockStore.enabled && currentItemId == R.id.nav_view_logs + + private fun refreshLogProtection(requestUnlock: Boolean = false) { + val protectedLogs = isProtectedLogPage() + setRecentsScreenshotEnabled(!protectedLogs) + if (protectedLogs) window.addFlags(WindowManager.LayoutParams.FLAG_SECURE) else window.clearFlags(WindowManager.LayoutParams.FLAG_SECURE) + showLockedOverlay(protectedLogs && needsUnlock) + if (protectedLogs && needsUnlock && requestUnlock) binding.root.post(::requestUnlock) } override fun onNavigationItemSelected(item: MenuItem): Boolean { @@ -146,6 +152,7 @@ class MainActivity : AppCompatActivity(), NavigationView.OnNavigationItemSelecte private fun navigateTo(itemId: Int) { currentItemId = itemId + refreshLogProtection(requestUnlock = hasWindowFocus()) syncDrawerSelection(itemId) val page = Page.fromMenuItem(itemId) supportFragmentManager.commit { diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml index fd4008f..3ac64f6 100644 --- a/app/src/main/res/layout/activity_main.xml +++ b/app/src/main/res/layout/activity_main.xml @@ -81,7 +81,7 @@ diff --git a/app/src/main/res/layout/fragment_settings.xml b/app/src/main/res/layout/fragment_settings.xml index b110c11..8eec330 100644 --- a/app/src/main/res/layout/fragment_settings.xml +++ b/app/src/main/res/layout/fragment_settings.xml @@ -33,7 +33,7 @@ android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="24dp" - android:text="Lock app with phone unlock" /> + android:text="Lock logs with phone unlock" />