Updated on 2026-08-14
This commit is contained in:
parent
58d57d7b85
commit
5b02239896
4 changed files with 130 additions and 2 deletions
|
|
@ -3,7 +3,10 @@ package com.tangem.tap.features.main
|
|||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import com.tangem.blockchainsdk.BlockchainSDKFactory
|
||||
import com.tangem.common.keyboard.KeyboardValidator
|
||||
import com.tangem.core.analytics.Analytics
|
||||
import com.tangem.core.analytics.api.AnalyticsEventHandler
|
||||
import com.tangem.core.analytics.models.event.TechAnalyticsEvent
|
||||
import com.tangem.core.decompose.di.GlobalUiMessageSender
|
||||
import com.tangem.core.decompose.ui.UiMessageSender
|
||||
import com.tangem.core.ui.R
|
||||
|
|
@ -44,8 +47,9 @@ internal class MainViewModel @Inject constructor(
|
|||
private val fetchStakingTokensUseCase: FetchStakingTokensUseCase,
|
||||
private val apiConfigsManager: ApiConfigsManager,
|
||||
private val fetchUserCountryUseCase: FetchUserCountryUseCase,
|
||||
@GlobalUiMessageSender
|
||||
private val messageSender: UiMessageSender,
|
||||
@GlobalUiMessageSender private val messageSender: UiMessageSender,
|
||||
private val keyboardValidator: KeyboardValidator,
|
||||
private val analyticsEventHandler: AnalyticsEventHandler,
|
||||
getBalanceHidingSettingsUseCase: GetBalanceHidingSettingsUseCase,
|
||||
) : ViewModel() {
|
||||
|
||||
|
|
@ -74,6 +78,8 @@ internal class MainViewModel @Inject constructor(
|
|||
fetchStakingTokens()
|
||||
|
||||
deleteDeprecatedLogsUseCase()
|
||||
|
||||
sendKeyboardIdentifierEvent()
|
||||
}
|
||||
|
||||
/** Loading the resources needed to run the application */
|
||||
|
|
@ -252,4 +258,24 @@ internal class MainViewModel @Inject constructor(
|
|||
private fun onBottomSheetDismissed() {
|
||||
listenToFlipsUseCase.changeUpdateEnabled(isUpdateEnabled = true)
|
||||
}
|
||||
|
||||
private fun sendKeyboardIdentifierEvent() {
|
||||
viewModelScope.launch {
|
||||
val keyboardId = keyboardValidator.getKeyboardId()
|
||||
|
||||
if (keyboardId != null) {
|
||||
Timber.d("Keyboard ID: https://play.google.com/store/apps/details?id=${keyboardId.getPackageName()}")
|
||||
|
||||
analyticsEventHandler.send(
|
||||
event = TechAnalyticsEvent.KeyboardIdentifier(
|
||||
id = keyboardId.value,
|
||||
packageName = keyboardId.getPackageName(),
|
||||
isTrusted = keyboardValidator.validate(id = keyboardId),
|
||||
),
|
||||
)
|
||||
} else {
|
||||
Timber.e("Unable to get keyboard identifier")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,6 +1,8 @@
|
|||
plugins {
|
||||
alias(deps.plugins.android.library)
|
||||
alias(deps.plugins.kotlin.android)
|
||||
alias(deps.plugins.kotlin.kapt)
|
||||
alias(deps.plugins.hilt.android)
|
||||
id("configuration")
|
||||
}
|
||||
|
||||
|
|
@ -25,4 +27,9 @@ dependencies {
|
|||
|
||||
implementation(deps.test.junit)
|
||||
implementation(deps.test.truth)
|
||||
|
||||
// region DI
|
||||
implementation(deps.hilt.android)
|
||||
kapt(deps.hilt.kapt)
|
||||
// end
|
||||
}
|
||||
|
|
@ -0,0 +1,83 @@
|
|||
package com.tangem.common.keyboard
|
||||
|
||||
import android.content.Context
|
||||
import android.provider.Settings
|
||||
import dagger.hilt.android.qualifiers.ApplicationContext
|
||||
import javax.inject.Inject
|
||||
import javax.inject.Singleton
|
||||
|
||||
/**
|
||||
* Keyboard validator
|
||||
*
|
||||
* @property context application context
|
||||
*/
|
||||
@Singleton
|
||||
class KeyboardValidator @Inject constructor(
|
||||
@ApplicationContext private val context: Context,
|
||||
) {
|
||||
|
||||
/** Get keyboard identifier [KeyboardID] */
|
||||
fun getKeyboardId(): KeyboardID? {
|
||||
val id = Settings.Secure.getString(
|
||||
this.context.contentResolver,
|
||||
Settings.Secure.DEFAULT_INPUT_METHOD,
|
||||
) ?: return null
|
||||
|
||||
return KeyboardID(value = id)
|
||||
}
|
||||
|
||||
/** Check if [id] is trusted */
|
||||
fun validate(id: KeyboardID): Boolean = trustedIdentifiers.contains(id.getPackageName())
|
||||
|
||||
/**
|
||||
* Keyboard identifier
|
||||
*
|
||||
* @property value value
|
||||
*/
|
||||
@JvmInline
|
||||
value class KeyboardID(val value: String) {
|
||||
|
||||
/** Get package name */
|
||||
fun getPackageName(): String? = value.split("/").firstOrNull()
|
||||
}
|
||||
|
||||
private companion object {
|
||||
|
||||
val trustedIdentifiers = listOf(
|
||||
// Google
|
||||
"com.android.inputmethod.latin",
|
||||
"com.google.android.inputmethod.latin",
|
||||
"com.google.android.tts",
|
||||
|
||||
// Samsung
|
||||
"com.sec.android.inputmethod.latin",
|
||||
"com.sec.android.inputmethod/.SamsungVoiceIME",
|
||||
"com.samsung.android.honeyboard",
|
||||
|
||||
// Microsoft
|
||||
"com.microsoft.SwiftKeyApp",
|
||||
"com.touchtype.swiftkey",
|
||||
"com.touchtype.swiftkey.beta",
|
||||
|
||||
// HtC
|
||||
"com.htc.sense.ime.langpack.tger",
|
||||
|
||||
// LG
|
||||
"com.lge.ime",
|
||||
|
||||
// Huawei
|
||||
"com.huawei.ohos.inputmethod",
|
||||
|
||||
// Third party
|
||||
"com.menny.android.anysoftkeyboard",
|
||||
"ch.icoaching.wrio",
|
||||
"rkr.simplekeyboard.inputmethod",
|
||||
"keepass2android.keepass2android",
|
||||
"keepass2android.keepass2android_nonet",
|
||||
"com.softwarevalencia.openboard.inputmethod.latin",
|
||||
"kl.ime.oh",
|
||||
"com.syntellia.fleksy.keyboard",
|
||||
"org.pocketworkstation.pckeyboard",
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
@ -23,4 +23,16 @@ sealed class TechAnalyticsEvent(
|
|||
FULLY,
|
||||
}
|
||||
}
|
||||
|
||||
class KeyboardIdentifier(id: String, packageName: String?, isTrusted: Boolean) : TechAnalyticsEvent(
|
||||
event = "Keyboard Identifier",
|
||||
params = buildMap {
|
||||
put("Id", id)
|
||||
packageName?.let {
|
||||
put("Package", it)
|
||||
put("GPUrl", "https://play.google.com/store/apps/details?id=$packageName")
|
||||
}
|
||||
put("isTrusted", isTrusted.toString())
|
||||
},
|
||||
)
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue