blob: b1296179d7f761a79be6a984f6d953400039e733 [file] [log] [blame]
/*
* Copyright (C) 2022 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.systemui.statusbar.pipeline.wifi.data.repository
import android.os.Bundle
import androidx.annotation.VisibleForTesting
import com.android.systemui.common.coroutine.ConflatedCallbackFlow.conflatedCallbackFlow
import com.android.systemui.dagger.qualifiers.Application
import com.android.systemui.demomode.DemoMode
import com.android.systemui.demomode.DemoModeController
import com.android.systemui.statusbar.pipeline.shared.data.model.DataActivityModel
import com.android.systemui.statusbar.pipeline.wifi.data.repository.demo.DemoWifiRepository
import com.android.systemui.statusbar.pipeline.wifi.data.repository.prod.WifiRepositoryImpl
import com.android.systemui.statusbar.pipeline.wifi.shared.model.WifiNetworkModel
import javax.inject.Inject
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.channels.awaitClose
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.flatMapLatest
import kotlinx.coroutines.flow.mapLatest
import kotlinx.coroutines.flow.stateIn
/**
* Provides the [WifiRepository] interface either through the [DemoWifiRepository] implementation,
* or the [WifiRepositoryImpl]'s prod implementation, based on the current demo mode value. In this
* way, downstream clients can all consist of real implementations and not care about which
* repository is responsible for the data. Graphically:
* ```
* RealRepository
* │
* ├──►RepositorySwitcher──►RealInteractor──►RealViewModel
* │
* DemoRepository
* ```
*
* When demo mode turns on, every flow will [flatMapLatest] to the current provider's version of
* that flow.
*/
@Suppress("EXPERIMENTAL_IS_NOT_ENABLED")
@OptIn(ExperimentalCoroutinesApi::class)
class WifiRepositorySwitcher
@Inject
constructor(
private val realImpl: RealWifiRepository,
private val demoImpl: DemoWifiRepository,
private val demoModeController: DemoModeController,
@Application scope: CoroutineScope,
) : WifiRepository {
private val isDemoMode =
conflatedCallbackFlow {
val callback =
object : DemoMode {
override fun dispatchDemoCommand(command: String?, args: Bundle?) {
// Don't care
}
override fun onDemoModeStarted() {
demoImpl.startProcessingCommands()
trySend(true)
}
override fun onDemoModeFinished() {
demoImpl.stopProcessingCommands()
trySend(false)
}
}
demoModeController.addCallback(callback)
awaitClose { demoModeController.removeCallback(callback) }
}
.stateIn(scope, SharingStarted.WhileSubscribed(), demoModeController.isInDemoMode)
@VisibleForTesting
val activeRepo =
isDemoMode
.mapLatest { isDemoMode ->
if (isDemoMode) {
demoImpl
} else {
realImpl
}
}
.stateIn(scope, SharingStarted.WhileSubscribed(), realImpl)
override val isWifiEnabled: StateFlow<Boolean> =
activeRepo
.flatMapLatest { it.isWifiEnabled }
.stateIn(scope, SharingStarted.WhileSubscribed(), realImpl.isWifiEnabled.value)
override val isWifiDefault: StateFlow<Boolean> =
activeRepo
.flatMapLatest { it.isWifiDefault }
.stateIn(scope, SharingStarted.WhileSubscribed(), realImpl.isWifiDefault.value)
override val wifiNetwork: StateFlow<WifiNetworkModel> =
activeRepo
.flatMapLatest { it.wifiNetwork }
.stateIn(scope, SharingStarted.WhileSubscribed(), realImpl.wifiNetwork.value)
override val wifiActivity: StateFlow<DataActivityModel> =
activeRepo
.flatMapLatest { it.wifiActivity }
.stateIn(scope, SharingStarted.WhileSubscribed(), realImpl.wifiActivity.value)
}