SecureFlagEffect.kt

1.6 KB · raw

1package com.peachpasswords.ui.components23import androidx.compose.runtime.Composable4import androidx.compose.runtime.DisposableEffect5import androidx.compose.ui.platform.LocalContext6import androidx.fragment.app.FragmentActivity7import com.peachpasswords.BuildConfig89/**10 * Acquires a reference-counted secure-window lease while this composable is in11 * the composition — blocking screenshots, screen recording, and the recents12 * thumbnail of screens that display secrets (MN-3: recovery words, export blob,13 * codex generation). Mirrors the inline effect EntryDetailScreen / NotesModeScreen14 * already use. The lease is safe when secret composables are nested.15 *16 * Skipped only when BuildConfig.DEBUG is true AND [QaFlags.disableSecureCaptureForQa]17 * was explicitly opted into (see that file) — automated visual QA needs to capture18 * these screens too. Always enforced in release builds regardless of the flag.19 */20@Composable21fun SecureFlagEffect() {22    val context = LocalContext.current23    DisposableEffect(Unit) {24        if (BuildConfig.DEBUG && QaFlags.disableSecureCaptureForQa) {25            return@DisposableEffect onDispose { }26        }27        val window = (context as? FragmentActivity)?.window28        // MainActivity installs a permanent release owner before Compose starts;29        // on debug builds this is a reference-counted lease. In either case a30        // child effect can never clear a sibling's or the activity's protection.31        window?.let(SecureWindowPolicy::acquire)32        onDispose {33            window?.let(SecureWindowPolicy::release)34        }35    }36}