1 /* <lambda>null2 * Copyright (C) 2022 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.systemui.statusbar.pipeline.wifi.data.repository 18 19 import android.os.Bundle 20 import androidx.annotation.VisibleForTesting 21 import com.android.systemui.common.coroutine.ConflatedCallbackFlow.conflatedCallbackFlow 22 import com.android.systemui.dagger.qualifiers.Application 23 import com.android.systemui.demomode.DemoMode 24 import com.android.systemui.demomode.DemoModeController 25 import com.android.systemui.statusbar.pipeline.shared.data.model.DataActivityModel 26 import com.android.systemui.statusbar.pipeline.wifi.data.repository.demo.DemoWifiRepository 27 import com.android.systemui.statusbar.pipeline.wifi.data.repository.prod.WifiRepositoryImpl 28 import com.android.systemui.statusbar.pipeline.wifi.shared.model.WifiNetworkModel 29 import javax.inject.Inject 30 import kotlinx.coroutines.CoroutineScope 31 import kotlinx.coroutines.ExperimentalCoroutinesApi 32 import kotlinx.coroutines.channels.awaitClose 33 import kotlinx.coroutines.flow.SharingStarted 34 import kotlinx.coroutines.flow.StateFlow 35 import kotlinx.coroutines.flow.flatMapLatest 36 import kotlinx.coroutines.flow.mapLatest 37 import kotlinx.coroutines.flow.stateIn 38 39 /** 40 * Provides the [WifiRepository] interface either through the [DemoWifiRepository] implementation, 41 * or the [WifiRepositoryImpl]'s prod implementation, based on the current demo mode value. In this 42 * way, downstream clients can all consist of real implementations and not care about which 43 * repository is responsible for the data. Graphically: 44 * ``` 45 * RealRepository 46 * │ 47 * ├──►RepositorySwitcher──►RealInteractor──►RealViewModel 48 * │ 49 * DemoRepository 50 * ``` 51 * 52 * When demo mode turns on, every flow will [flatMapLatest] to the current provider's version of 53 * that flow. 54 */ 55 @Suppress("EXPERIMENTAL_IS_NOT_ENABLED") 56 @OptIn(ExperimentalCoroutinesApi::class) 57 class WifiRepositorySwitcher 58 @Inject 59 constructor( 60 private val realImpl: RealWifiRepository, 61 private val demoImpl: DemoWifiRepository, 62 private val demoModeController: DemoModeController, 63 @Application scope: CoroutineScope, 64 ) : WifiRepository { 65 private val isDemoMode = 66 conflatedCallbackFlow { 67 val callback = 68 object : DemoMode { 69 override fun dispatchDemoCommand(command: String?, args: Bundle?) { 70 // Don't care 71 } 72 73 override fun onDemoModeStarted() { 74 demoImpl.startProcessingCommands() 75 trySend(true) 76 } 77 78 override fun onDemoModeFinished() { 79 demoImpl.stopProcessingCommands() 80 trySend(false) 81 } 82 } 83 84 demoModeController.addCallback(callback) 85 awaitClose { demoModeController.removeCallback(callback) } 86 } 87 .stateIn(scope, SharingStarted.WhileSubscribed(), demoModeController.isInDemoMode) 88 89 @VisibleForTesting 90 val activeRepo = 91 isDemoMode 92 .mapLatest { isDemoMode -> 93 if (isDemoMode) { 94 demoImpl 95 } else { 96 realImpl 97 } 98 } 99 .stateIn(scope, SharingStarted.WhileSubscribed(), realImpl) 100 101 override val isWifiEnabled: StateFlow<Boolean> = 102 activeRepo 103 .flatMapLatest { it.isWifiEnabled } 104 .stateIn(scope, SharingStarted.WhileSubscribed(), realImpl.isWifiEnabled.value) 105 106 override val isWifiDefault: StateFlow<Boolean> = 107 activeRepo 108 .flatMapLatest { it.isWifiDefault } 109 .stateIn(scope, SharingStarted.WhileSubscribed(), realImpl.isWifiDefault.value) 110 111 override val wifiNetwork: StateFlow<WifiNetworkModel> = 112 activeRepo 113 .flatMapLatest { it.wifiNetwork } 114 .stateIn(scope, SharingStarted.WhileSubscribed(), realImpl.wifiNetwork.value) 115 116 override val wifiActivity: StateFlow<DataActivityModel> = 117 activeRepo 118 .flatMapLatest { it.wifiActivity } 119 .stateIn(scope, SharingStarted.WhileSubscribed(), realImpl.wifiActivity.value) 120 } 121