Limit app lock to notification logs
This commit is contained in:
@@ -31,6 +31,7 @@ class MainActivity : AppCompatActivity(), NavigationView.OnNavigationItemSelecte
|
|||||||
private lateinit var drawerToggle: ActionBarDrawerToggle
|
private lateinit var drawerToggle: ActionBarDrawerToggle
|
||||||
private var permanentSidebar = false
|
private var permanentSidebar = false
|
||||||
private var needsUnlock = true
|
private var needsUnlock = true
|
||||||
|
private var unlockInProgress = false
|
||||||
private lateinit var appLockStore: AppLockStore
|
private lateinit var appLockStore: AppLockStore
|
||||||
private var currentItemId = R.id.nav_view_logs
|
private var currentItemId = R.id.nav_view_logs
|
||||||
private var drawerNavigationBasePaddingLeft: Int? = null
|
private var drawerNavigationBasePaddingLeft: Int? = null
|
||||||
@@ -39,12 +40,10 @@ class MainActivity : AppCompatActivity(), NavigationView.OnNavigationItemSelecte
|
|||||||
override fun onCreate(savedInstanceState: Bundle?) {
|
override fun onCreate(savedInstanceState: Bundle?) {
|
||||||
super.onCreate(savedInstanceState)
|
super.onCreate(savedInstanceState)
|
||||||
appLockStore = AppLockStore(this)
|
appLockStore = AppLockStore(this)
|
||||||
updateSensitiveWindowPolicy(appLockStore.enabled)
|
|
||||||
// Keep every app surface below the system bars rather than relying on edge-to-edge drawing.
|
// Keep every app surface below the system bars rather than relying on edge-to-edge drawing.
|
||||||
WindowCompat.setDecorFitsSystemWindows(window, true)
|
WindowCompat.setDecorFitsSystemWindows(window, true)
|
||||||
binding = ActivityMainBinding.inflate(layoutInflater)
|
binding = ActivityMainBinding.inflate(layoutInflater)
|
||||||
setContentView(binding.root)
|
setContentView(binding.root)
|
||||||
showLockedOverlay(appLockStore.enabled)
|
|
||||||
val isNightMode = resources.configuration.uiMode and Configuration.UI_MODE_NIGHT_MASK ==
|
val isNightMode = resources.configuration.uiMode and Configuration.UI_MODE_NIGHT_MASK ==
|
||||||
Configuration.UI_MODE_NIGHT_YES
|
Configuration.UI_MODE_NIGHT_YES
|
||||||
WindowInsetsControllerCompat(window, binding.root).isAppearanceLightNavigationBars = !isNightMode
|
WindowInsetsControllerCompat(window, binding.root).isAppearanceLightNavigationBars = !isNightMode
|
||||||
@@ -90,33 +89,34 @@ class MainActivity : AppCompatActivity(), NavigationView.OnNavigationItemSelecte
|
|||||||
|
|
||||||
override fun onResume() {
|
override fun onResume() {
|
||||||
super.onResume()
|
super.onResume()
|
||||||
if (needsUnlock && appLockStore.enabled) {
|
refreshLogProtection(requestUnlock = true)
|
||||||
showLockedOverlay(true)
|
|
||||||
requestUnlock()
|
|
||||||
} else {
|
|
||||||
showLockedOverlay(false)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onStop() {
|
override fun onStop() {
|
||||||
super.onStop()
|
super.onStop()
|
||||||
if (!isChangingConfigurations) {
|
if (!isChangingConfigurations && isProtectedLogPage()) {
|
||||||
needsUnlock = true
|
needsUnlock = true
|
||||||
if (appLockStore.enabled) showLockedOverlay(true)
|
showLockedOverlay(true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun requestUnlock() {
|
private fun requestUnlock() {
|
||||||
|
if (!isProtectedLogPage() || !needsUnlock || unlockInProgress) return
|
||||||
|
unlockInProgress = true
|
||||||
BiometricPrompt.Builder(this)
|
BiometricPrompt.Builder(this)
|
||||||
.setTitle("Unlock Notifications Master")
|
.setTitle("Unlock notification logs")
|
||||||
.setAllowedAuthenticators(Authenticators.BIOMETRIC_STRONG or Authenticators.DEVICE_CREDENTIAL)
|
.setAllowedAuthenticators(Authenticators.BIOMETRIC_STRONG or Authenticators.DEVICE_CREDENTIAL)
|
||||||
.build()
|
.build()
|
||||||
.authenticate(CancellationSignal(), mainExecutor, object : BiometricPrompt.AuthenticationCallback() {
|
.authenticate(CancellationSignal(), mainExecutor, object : BiometricPrompt.AuthenticationCallback() {
|
||||||
override fun onAuthenticationSucceeded(result: BiometricPrompt.AuthenticationResult?) {
|
override fun onAuthenticationSucceeded(result: BiometricPrompt.AuthenticationResult?) {
|
||||||
needsUnlock = false
|
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. */
|
/** Called immediately when the Settings switch changes, before a task snapshot can be captured. */
|
||||||
fun setAppLockEnabled(enabled: Boolean) {
|
fun setAppLockEnabled(enabled: Boolean) {
|
||||||
appLockStore.enabled = enabled
|
appLockStore.enabled = enabled
|
||||||
updateSensitiveWindowPolicy(enabled)
|
needsUnlock = enabled
|
||||||
|
refreshLogProtection(requestUnlock = true)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun updateSensitiveWindowPolicy(locked: Boolean) {
|
private fun isProtectedLogPage() = appLockStore.enabled && currentItemId == R.id.nav_view_logs
|
||||||
setRecentsScreenshotEnabled(!locked)
|
|
||||||
if (locked) window.addFlags(WindowManager.LayoutParams.FLAG_SECURE)
|
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)
|
else window.clearFlags(WindowManager.LayoutParams.FLAG_SECURE)
|
||||||
|
showLockedOverlay(protectedLogs && needsUnlock)
|
||||||
|
if (protectedLogs && needsUnlock && requestUnlock) binding.root.post(::requestUnlock)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onNavigationItemSelected(item: MenuItem): Boolean {
|
override fun onNavigationItemSelected(item: MenuItem): Boolean {
|
||||||
@@ -146,6 +152,7 @@ class MainActivity : AppCompatActivity(), NavigationView.OnNavigationItemSelecte
|
|||||||
|
|
||||||
private fun navigateTo(itemId: Int) {
|
private fun navigateTo(itemId: Int) {
|
||||||
currentItemId = itemId
|
currentItemId = itemId
|
||||||
|
refreshLogProtection(requestUnlock = hasWindowFocus())
|
||||||
syncDrawerSelection(itemId)
|
syncDrawerSelection(itemId)
|
||||||
val page = Page.fromMenuItem(itemId)
|
val page = Page.fromMenuItem(itemId)
|
||||||
supportFragmentManager.commit {
|
supportFragmentManager.commit {
|
||||||
|
|||||||
@@ -81,7 +81,7 @@
|
|||||||
<TextView
|
<TextView
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:text="Notifications Master is locked"
|
android:text="Notification logs are locked"
|
||||||
android:textAppearance="?attr/textAppearanceHeadline6" />
|
android:textAppearance="?attr/textAppearanceHeadline6" />
|
||||||
</LinearLayout>
|
</LinearLayout>
|
||||||
</FrameLayout>
|
</FrameLayout>
|
||||||
|
|||||||
@@ -33,7 +33,7 @@
|
|||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:layout_marginTop="24dp"
|
android:layout_marginTop="24dp"
|
||||||
android:text="Lock app with phone unlock" />
|
android:text="Lock logs with phone unlock" />
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:layout_width="match_parent"
|
android:layout_width="match_parent"
|
||||||
|
|||||||
Reference in New Issue
Block a user