SecureFlagEffect.kt
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}