Updated on 2026-08-14

This commit is contained in:
Tangem 2023-09-20 18:48:25 +03:00
parent 3c59214c76
commit 4c903fc654
73 changed files with 886 additions and 190 deletions

1
data/balance-hiding/.gitignore vendored Normal file
View file

@ -0,0 +1 @@
/build

View file

@ -0,0 +1,27 @@
plugins {
alias(deps.plugins.android.library)
alias(deps.plugins.kotlin.android)
alias(deps.plugins.kotlin.kapt)
alias(deps.plugins.hilt.android)
id("configuration")
}
android {
namespace = "com.tangem.data.balancehiding"
}
dependencies {
/** DI */
implementation(deps.hilt.android)
kapt(deps.hilt.kapt)
implementation(deps.kotlin.coroutines)
implementation(projects.core.utils)
implementation(projects.core.datasource)
implementation(projects.domain.balanceHiding)
implementation(projects.domain.balanceHiding.models)
}

View file

@ -0,0 +1,36 @@
package com.tangem.data.balancehiding
import com.tangem.datasource.local.appcurrency.BalanceHidingSettingsStore
import com.tangem.domain.balancehiding.BalanceHidingSettings
import com.tangem.domain.balancehiding.repositories.BalanceHidingRepository
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.flowOn
import kotlinx.coroutines.flow.onStart
import kotlinx.coroutines.withContext
internal class DefaultBalanceHidingRepository(
private val balanceHidingSettingsStore: BalanceHidingSettingsStore,
private val dispatchers: CoroutineDispatcherProvider,
) : BalanceHidingRepository {
override fun getBalanceHidingSettingsFlow(): Flow<BalanceHidingSettings> {
return balanceHidingSettingsStore.get()
.onStart { emit(getBalanceHidingSettings()) }
.flowOn(dispatchers.io)
.distinctUntilChanged()
}
override suspend fun storeBalanceHidingSettings(balanceHidingSettings: BalanceHidingSettings) {
withContext(dispatchers.io) {
balanceHidingSettingsStore.store(balanceHidingSettings)
}
}
override suspend fun getBalanceHidingSettings(): BalanceHidingSettings {
return withContext(dispatchers.io) {
balanceHidingSettingsStore.getSyncOrDefault()
}
}
}

View file

@ -0,0 +1,25 @@
package com.tangem.data.balancehiding
import android.content.Context
import android.hardware.Sensor
import android.hardware.SensorManager
import com.tangem.domain.balancehiding.DeviceFlipDetector
import kotlinx.coroutines.channels.awaitClose
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.callbackFlow
internal class DefaultDeviceFlipDetector(context: Context) : DeviceFlipDetector {
private val sensorManager = context.getSystemService(Context.SENSOR_SERVICE) as SensorManager
private var gravitySensor = sensorManager.getDefaultSensor(Sensor.TYPE_GRAVITY)
override fun getDeviceFlipFlow(): Flow<Unit> = callbackFlow {
val listener = FlipListener { trySend(Unit) }
gravitySensor?.let {
sensorManager.registerListener(listener, it, SensorManager.SENSOR_DELAY_NORMAL)
}
awaitClose { sensorManager.unregisterListener(listener) }
}
}

View file

@ -0,0 +1,39 @@
package com.tangem.data.balancehiding
import android.hardware.Sensor
import android.hardware.SensorEvent
import android.hardware.SensorEventListener
import android.os.SystemClock
internal class FlipListener(private val action: () -> Unit) : SensorEventListener {
private val zAxisThreshold = -6
private val throttleTimeMs = 3000
private var lastTriggerTime = 0L
private var isScreenDown = false
override fun onAccuracyChanged(sensor: Sensor?, accuracy: Int) {
/* no-op */
}
override fun onSensorChanged(event: SensorEvent?) {
event?.let {
val currentTime = SystemClock.elapsedRealtime()
val zAxisValue = it.values[2]
if (zAxisValue < zAxisThreshold && !isScreenDown) {
isScreenDown = true
lastTriggerTime = currentTime
// TODO add module logging
// Timber.tag("onSensorChanged").d("screen down")
} else if (zAxisValue >= zAxisThreshold) {
if (isScreenDown && currentTime - lastTriggerTime <= throttleTimeMs) {
// Timber.tag("onSensorChanged").d("screen up!")
lastTriggerTime = currentTime
action.invoke()
}
isScreenDown = false
}
}
}
}

View file

@ -0,0 +1,38 @@
package com.tangem.data.balancehiding.di
import android.content.Context
import com.tangem.data.balancehiding.DefaultBalanceHidingRepository
import com.tangem.data.balancehiding.DefaultDeviceFlipDetector
import com.tangem.datasource.local.appcurrency.BalanceHidingSettingsStore
import com.tangem.domain.balancehiding.DeviceFlipDetector
import com.tangem.domain.balancehiding.repositories.BalanceHidingRepository
import com.tangem.utils.coroutines.CoroutineDispatcherProvider
import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
import dagger.hilt.components.SingletonComponent
import javax.inject.Singleton
import dagger.hilt.android.qualifiers.ApplicationContext
@Module
@InstallIn(SingletonComponent::class)
internal object BalanceHidingModule {
@Provides
@Singleton
fun provideBalanceHidingRepository(
balanceHidingSettingsStore: BalanceHidingSettingsStore,
dispatchers: CoroutineDispatcherProvider,
): BalanceHidingRepository {
return DefaultBalanceHidingRepository(
balanceHidingSettingsStore = balanceHidingSettingsStore,
dispatchers = dispatchers,
)
}
@Provides
@Singleton
fun provideFlipDetector(@ApplicationContext context: Context): DeviceFlipDetector {
return DefaultDeviceFlipDetector(context = context)
}
}

View file

@ -14,13 +14,16 @@ dependencies {
/** DI */
implementation(deps.hilt.android)
kapt(deps.hilt.kapt)
implementation(deps.kotlin.coroutines)
implementation(projects.core.utils)
implementation(projects.core.datasource)
implementation(projects.domain.settings)
implementation(projects.domain.balanceHiding.models)
implementation(projects.data.source.preferences)
}

View file

@ -20,6 +20,9 @@ internal object SettingsDataModule {
preferencesDataSource: PreferencesDataSource,
dispatchers: CoroutineDispatcherProvider,
): SettingsRepository {
return DefaultSettingsRepository(preferencesDataSource = preferencesDataSource, dispatchers = dispatchers)
return DefaultSettingsRepository(
preferencesDataSource = preferencesDataSource,
dispatchers = dispatchers,
)
}
}