Updated on 2026-08-14
This commit is contained in:
parent
3306749ae5
commit
b98b66ff9f
6 changed files with 84 additions and 46 deletions
|
|
@ -31,6 +31,7 @@ import com.tangem.core.ui.message.EventMessageEffect
|
|||
import com.tangem.core.ui.res.LocalRootBackgroundColor
|
||||
import com.tangem.core.ui.res.LocalSnackbarHostState
|
||||
import com.tangem.core.ui.res.TangemTheme
|
||||
import com.tangem.core.ui.security.ProvideSecureFlagController
|
||||
import com.tangem.tap.routing.component.RoutingComponent
|
||||
import com.tangem.tap.routing.transitions.RoutingTransitionAnimationFactory
|
||||
|
||||
|
|
@ -52,39 +53,41 @@ internal fun RootContent(
|
|||
activity = context as Activity,
|
||||
uiDependencies = uiDependencies,
|
||||
) {
|
||||
val snackbarHostState = LocalSnackbarHostState.current
|
||||
ProvideSecureFlagController {
|
||||
val snackbarHostState = LocalSnackbarHostState.current
|
||||
|
||||
Box(Modifier.background(LocalRootBackgroundColor.current.value)) {
|
||||
Children(
|
||||
modifier = modifier,
|
||||
animation = childrenAnimation(backHandler = backHandler, onBack = onBack),
|
||||
stack = stack,
|
||||
) { child ->
|
||||
when (val instance = child.instance) {
|
||||
is RoutingComponent.Child.Initial -> Unit
|
||||
is RoutingComponent.Child.ComposableComponent -> {
|
||||
instance.component.Content(Modifier.fillMaxSize())
|
||||
}
|
||||
is RoutingComponent.Child.LegacyIntent -> {
|
||||
// TODO: Remove and use it's own router: [REDACTED_JIRA]
|
||||
LaunchedEffect(instance) {
|
||||
startActivity(context, instance.intent, Bundle.EMPTY)
|
||||
Box(Modifier.background(LocalRootBackgroundColor.current.value)) {
|
||||
Children(
|
||||
modifier = modifier,
|
||||
animation = childrenAnimation(backHandler = backHandler, onBack = onBack),
|
||||
stack = stack,
|
||||
) { child ->
|
||||
when (val instance = child.instance) {
|
||||
is RoutingComponent.Child.Initial -> Unit
|
||||
is RoutingComponent.Child.ComposableComponent -> {
|
||||
instance.component.Content(Modifier.fillMaxSize())
|
||||
}
|
||||
is RoutingComponent.Child.LegacyIntent -> {
|
||||
// TODO: Remove and use it's own router: [REDACTED_JIRA]
|
||||
LaunchedEffect(instance) {
|
||||
startActivity(context, instance.intent, Bundle.EMPTY)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
wcContent(Modifier.fillMaxSize())
|
||||
|
||||
hotAccessCodeContent(Modifier.fillMaxSize())
|
||||
|
||||
TangemSnackbarHost(
|
||||
modifier = Modifier
|
||||
.align(Alignment.BottomCenter)
|
||||
.navigationBarsPadding()
|
||||
.padding(all = 16.dp),
|
||||
hostState = snackbarHostState,
|
||||
)
|
||||
}
|
||||
|
||||
wcContent(Modifier.fillMaxSize())
|
||||
|
||||
hotAccessCodeContent(Modifier.fillMaxSize())
|
||||
|
||||
TangemSnackbarHost(
|
||||
modifier = Modifier
|
||||
.align(Alignment.BottomCenter)
|
||||
.navigationBarsPadding()
|
||||
.padding(all = 16.dp),
|
||||
hostState = snackbarHostState,
|
||||
)
|
||||
}
|
||||
EventMessageEffect()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,11 +1,53 @@
|
|||
package com.tangem.core.ui.security
|
||||
|
||||
import android.app.Activity
|
||||
import android.view.WindowManager
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.CompositionLocalProvider
|
||||
import androidx.compose.runtime.DisposableEffect
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableIntStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.runtime.staticCompositionLocalOf
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import com.tangem.core.ui.utils.findActivity
|
||||
import timber.log.Timber
|
||||
|
||||
private val LocalSecureFlagController = staticCompositionLocalOf<SecureFlagController> {
|
||||
error("No SecureFlagController provided")
|
||||
}
|
||||
|
||||
private class SecureFlagController(private val activity: Activity) {
|
||||
private var count by mutableIntStateOf(0)
|
||||
|
||||
fun enable() {
|
||||
if (count == 0) {
|
||||
activity.window.setFlags(
|
||||
WindowManager.LayoutParams.FLAG_SECURE,
|
||||
WindowManager.LayoutParams.FLAG_SECURE,
|
||||
)
|
||||
}
|
||||
count++
|
||||
}
|
||||
|
||||
fun disable() {
|
||||
count--
|
||||
if (count == 0) {
|
||||
activity.window.clearFlags(WindowManager.LayoutParams.FLAG_SECURE)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun ProvideSecureFlagController(content: @Composable () -> Unit) {
|
||||
val activity = LocalContext.current.findActivity()
|
||||
val controller = remember(activity) { SecureFlagController(activity) }
|
||||
|
||||
CompositionLocalProvider(
|
||||
LocalSecureFlagController provides controller,
|
||||
content = content,
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Disables screenshots for the current composition.
|
||||
|
|
@ -14,18 +56,10 @@ import timber.log.Timber
|
|||
*/
|
||||
@Composable
|
||||
fun DisableScreenshotsDisposableEffect() {
|
||||
val activity = LocalContext.current.findActivity()
|
||||
val secureFlagController = LocalSecureFlagController.current
|
||||
|
||||
DisposableEffect(activity) {
|
||||
Timber.d("Security mode: enabled")
|
||||
activity.window.setFlags(
|
||||
WindowManager.LayoutParams.FLAG_SECURE,
|
||||
WindowManager.LayoutParams.FLAG_SECURE,
|
||||
)
|
||||
|
||||
onDispose {
|
||||
Timber.d("Security mode: disabled")
|
||||
activity.window.clearFlags(WindowManager.LayoutParams.FLAG_SECURE)
|
||||
}
|
||||
DisposableEffect(secureFlagController) {
|
||||
secureFlagController.enable()
|
||||
onDispose { secureFlagController.disable() }
|
||||
}
|
||||
}
|
||||
|
|
@ -25,10 +25,7 @@ internal class AccessCodeComponent @AssistedInject constructor(
|
|||
override fun Content(modifier: Modifier) {
|
||||
val state by model.uiState.collectAsStateWithLifecycle()
|
||||
|
||||
if (!state.isConfirmMode) {
|
||||
DisableScreenshotsDisposableEffect()
|
||||
}
|
||||
|
||||
DisableScreenshotsDisposableEffect()
|
||||
AccessCode(
|
||||
modifier = modifier,
|
||||
state = state,
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
|||
import com.tangem.core.decompose.context.AppComponentContext
|
||||
import com.tangem.core.decompose.model.getOrCreateModel
|
||||
import com.tangem.core.ui.decompose.ComposableContentComponent
|
||||
import com.tangem.core.ui.security.DisableScreenshotsDisposableEffect
|
||||
import com.tangem.domain.models.wallet.UserWalletId
|
||||
import com.tangem.features.hotwallet.addexistingwallet.im.port.model.AddExistingWalletImportModel
|
||||
import com.tangem.features.hotwallet.addexistingwallet.im.port.ui.AddExistingWalletImportContent
|
||||
|
|
@ -22,6 +23,7 @@ internal class AddExistingWalletImportComponent @AssistedInject constructor(
|
|||
@Composable
|
||||
override fun Content(modifier: Modifier) {
|
||||
val state by model.uiState.collectAsStateWithLifecycle()
|
||||
DisableScreenshotsDisposableEffect()
|
||||
AddExistingWalletImportContent(
|
||||
state = state,
|
||||
modifier = modifier,
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ import androidx.lifecycle.compose.collectAsStateWithLifecycle
|
|||
import com.tangem.core.decompose.context.AppComponentContext
|
||||
import com.tangem.core.decompose.model.getOrCreateModel
|
||||
import com.tangem.core.ui.decompose.ComposableContentComponent
|
||||
import com.tangem.core.ui.security.DisableScreenshotsDisposableEffect
|
||||
import com.tangem.domain.models.wallet.UserWalletId
|
||||
import com.tangem.features.hotwallet.manualbackup.check.model.ManualBackupCheckModel
|
||||
import com.tangem.features.hotwallet.manualbackup.check.ui.ManualBackupCheckContent
|
||||
|
|
@ -22,6 +23,7 @@ internal class ManualBackupCheckComponent @AssistedInject constructor(
|
|||
@Composable
|
||||
override fun Content(modifier: Modifier) {
|
||||
val state by model.uiState.collectAsStateWithLifecycle()
|
||||
DisableScreenshotsDisposableEffect()
|
||||
ManualBackupCheckContent(
|
||||
state = state,
|
||||
modifier = modifier,
|
||||
|
|
|
|||
|
|
@ -63,7 +63,7 @@ internal class WalletActivationModel @Inject constructor(
|
|||
is WalletActivationRoute.ManualBackupCheck -> stackNavigation.pop()
|
||||
is WalletActivationRoute.ManualBackupCompleted -> Unit
|
||||
is WalletActivationRoute.SetAccessCode -> Unit
|
||||
is WalletActivationRoute.ConfirmAccessCode -> Unit
|
||||
is WalletActivationRoute.ConfirmAccessCode -> stackNavigation.pop()
|
||||
is WalletActivationRoute.PushNotifications -> Unit
|
||||
is WalletActivationRoute.SetupFinished -> Unit
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue