Lock Android app on background for biometrics

This commit is contained in:
2026-04-23 15:07:16 -05:00
parent 5f27b1562e
commit d80d537d02
6 changed files with 33 additions and 6 deletions
+2 -2
View File
@@ -18,8 +18,8 @@ android {
applicationId "net.linkedcorp.linkedsign"
minSdk 26
targetSdk 35
versionCode 10204
versionName "1.2.4"
versionCode 10205
versionName "1.2.5"
buildConfigField "String", "API_BASE_URL", "\"${apiBaseUrl}\""
}
@@ -95,6 +95,7 @@ import androidx.compose.material3.TopAppBar
import androidx.compose.material3.TopAppBarDefaults
import androidx.compose.material3.IconButton
import androidx.compose.runtime.Composable
import androidx.compose.runtime.DisposableEffect
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
@@ -113,6 +114,9 @@ import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.layout.onSizeChanged
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.platform.LocalContext
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleEventObserver
import androidx.lifecycle.compose.LocalLifecycleOwner
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.input.KeyboardType
import androidx.compose.ui.text.input.PasswordVisualTransformation
@@ -209,6 +213,7 @@ fun LinkedSignApp(viewModel: MainViewModel, appContext: Context, activity: Compo
var selectedTab by rememberSaveable { mutableStateOf(AppTab.Documents) }
var pendingSignDocumentId by rememberSaveable { mutableStateOf<String?>(null) }
val biometricAvailable = remember(activity) { canUseBiometricAccess(activity) }
val lifecycleOwner = LocalLifecycleOwner.current
var appUnlocked by rememberSaveable { mutableStateOf(false) }
var bootstrapGateHandled by rememberSaveable { mutableStateOf(false) }
var showBiometricOptIn by rememberSaveable { mutableStateOf(false) }
@@ -235,6 +240,23 @@ fun LinkedSignApp(viewModel: MainViewModel, appContext: Context, activity: Compo
}
}
DisposableEffect(lifecycleOwner, biometricAvailable, state.biometricEnabled, state.biometricHasCredentials) {
val observer = LifecycleEventObserver { _, event ->
if (event == Lifecycle.Event.ON_STOP &&
biometricAvailable &&
state.biometricEnabled &&
state.biometricHasCredentials
) {
appUnlocked = false
}
}
lifecycleOwner.lifecycle.addObserver(observer)
onDispose {
lifecycleOwner.lifecycle.removeObserver(observer)
}
}
Scaffold(
modifier = Modifier.pointerInput(state.authenticated) {
if (!state.authenticated) return@pointerInput