Updated on 2026-08-14

This commit is contained in:
Tangem 2024-12-20 16:42:36 +04:00
parent cff20ef515
commit 29df79b1c2
4 changed files with 73 additions and 12 deletions

View file

@ -2,7 +2,7 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<uses-permission android:name="android.permission.HIDE_OVERLAY_WINDOWS" />
<!--<uses-permission android:name="android.permission.HIDE_OVERLAY_WINDOWS" />-->
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.NFC" />
<uses-permission android:name="android.permission.INTERNET" />

View file

@ -32,6 +32,8 @@ import com.google.android.material.snackbar.Snackbar
import com.tangem.common.routing.AppRoute
import com.tangem.common.routing.entity.SerializableIntent
import com.tangem.core.analytics.api.AnalyticsEventHandler
import com.tangem.core.analytics.models.event.TechAnalyticsEvent
import com.tangem.core.analytics.models.event.TechAnalyticsEvent.WindowObscured.ObscuredState
import com.tangem.core.decompose.context.AppComponentContext
import com.tangem.core.decompose.di.RootAppComponentContext
import com.tangem.core.deeplink.DeepLinksRegistry
@ -222,6 +224,9 @@ class MainActivity : AppCompatActivity(), SnackbarHandler, ActivityResultCallbac
private val onActivityResultCallbacks = mutableListOf<OnActivityResultCallback>()
private var isWindowPartiallyObscuredAlreadySent: Boolean = false
private var isWindowFullyObscuredAlreadySent: Boolean = false
override fun onCreate(savedInstanceState: Bundle?) {
// We need to call it before onCreate to prevent unnecessary activity recreation
installAppTheme()
@ -246,9 +251,9 @@ class MainActivity : AppCompatActivity(), SnackbarHandler, ActivityResultCallbac
window.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING)
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) {
window.setHideOverlayWindows(true)
}
// if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) {
// window.setHideOverlayWindows(true)
// }
splashScreen.setKeepOnScreenCondition { viewModel.isSplashScreenShown }
@ -530,10 +535,31 @@ class MainActivity : AppCompatActivity(), SnackbarHandler, ActivityResultCallbac
false
}
if (isPartiallyObscured) {
Timber.d("Window is partially obscured")
if (!isWindowPartiallyObscuredAlreadySent) {
analyticsEventsHandler.send(
event = TechAnalyticsEvent.WindowObscured(state = ObscuredState.PARTIALLY),
)
isWindowPartiallyObscuredAlreadySent = true
}
}
val isFullyObscured = event.flags and MotionEvent.FLAG_WINDOW_IS_OBSCURED != 0
if (isPartiallyObscured || isFullyObscured) {
Timber.e("Window is partially or fully obscured")
if (isFullyObscured) {
Timber.d("Window is partially or fully obscured")
if (!isWindowFullyObscuredAlreadySent) {
analyticsEventsHandler.send(
event = TechAnalyticsEvent.WindowObscured(state = ObscuredState.FULLY),
)
isWindowFullyObscuredAlreadySent = true
}
return false
}

View file

@ -0,0 +1,26 @@
package com.tangem.core.analytics.models.event
import com.tangem.core.analytics.models.AnalyticsEvent
/**
* Tech analytics event
*
* @param event event name
* @param params params
*/
sealed class TechAnalyticsEvent(
event: String,
params: Map<String, String> = mapOf(),
) : AnalyticsEvent(category = "Tech", event = event, params = params) {
class WindowObscured(state: ObscuredState) : TechAnalyticsEvent(
event = "Window Obscured",
params = mapOf("State" to state.name),
) {
enum class ObscuredState {
PARTIALLY,
FULLY,
}
}
}

View file

@ -47,11 +47,16 @@ import java.nio.charset.StandardCharsets
@Composable
internal fun DisclaimerScreen(state: DisclaimerUM) {
val bottomBarHeight = with(LocalDensity.current) { WindowInsets.systemBars.getBottom(this).toDp() }
val bottomPadding = bottomBarHeight + TangemTheme.dimens.size16
val bottomPadding = if (state.isTosAccepted) {
bottomBarHeight + TangemTheme.dimens.size16
} else {
bottomBarHeight + TangemTheme.dimens.size64
}
val backgroundColor = TangemTheme.colors.background.primary
val (textColor, iconColor) = TangemTheme.colors.text.primary1 to TangemTheme.colors.icon.primary1
Box(
modifier = Modifier
.background(TangemTheme.colors.background.primary)
.background(backgroundColor)
.statusBarsPadding()
.testTag(DISCLAIMER_SCREEN_CONTAINER),
) {
@ -67,6 +72,8 @@ internal fun DisclaimerScreen(state: DisclaimerUM) {
onIconClicked = state.popBack,
).takeIf { state.isTosAccepted },
titleAlignment = Alignment.CenterHorizontally,
textColor = textColor,
iconTint = iconColor,
)
DisclaimerContent(state.url)
}
@ -74,7 +81,7 @@ internal fun DisclaimerScreen(state: DisclaimerUM) {
if (!state.isTosAccepted) {
BottomFade(
modifier = Modifier.align(Alignment.BottomCenter),
backgroundColor = TangemTheme.colors.background.primary,
backgroundColor = backgroundColor,
)
DisclaimerButton(state.onAccept)
} else {
@ -85,6 +92,8 @@ internal fun DisclaimerScreen(state: DisclaimerUM) {
@Composable
private fun DisclaimerContent(url: String) {
val backgroundColor = TangemTheme.colors.background.primary
val webViewStateUrl = rememberWebViewState(url)
val webViewStateData = rememberWebViewStateWithHTMLData(
data = localTermsOfServices,
@ -119,12 +128,12 @@ private fun DisclaimerContent(url: String) {
exit = fadeOut(),
modifier = Modifier
.fillMaxSize()
.background(TangemTheme.colors.background.primary),
.background(backgroundColor),
) {
Box(
modifier = Modifier
.fillMaxSize()
.background(TangemTheme.colors.background.primary),
.background(backgroundColor),
) {
CircularProgressIndicator(
color = TangemTheme.colors.icon.informative,