feat: route infrared debug hardware modes
This commit is contained in:
@@ -45,6 +45,15 @@ android {
|
||||
kotlinOptions {
|
||||
jvmTarget = "17"
|
||||
}
|
||||
|
||||
packaging {
|
||||
resources {
|
||||
excludes += "/META-INF/{AL2.0,LGPL2.1}"
|
||||
excludes += "/META-INF/DEPENDENCIES"
|
||||
excludes += "/META-INF/LICENSE*"
|
||||
excludes += "/META-INF/NOTICE*"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
kapt {
|
||||
@@ -54,7 +63,9 @@ kapt {
|
||||
dependencies {
|
||||
implementation(project(":domain"))
|
||||
implementation(project(":android:core:designsystem"))
|
||||
implementation(project(":android:feature:infrared"))
|
||||
debugImplementation(project(":testing:fakes"))
|
||||
debugImplementation(project(":absdk-bridge"))
|
||||
|
||||
implementation(platform(libs.compose.bom))
|
||||
implementation(libs.androidx.activity.compose)
|
||||
@@ -68,6 +79,7 @@ dependencies {
|
||||
kapt(libs.hilt.compiler)
|
||||
|
||||
testImplementation(libs.junit)
|
||||
testImplementation(libs.kotlinx.coroutines.test)
|
||||
androidTestImplementation(platform(libs.compose.bom))
|
||||
androidTestImplementation(libs.androidx.junit)
|
||||
androidTestImplementation(libs.espresso.core)
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
<application android:usesCleartextTraffic="true" />
|
||||
</manifest>
|
||||
+41
@@ -0,0 +1,41 @@
|
||||
package com.flagship.abox.manager.di
|
||||
|
||||
import com.flagship.abox.manager.domain.DeviceName
|
||||
import com.flagship.abox.manager.domain.DomainResult
|
||||
import com.flagship.abox.manager.domain.InfraredCode
|
||||
import com.flagship.abox.manager.domain.InfraredCodeDownloadResult
|
||||
import com.flagship.abox.manager.domain.InfraredGateway
|
||||
import com.flagship.abox.manager.domain.ProviderProfileId
|
||||
import com.flagship.abox.manager.infrared.runtime.InfraredRuntimeMode
|
||||
import com.flagship.abox.manager.infrared.runtime.InfraredRuntimeModeStore
|
||||
|
||||
class DebugRoutingInfraredGateway(
|
||||
private val modeStore: InfraredRuntimeModeStore,
|
||||
private val fakeGateway: InfraredGateway,
|
||||
private val realGateway: InfraredGateway,
|
||||
) : InfraredGateway {
|
||||
|
||||
private suspend fun delegate(): InfraredGateway {
|
||||
return when (modeStore.currentMode()) {
|
||||
InfraredRuntimeMode.REAL_ABSDK -> realGateway
|
||||
InfraredRuntimeMode.FAKE -> fakeGateway
|
||||
}
|
||||
}
|
||||
|
||||
override suspend fun sendKey(
|
||||
profileId: ProviderProfileId,
|
||||
deviceName: DeviceName,
|
||||
key: String,
|
||||
): DomainResult<Unit> = delegate().sendKey(profileId, deviceName, key)
|
||||
|
||||
override suspend fun learnKey(
|
||||
profileId: ProviderProfileId,
|
||||
deviceName: DeviceName,
|
||||
key: String,
|
||||
): DomainResult<Unit> = delegate().learnKey(profileId, deviceName, key)
|
||||
|
||||
override suspend fun downloadCodes(
|
||||
profileId: ProviderProfileId,
|
||||
codes: List<InfraredCode>,
|
||||
): DomainResult<List<InfraredCodeDownloadResult>> = delegate().downloadCodes(profileId, codes)
|
||||
}
|
||||
@@ -1,10 +1,13 @@
|
||||
package com.flagship.abox.manager.di
|
||||
|
||||
import com.flagship.abox.manager.absdk.bridge.AbsdkBridge
|
||||
import com.flagship.abox.manager.absdk.bridge.CleartextAbsdkTransport
|
||||
import com.flagship.abox.manager.domain.DeviceCatalog
|
||||
import com.flagship.abox.manager.domain.InfraredGateway
|
||||
import com.flagship.abox.manager.domain.SessionGateway
|
||||
import com.flagship.abox.manager.domain.SocketGateway
|
||||
import com.flagship.abox.manager.domain.TemperatureHumidityGateway
|
||||
import com.flagship.abox.manager.infrared.runtime.InfraredRuntimeModeStore
|
||||
import com.flagship.abox.manager.testing.fakes.FakeDeviceCatalog
|
||||
import com.flagship.abox.manager.testing.fakes.FakeInfraredGateway
|
||||
import com.flagship.abox.manager.testing.fakes.FakeSessionGateway
|
||||
@@ -38,5 +41,18 @@ object FoundationModule {
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
fun provideInfraredGateway(): InfraredGateway = FakeInfraredGateway()
|
||||
fun provideFakeInfraredGateway(): FakeInfraredGateway = FakeInfraredGateway()
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
@OptIn(CleartextAbsdkTransport::class)
|
||||
fun provideRealAbsdkBridge(): AbsdkBridge = AbsdkBridge.create()
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
fun provideInfraredGateway(
|
||||
modeStore: InfraredRuntimeModeStore,
|
||||
fake: FakeInfraredGateway,
|
||||
real: AbsdkBridge,
|
||||
): InfraredGateway = DebugRoutingInfraredGateway(modeStore, fake, real)
|
||||
}
|
||||
|
||||
@@ -0,0 +1,47 @@
|
||||
package com.flagship.abox.manager.di
|
||||
|
||||
import com.flagship.abox.manager.domain.DeviceName
|
||||
import com.flagship.abox.manager.domain.DomainError
|
||||
import com.flagship.abox.manager.domain.DomainResult
|
||||
import com.flagship.abox.manager.domain.InfraredCode
|
||||
import com.flagship.abox.manager.domain.InfraredCodeDownloadResult
|
||||
import com.flagship.abox.manager.domain.InfraredGateway
|
||||
import com.flagship.abox.manager.domain.ProviderProfileId
|
||||
import dagger.Module
|
||||
import dagger.Provides
|
||||
import dagger.hilt.InstallIn
|
||||
import dagger.hilt.components.SingletonComponent
|
||||
import javax.inject.Singleton
|
||||
|
||||
@Module
|
||||
@InstallIn(SingletonComponent::class)
|
||||
object InfraredReleaseModule {
|
||||
|
||||
@Provides
|
||||
@Singleton
|
||||
fun provideInfraredGateway(): InfraredGateway = object : InfraredGateway {
|
||||
override suspend fun sendKey(
|
||||
profileId: ProviderProfileId,
|
||||
deviceName: DeviceName,
|
||||
key: String,
|
||||
): DomainResult<Unit> = disabledFailure()
|
||||
|
||||
override suspend fun learnKey(
|
||||
profileId: ProviderProfileId,
|
||||
deviceName: DeviceName,
|
||||
key: String,
|
||||
): DomainResult<Unit> = disabledFailure()
|
||||
|
||||
override suspend fun downloadCodes(
|
||||
profileId: ProviderProfileId,
|
||||
codes: List<InfraredCode>,
|
||||
): DomainResult<List<InfraredCodeDownloadResult>> = disabledFailure()
|
||||
|
||||
private fun <T> disabledFailure(): DomainResult<T> = DomainResult.Failure(
|
||||
DomainError.OperationFailed(
|
||||
externalCode = "REAL_ABSDK_DISABLED",
|
||||
detail = "Infrared hardware transport is disabled in release builds",
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
+70
@@ -0,0 +1,70 @@
|
||||
package com.flagship.abox.manager.di
|
||||
|
||||
import com.flagship.abox.manager.domain.DeviceName
|
||||
import com.flagship.abox.manager.domain.DomainResult
|
||||
import com.flagship.abox.manager.domain.InfraredCode
|
||||
import com.flagship.abox.manager.domain.ProviderProfileId
|
||||
import com.flagship.abox.manager.infrared.runtime.InfraredRuntimeMode
|
||||
import com.flagship.abox.manager.infrared.runtime.InfraredRuntimeModeStore
|
||||
import com.flagship.abox.manager.testing.fakes.FakeInfraredGateway
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.test.runTest
|
||||
import org.junit.Assert.assertEquals
|
||||
import org.junit.Assert.assertTrue
|
||||
import org.junit.Test
|
||||
|
||||
private class TestModeStore : InfraredRuntimeModeStore {
|
||||
private val modeFlow = MutableStateFlow(InfraredRuntimeMode.FAKE)
|
||||
override val mode: Flow<InfraredRuntimeMode> = modeFlow
|
||||
override suspend fun currentMode(): InfraredRuntimeMode = modeFlow.value
|
||||
override suspend fun setMode(mode: InfraredRuntimeMode): DomainResult<Unit> {
|
||||
modeFlow.value = mode
|
||||
return DomainResult.Success(Unit)
|
||||
}
|
||||
}
|
||||
|
||||
class DebugRoutingInfraredGatewayTest {
|
||||
|
||||
private val modeStore = TestModeStore()
|
||||
private val fake = FakeInfraredGateway()
|
||||
private val real = FakeInfraredGateway()
|
||||
private val router = DebugRoutingInfraredGateway(modeStore, fake, real)
|
||||
|
||||
private val profile = ProviderProfileId("profile1")
|
||||
private val device = DeviceName("ir-1")
|
||||
|
||||
@Test
|
||||
fun delegatesToFakeByDefault() = runTest {
|
||||
val result = router.sendKey(profile, device, "key1")
|
||||
assertTrue(result is DomainResult.Success)
|
||||
assertEquals(1, fake.sentKeys.size)
|
||||
assertTrue(real.sentKeys.isEmpty())
|
||||
|
||||
router.learnKey(profile, device, "key2")
|
||||
assertEquals(1, fake.learnedKeys.size)
|
||||
assertTrue(real.learnedKeys.isEmpty())
|
||||
|
||||
router.downloadCodes(profile, listOf(InfraredCode(device, "k", "code")))
|
||||
assertEquals(1, fake.downloadCalls.size)
|
||||
assertTrue(real.downloadCalls.isEmpty())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun delegatesToRealWhenModeIsRealAbsdk() = runTest {
|
||||
modeStore.setMode(InfraredRuntimeMode.REAL_ABSDK)
|
||||
|
||||
val result = router.sendKey(profile, device, "key1")
|
||||
assertTrue(result is DomainResult.Success)
|
||||
assertTrue(fake.sentKeys.isEmpty())
|
||||
assertEquals(1, real.sentKeys.size)
|
||||
|
||||
router.learnKey(profile, device, "key2")
|
||||
assertTrue(fake.learnedKeys.isEmpty())
|
||||
assertEquals(1, real.learnedKeys.size)
|
||||
|
||||
router.downloadCodes(profile, listOf(InfraredCode(device, "k", "code")))
|
||||
assertTrue(fake.downloadCalls.isEmpty())
|
||||
assertEquals(1, real.downloadCalls.size)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user