mirror of
https://github.com/signalapp/Signal-Android.git
synced 2026-07-04 04:55:16 +01:00
Block screen recording during registration by applying FLAG_SECURE.
Co-authored-by: Greyson Parrelli <greyson@signal.org>
This commit is contained in:
committed by
Greyson Parrelli
parent
d91f130238
commit
370fca3c89
+3
@@ -43,6 +43,7 @@ import org.signal.core.models.AccountEntropyPool
|
||||
import org.signal.core.ui.compose.Buttons
|
||||
import org.signal.core.ui.compose.horizontalGutters
|
||||
import org.thoughtcrime.securesms.R
|
||||
import org.thoughtcrime.securesms.components.TemporaryScreenshotSecurity
|
||||
import org.thoughtcrime.securesms.fonts.MonoTypeface
|
||||
import org.thoughtcrime.securesms.registration.ui.restore.BackupKeyVisualTransformation
|
||||
import org.thoughtcrime.securesms.registration.ui.restore.attachBackupKeyAutoFillHelper
|
||||
@@ -59,6 +60,8 @@ fun EnterKeyScreen(
|
||||
captionContent: @Composable () -> Unit,
|
||||
seeKeyButton: @Composable () -> Unit
|
||||
) {
|
||||
TemporaryScreenshotSecurity.bind()
|
||||
|
||||
Column(
|
||||
verticalArrangement = Arrangement.SpaceBetween,
|
||||
modifier = Modifier
|
||||
|
||||
+3
@@ -59,6 +59,7 @@ import org.signal.core.ui.compose.horizontalGutters
|
||||
import org.signal.core.ui.compose.theme.SignalTheme
|
||||
import org.signal.core.util.Util
|
||||
import org.thoughtcrime.securesms.R
|
||||
import org.thoughtcrime.securesms.components.TemporaryScreenshotSecurity
|
||||
import org.thoughtcrime.securesms.components.settings.app.backups.remote.BackupKeyCredentialManagerHandler
|
||||
import org.thoughtcrime.securesms.components.settings.app.backups.remote.BackupKeySaveState
|
||||
import org.thoughtcrime.securesms.fonts.MonoTypeface
|
||||
@@ -133,6 +134,8 @@ fun MessageBackupsKeyRecordScreen(
|
||||
mode: MessageBackupsKeyRecordMode = MessageBackupsKeyRecordMode.Next(onNextClick = {}),
|
||||
notifyKeyIsSameAsOnDeviceBackupKey: Boolean = false
|
||||
) {
|
||||
TemporaryScreenshotSecurity.bind()
|
||||
|
||||
val snackbarHostState = remember { SnackbarHostState() }
|
||||
val backupKeyString = remember(backupKey) {
|
||||
backupKey.chunked(4).joinToString(" ")
|
||||
|
||||
+47
-8
@@ -5,18 +5,41 @@
|
||||
|
||||
package org.thoughtcrime.securesms.components
|
||||
|
||||
import android.view.Window
|
||||
import android.view.WindowManager
|
||||
import androidx.activity.ComponentActivity
|
||||
import androidx.activity.compose.LocalActivity
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.DisposableEffect
|
||||
import androidx.fragment.app.Fragment
|
||||
import androidx.lifecycle.DefaultLifecycleObserver
|
||||
import androidx.lifecycle.LifecycleOwner
|
||||
import org.thoughtcrime.securesms.util.TextSecurePreferences
|
||||
import java.util.WeakHashMap
|
||||
|
||||
/**
|
||||
* Applies temporary screenshot security for the given component lifecycle.
|
||||
*
|
||||
* Multiple callers can request security on the same window concurrently; the
|
||||
* flag is only cleared once every caller has released its hold.
|
||||
*/
|
||||
object TemporaryScreenshotSecurity {
|
||||
|
||||
private val activeHolds = WeakHashMap<Window, Int>()
|
||||
|
||||
@Composable
|
||||
fun bind() {
|
||||
val activity = LocalActivity.current as? ComponentActivity ?: return
|
||||
|
||||
DisposableEffect(activity) {
|
||||
acquire(activity)
|
||||
|
||||
onDispose {
|
||||
release(activity)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun bindToViewLifecycleOwner(fragment: Fragment) {
|
||||
val observer = LifecycleObserver { fragment.requireActivity() }
|
||||
@@ -31,21 +54,37 @@ object TemporaryScreenshotSecurity {
|
||||
activity.lifecycle.addObserver(observer)
|
||||
}
|
||||
|
||||
private fun acquire(activity: ComponentActivity) {
|
||||
val window = activity.window
|
||||
val previous = activeHolds[window] ?: 0
|
||||
activeHolds[window] = previous + 1
|
||||
if (previous == 0 && !TextSecurePreferences.isScreenSecurityEnabled(activity)) {
|
||||
window.addFlags(WindowManager.LayoutParams.FLAG_SECURE)
|
||||
}
|
||||
}
|
||||
|
||||
private fun release(activity: ComponentActivity) {
|
||||
val window = activity.window
|
||||
val next = ((activeHolds[window] ?: 0) - 1).coerceAtLeast(0)
|
||||
if (next == 0) {
|
||||
activeHolds.remove(window)
|
||||
if (!TextSecurePreferences.isScreenSecurityEnabled(activity)) {
|
||||
window.clearFlags(WindowManager.LayoutParams.FLAG_SECURE)
|
||||
}
|
||||
} else {
|
||||
activeHolds[window] = next
|
||||
}
|
||||
}
|
||||
|
||||
private class LifecycleObserver(
|
||||
private val activityProvider: () -> ComponentActivity
|
||||
) : DefaultLifecycleObserver {
|
||||
override fun onResume(owner: LifecycleOwner) {
|
||||
val activity = activityProvider()
|
||||
if (!TextSecurePreferences.isScreenSecurityEnabled(activity)) {
|
||||
activity.window.addFlags(WindowManager.LayoutParams.FLAG_SECURE)
|
||||
}
|
||||
acquire(activityProvider())
|
||||
}
|
||||
|
||||
override fun onPause(owner: LifecycleOwner) {
|
||||
val activity = activityProvider()
|
||||
if (!TextSecurePreferences.isScreenSecurityEnabled(activity)) {
|
||||
activity.window.clearFlags(WindowManager.LayoutParams.FLAG_SECURE)
|
||||
}
|
||||
release(activityProvider())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,7 +12,6 @@ import androidx.activity.viewModels
|
||||
import androidx.lifecycle.DefaultLifecycleObserver
|
||||
import androidx.lifecycle.LifecycleOwner
|
||||
import androidx.navigation.ActivityNavigator
|
||||
import org.signal.core.util.logging.Log
|
||||
import org.thoughtcrime.securesms.BaseActivity
|
||||
import org.thoughtcrime.securesms.MainActivity
|
||||
import org.thoughtcrime.securesms.R
|
||||
@@ -26,8 +25,6 @@ import org.thoughtcrime.securesms.util.DynamicNoActionBarTheme
|
||||
*/
|
||||
class RegistrationActivity : BaseActivity() {
|
||||
|
||||
private val TAG = Log.tag(RegistrationActivity::class.java)
|
||||
|
||||
private val dynamicTheme = DynamicNoActionBarTheme()
|
||||
val sharedViewModel: RegistrationViewModel by viewModels()
|
||||
|
||||
|
||||
+3
@@ -57,6 +57,7 @@ import org.signal.core.ui.compose.Previews
|
||||
import org.signal.core.ui.compose.horizontalGutters
|
||||
import org.thoughtcrime.securesms.R
|
||||
import org.thoughtcrime.securesms.backup.v2.ui.BackupsIconColors
|
||||
import org.thoughtcrime.securesms.components.TemporaryScreenshotSecurity
|
||||
import org.thoughtcrime.securesms.fonts.MonoTypeface
|
||||
import org.thoughtcrime.securesms.registration.ui.shared.RegistrationScreen
|
||||
|
||||
@@ -78,6 +79,8 @@ fun EnterBackupKeyScreen(
|
||||
onSkip: () -> Unit = {},
|
||||
dialogContent: @Composable () -> Unit
|
||||
) {
|
||||
TemporaryScreenshotSecurity.bind()
|
||||
|
||||
val coroutineScope = rememberCoroutineScope()
|
||||
val sheetState = rememberModalBottomSheetState(
|
||||
skipPartiallyExpanded = true
|
||||
|
||||
+3
@@ -36,6 +36,7 @@ import org.signal.core.ui.compose.CircularProgressWrapper
|
||||
import org.signal.core.ui.compose.DayNightPreviews
|
||||
import org.signal.core.ui.compose.Previews
|
||||
import org.thoughtcrime.securesms.R
|
||||
import org.thoughtcrime.securesms.components.TemporaryScreenshotSecurity
|
||||
import org.thoughtcrime.securesms.fonts.MonoTypeface
|
||||
import org.thoughtcrime.securesms.registration.data.network.RegisterAccountResult
|
||||
import org.thoughtcrime.securesms.registration.ui.restore.AccountEntropyPoolVerification
|
||||
@@ -59,6 +60,8 @@ fun EnterLocalBackupKeyScreen(
|
||||
onRegistrationErrorDismiss: () -> Unit = {},
|
||||
onBackupKeyHelp: () -> Unit = {}
|
||||
) {
|
||||
TemporaryScreenshotSecurity.bind()
|
||||
|
||||
val visualTransform = remember { BackupKeyVisualTransformation(chunkSize = 4) }
|
||||
val keyboardController = LocalSoftwareKeyboardController.current
|
||||
val focusRequester = remember { FocusRequester() }
|
||||
|
||||
Reference in New Issue
Block a user