Merge changes Ieb73c357,I7f5bc07b,I01b33b24,I873e57bf,I8de76ad5 into tm-qpr-dev am: b9115ca03b

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/20855887

Change-Id: I90ca359eaa83fc54e8a547b1f4a841b031bced64
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
This commit is contained in:
TreeHugger Robot
2023-01-05 02:22:53 +00:00
committed by Automerger Merge Worker
30 changed files with 471 additions and 413 deletions

View File

@@ -460,7 +460,6 @@
-packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ConnectivityPipelineLogger.kt -packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ConnectivityPipelineLogger.kt
-packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/model/WifiActivityModel.kt -packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/model/WifiActivityModel.kt
-packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/model/WifiNetworkModel.kt -packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/model/WifiNetworkModel.kt
-packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/prod/WifiRepositoryImpl.kt
-packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/domain/interactor/WifiInteractor.kt -packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/domain/interactor/WifiInteractor.kt
-packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/shared/WifiConstants.kt -packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/shared/WifiConstants.kt
-packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/ui/view/ModernStatusBarWifiView.kt -packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/ui/view/ModernStatusBarWifiView.kt

View File

@@ -16,6 +16,7 @@
package com.android.systemui.statusbar.pipeline.dagger package com.android.systemui.statusbar.pipeline.dagger
import android.net.wifi.WifiManager
import com.android.systemui.CoreStartable import com.android.systemui.CoreStartable
import com.android.systemui.dagger.SysUISingleton import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.log.table.TableLogBuffer import com.android.systemui.log.table.TableLogBuffer
@@ -35,8 +36,11 @@ import com.android.systemui.statusbar.pipeline.mobile.util.MobileMappingsProxy
import com.android.systemui.statusbar.pipeline.mobile.util.MobileMappingsProxyImpl import com.android.systemui.statusbar.pipeline.mobile.util.MobileMappingsProxyImpl
import com.android.systemui.statusbar.pipeline.shared.data.repository.ConnectivityRepository import com.android.systemui.statusbar.pipeline.shared.data.repository.ConnectivityRepository
import com.android.systemui.statusbar.pipeline.shared.data.repository.ConnectivityRepositoryImpl import com.android.systemui.statusbar.pipeline.shared.data.repository.ConnectivityRepositoryImpl
import com.android.systemui.statusbar.pipeline.wifi.data.repository.RealWifiRepository
import com.android.systemui.statusbar.pipeline.wifi.data.repository.WifiRepository import com.android.systemui.statusbar.pipeline.wifi.data.repository.WifiRepository
import com.android.systemui.statusbar.pipeline.wifi.data.repository.WifiRepositorySwitcher import com.android.systemui.statusbar.pipeline.wifi.data.repository.WifiRepositorySwitcher
import com.android.systemui.statusbar.pipeline.wifi.data.repository.prod.DisabledWifiRepository
import com.android.systemui.statusbar.pipeline.wifi.data.repository.prod.WifiRepositoryImpl
import com.android.systemui.statusbar.pipeline.wifi.domain.interactor.WifiInteractor import com.android.systemui.statusbar.pipeline.wifi.domain.interactor.WifiInteractor
import com.android.systemui.statusbar.pipeline.wifi.domain.interactor.WifiInteractorImpl import com.android.systemui.statusbar.pipeline.wifi.domain.interactor.WifiInteractorImpl
import dagger.Binds import dagger.Binds
@@ -78,9 +82,23 @@ abstract class StatusBarPipelineModule {
@ClassKey(MobileUiAdapter::class) @ClassKey(MobileUiAdapter::class)
abstract fun bindFeature(impl: MobileUiAdapter): CoreStartable abstract fun bindFeature(impl: MobileUiAdapter): CoreStartable
@Module
companion object { companion object {
@JvmStatic @Provides
@SysUISingleton
fun provideRealWifiRepository(
wifiManager: WifiManager?,
disabledWifiRepository: DisabledWifiRepository,
wifiRepositoryImplFactory: WifiRepositoryImpl.Factory,
): RealWifiRepository {
// If we have a null [WifiManager], then the wifi repository should be permanently
// disabled.
return if (wifiManager == null) {
disabledWifiRepository
} else {
wifiRepositoryImplFactory.create(wifiManager)
}
}
@Provides @Provides
@SysUISingleton @SysUISingleton
@WifiTableLog @WifiTableLog
@@ -88,7 +106,6 @@ abstract class StatusBarPipelineModule {
return factory.create("WifiTableLog", 100) return factory.create("WifiTableLog", 100)
} }
@JvmStatic
@Provides @Provides
@SysUISingleton @SysUISingleton
@AirplaneTableLog @AirplaneTableLog

View File

@@ -17,7 +17,6 @@
package com.android.systemui.statusbar.pipeline.mobile.data.model package com.android.systemui.statusbar.pipeline.mobile.data.model
import android.telephony.Annotation.NetworkType import android.telephony.Annotation.NetworkType
import android.telephony.TelephonyManager.NETWORK_TYPE_UNKNOWN
import com.android.systemui.statusbar.pipeline.mobile.util.MobileMappingsProxy import com.android.systemui.statusbar.pipeline.mobile.util.MobileMappingsProxy
/** /**
@@ -26,21 +25,17 @@ import com.android.systemui.statusbar.pipeline.mobile.util.MobileMappingsProxy
* methods on [MobileMappingsProxy] to generate an icon lookup key. * methods on [MobileMappingsProxy] to generate an icon lookup key.
*/ */
sealed interface ResolvedNetworkType { sealed interface ResolvedNetworkType {
@NetworkType val type: Int
val lookupKey: String val lookupKey: String
object UnknownNetworkType : ResolvedNetworkType { object UnknownNetworkType : ResolvedNetworkType {
override val type: Int = NETWORK_TYPE_UNKNOWN
override val lookupKey: String = "unknown" override val lookupKey: String = "unknown"
} }
data class DefaultNetworkType( data class DefaultNetworkType(
@NetworkType override val type: Int,
override val lookupKey: String, override val lookupKey: String,
) : ResolvedNetworkType ) : ResolvedNetworkType
data class OverrideNetworkType( data class OverrideNetworkType(
@NetworkType override val type: Int,
override val lookupKey: String, override val lookupKey: String,
) : ResolvedNetworkType ) : ResolvedNetworkType
} }

View File

@@ -17,7 +17,6 @@
package com.android.systemui.statusbar.pipeline.mobile.data.repository package com.android.systemui.statusbar.pipeline.mobile.data.repository
import android.telephony.SubscriptionInfo import android.telephony.SubscriptionInfo
import android.telephony.SubscriptionManager
import android.telephony.TelephonyCallback import android.telephony.TelephonyCallback
import android.telephony.TelephonyManager import android.telephony.TelephonyManager
import com.android.systemui.log.table.TableLogBuffer import com.android.systemui.log.table.TableLogBuffer
@@ -52,13 +51,12 @@ interface MobileConnectionRepository {
* listener + model. * listener + model.
*/ */
val connectionInfo: Flow<MobileConnectionModel> val connectionInfo: Flow<MobileConnectionModel>
/** The total number of levels. Used with [SignalDrawable]. */
val numberOfLevels: StateFlow<Int>
/** Observable tracking [TelephonyManager.isDataConnectionAllowed] */ /** Observable tracking [TelephonyManager.isDataConnectionAllowed] */
val dataEnabled: StateFlow<Boolean> val dataEnabled: StateFlow<Boolean>
/**
* True if this connection represents the default subscription per
* [SubscriptionManager.getDefaultDataSubscriptionId]
*/
val isDefaultDataSubscription: StateFlow<Boolean>
/** /**
* See [TelephonyManager.getCdmaEnhancedRoamingIndicatorDisplayNumber]. This bit only matters if * See [TelephonyManager.getCdmaEnhancedRoamingIndicatorDisplayNumber]. This bit only matters if
@@ -70,4 +68,9 @@ interface MobileConnectionRepository {
/** The service provider name for this network connection, or the default name */ /** The service provider name for this network connection, or the default name */
val networkName: StateFlow<NetworkNameModel> val networkName: StateFlow<NetworkNameModel>
companion object {
/** The default number of levels to use for [numberOfLevels]. */
const val DEFAULT_NUM_LEVELS = 4
}
} }

View File

@@ -18,7 +18,6 @@ package com.android.systemui.statusbar.pipeline.mobile.data.repository
import android.provider.Settings import android.provider.Settings
import android.telephony.CarrierConfigManager import android.telephony.CarrierConfigManager
import android.telephony.SubscriptionManager
import com.android.settingslib.SignalIcon.MobileIconGroup import com.android.settingslib.SignalIcon.MobileIconGroup
import com.android.settingslib.mobile.MobileMappings import com.android.settingslib.mobile.MobileMappings
import com.android.settingslib.mobile.MobileMappings.Config import com.android.settingslib.mobile.MobileMappings.Config
@@ -38,9 +37,6 @@ interface MobileConnectionsRepository {
/** Observable for the subscriptionId of the current mobile data connection */ /** Observable for the subscriptionId of the current mobile data connection */
val activeMobileDataSubscriptionId: StateFlow<Int> val activeMobileDataSubscriptionId: StateFlow<Int>
/** Tracks [SubscriptionManager.getDefaultDataSubscriptionId] */
val defaultDataSubId: StateFlow<Int>
/** The current connectivity status for the default mobile network connection */ /** The current connectivity status for the default mobile network connection */
val defaultMobileNetworkConnectivity: StateFlow<MobileConnectivityModel> val defaultMobileNetworkConnectivity: StateFlow<MobileConnectivityModel>

View File

@@ -139,11 +139,6 @@ constructor(
override val defaultMobileIconGroup: Flow<SignalIcon.MobileIconGroup> = override val defaultMobileIconGroup: Flow<SignalIcon.MobileIconGroup> =
activeRepo.flatMapLatest { it.defaultMobileIconGroup } activeRepo.flatMapLatest { it.defaultMobileIconGroup }
override val defaultDataSubId: StateFlow<Int> =
activeRepo
.flatMapLatest { it.defaultDataSubId }
.stateIn(scope, SharingStarted.WhileSubscribed(), realRepository.defaultDataSubId.value)
override val defaultMobileNetworkConnectivity: StateFlow<MobileConnectivityModel> = override val defaultMobileNetworkConnectivity: StateFlow<MobileConnectivityModel> =
activeRepo activeRepo
.flatMapLatest { it.defaultMobileNetworkConnectivity } .flatMapLatest { it.defaultMobileNetworkConnectivity }

View File

@@ -34,6 +34,7 @@ import com.android.systemui.statusbar.pipeline.mobile.data.model.ResolvedNetwork
import com.android.systemui.statusbar.pipeline.mobile.data.model.ResolvedNetworkType.DefaultNetworkType import com.android.systemui.statusbar.pipeline.mobile.data.model.ResolvedNetworkType.DefaultNetworkType
import com.android.systemui.statusbar.pipeline.mobile.data.model.SubscriptionModel import com.android.systemui.statusbar.pipeline.mobile.data.model.SubscriptionModel
import com.android.systemui.statusbar.pipeline.mobile.data.repository.MobileConnectionRepository import com.android.systemui.statusbar.pipeline.mobile.data.repository.MobileConnectionRepository
import com.android.systemui.statusbar.pipeline.mobile.data.repository.MobileConnectionRepository.Companion.DEFAULT_NUM_LEVELS
import com.android.systemui.statusbar.pipeline.mobile.data.repository.MobileConnectionsRepository import com.android.systemui.statusbar.pipeline.mobile.data.repository.MobileConnectionsRepository
import com.android.systemui.statusbar.pipeline.mobile.data.repository.demo.model.FakeNetworkEventModel import com.android.systemui.statusbar.pipeline.mobile.data.repository.demo.model.FakeNetworkEventModel
import com.android.systemui.statusbar.pipeline.mobile.data.repository.demo.model.FakeNetworkEventModel.Mobile import com.android.systemui.statusbar.pipeline.mobile.data.repository.demo.model.FakeNetworkEventModel.Mobile
@@ -139,14 +140,6 @@ constructor(
private fun <K, V> Map<K, V>.reverse() = entries.associateBy({ it.value }) { it.key } private fun <K, V> Map<K, V>.reverse() = entries.associateBy({ it.value }) { it.key }
// TODO(b/261029387): add a command for this value
override val defaultDataSubId =
activeMobileDataSubscriptionId.stateIn(
scope,
SharingStarted.WhileSubscribed(),
INVALID_SUBSCRIPTION_ID
)
// TODO(b/261029387): not yet supported // TODO(b/261029387): not yet supported
override val defaultMobileNetworkConnectivity = MutableStateFlow(MobileConnectivityModel()) override val defaultMobileNetworkConnectivity = MutableStateFlow(MobileConnectivityModel())
@@ -199,7 +192,6 @@ constructor(
val connection = getRepoForSubId(subId) val connection = getRepoForSubId(subId)
// This is always true here, because we split out disabled states at the data-source level // This is always true here, because we split out disabled states at the data-source level
connection.dataEnabled.value = true connection.dataEnabled.value = true
connection.isDefaultDataSubscription.value = state.dataType != null
connection.networkName.value = NetworkNameModel.Derived(state.name) connection.networkName.value = NetworkNameModel.Derived(state.name)
connection.cdmaRoaming.value = state.roaming connection.cdmaRoaming.value = state.roaming
@@ -261,15 +253,13 @@ constructor(
private fun SignalIcon.MobileIconGroup?.toResolvedNetworkType(): ResolvedNetworkType { private fun SignalIcon.MobileIconGroup?.toResolvedNetworkType(): ResolvedNetworkType {
val key = mobileMappingsReverseLookup.value[this] ?: "dis" val key = mobileMappingsReverseLookup.value[this] ?: "dis"
return DefaultNetworkType(DEMO_NET_TYPE, key) return DefaultNetworkType(key)
} }
companion object { companion object {
private const val TAG = "DemoMobileConnectionsRepo" private const val TAG = "DemoMobileConnectionsRepo"
private const val DEFAULT_SUB_ID = 1 private const val DEFAULT_SUB_ID = 1
private const val DEMO_NET_TYPE = 1234
} }
} }
@@ -279,9 +269,9 @@ class DemoMobileConnectionRepository(
) : MobileConnectionRepository { ) : MobileConnectionRepository {
override val connectionInfo = MutableStateFlow(MobileConnectionModel()) override val connectionInfo = MutableStateFlow(MobileConnectionModel())
override val dataEnabled = MutableStateFlow(true) override val numberOfLevels = MutableStateFlow(DEFAULT_NUM_LEVELS)
override val isDefaultDataSubscription = MutableStateFlow(true) override val dataEnabled = MutableStateFlow(true)
override val cdmaRoaming = MutableStateFlow(false) override val cdmaRoaming = MutableStateFlow(false)

View File

@@ -48,6 +48,7 @@ import com.android.systemui.statusbar.pipeline.mobile.data.model.ResolvedNetwork
import com.android.systemui.statusbar.pipeline.mobile.data.model.toDataConnectionType import com.android.systemui.statusbar.pipeline.mobile.data.model.toDataConnectionType
import com.android.systemui.statusbar.pipeline.mobile.data.model.toNetworkNameModel import com.android.systemui.statusbar.pipeline.mobile.data.model.toNetworkNameModel
import com.android.systemui.statusbar.pipeline.mobile.data.repository.MobileConnectionRepository import com.android.systemui.statusbar.pipeline.mobile.data.repository.MobileConnectionRepository
import com.android.systemui.statusbar.pipeline.mobile.data.repository.MobileConnectionRepository.Companion.DEFAULT_NUM_LEVELS
import com.android.systemui.statusbar.pipeline.mobile.util.MobileMappingsProxy import com.android.systemui.statusbar.pipeline.mobile.util.MobileMappingsProxy
import com.android.systemui.statusbar.pipeline.shared.ConnectivityPipelineLogger import com.android.systemui.statusbar.pipeline.shared.ConnectivityPipelineLogger
import com.android.systemui.statusbar.pipeline.shared.data.model.toMobileDataActivityModel import com.android.systemui.statusbar.pipeline.shared.data.model.toMobileDataActivityModel
@@ -63,6 +64,7 @@ import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.flow.mapLatest import kotlinx.coroutines.flow.mapLatest
import kotlinx.coroutines.flow.merge import kotlinx.coroutines.flow.merge
import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.flow.onEach
@@ -78,7 +80,6 @@ class MobileConnectionRepositoryImpl(
private val telephonyManager: TelephonyManager, private val telephonyManager: TelephonyManager,
private val globalSettings: GlobalSettings, private val globalSettings: GlobalSettings,
broadcastDispatcher: BroadcastDispatcher, broadcastDispatcher: BroadcastDispatcher,
defaultDataSubId: StateFlow<Int>,
globalMobileDataSettingChangedEvent: Flow<Unit>, globalMobileDataSettingChangedEvent: Flow<Unit>,
mobileMappingsProxy: MobileMappingsProxy, mobileMappingsProxy: MobileMappingsProxy,
bgDispatcher: CoroutineDispatcher, bgDispatcher: CoroutineDispatcher,
@@ -185,14 +186,12 @@ class MobileConnectionRepositoryImpl(
OVERRIDE_NETWORK_TYPE_NONE OVERRIDE_NETWORK_TYPE_NONE
) { ) {
DefaultNetworkType( DefaultNetworkType(
telephonyDisplayInfo.networkType,
mobileMappingsProxy.toIconKey( mobileMappingsProxy.toIconKey(
telephonyDisplayInfo.networkType telephonyDisplayInfo.networkType
) )
) )
} else { } else {
OverrideNetworkType( OverrideNetworkType(
telephonyDisplayInfo.overrideNetworkType,
mobileMappingsProxy.toIconKeyOverride( mobileMappingsProxy.toIconKeyOverride(
telephonyDisplayInfo.overrideNetworkType telephonyDisplayInfo.overrideNetworkType
) )
@@ -214,6 +213,12 @@ class MobileConnectionRepositoryImpl(
.stateIn(scope, SharingStarted.WhileSubscribed(), state) .stateIn(scope, SharingStarted.WhileSubscribed(), state)
} }
// This will become variable based on [CarrierConfigManager.KEY_INFLATE_SIGNAL_STRENGTH_BOOL]
// once it's wired up inside of [CarrierConfigTracker].
override val numberOfLevels: StateFlow<Int> =
flowOf(DEFAULT_NUM_LEVELS)
.stateIn(scope, SharingStarted.WhileSubscribed(), DEFAULT_NUM_LEVELS)
/** Produces whenever the mobile data setting changes for this subId */ /** Produces whenever the mobile data setting changes for this subId */
private val localMobileDataSettingChangedEvent: Flow<Unit> = conflatedCallbackFlow { private val localMobileDataSettingChangedEvent: Flow<Unit> = conflatedCallbackFlow {
val observer = val observer =
@@ -284,20 +289,6 @@ class MobileConnectionRepositoryImpl(
private fun dataConnectionAllowed(): Boolean = telephonyManager.isDataConnectionAllowed private fun dataConnectionAllowed(): Boolean = telephonyManager.isDataConnectionAllowed
override val isDefaultDataSubscription: StateFlow<Boolean> = run {
val initialValue = defaultDataSubId.value == subId
defaultDataSubId
.mapLatest { it == subId }
.distinctUntilChanged()
.logDiffsForTable(
mobileLogger,
columnPrefix = "",
columnName = "isDefaultDataSub",
initialValue = initialValue,
)
.stateIn(scope, SharingStarted.WhileSubscribed(), initialValue)
}
class Factory class Factory
@Inject @Inject
constructor( constructor(
@@ -315,7 +306,6 @@ class MobileConnectionRepositoryImpl(
subId: Int, subId: Int,
defaultNetworkName: NetworkNameModel, defaultNetworkName: NetworkNameModel,
networkNameSeparator: String, networkNameSeparator: String,
defaultDataSubId: StateFlow<Int>,
globalMobileDataSettingChangedEvent: Flow<Unit>, globalMobileDataSettingChangedEvent: Flow<Unit>,
): MobileConnectionRepository { ): MobileConnectionRepository {
val mobileLogger = logFactory.create(tableBufferLogName(subId), 100) val mobileLogger = logFactory.create(tableBufferLogName(subId), 100)
@@ -328,7 +318,6 @@ class MobileConnectionRepositoryImpl(
telephonyManager.createForSubscriptionId(subId), telephonyManager.createForSubscriptionId(subId),
globalSettings, globalSettings,
broadcastDispatcher, broadcastDispatcher,
defaultDataSubId,
globalMobileDataSettingChangedEvent, globalMobileDataSettingChangedEvent,
mobileMappingsProxy, mobileMappingsProxy,
bgDispatcher, bgDispatcher,

View File

@@ -35,7 +35,6 @@ import android.telephony.TelephonyCallback
import android.telephony.TelephonyCallback.ActiveDataSubscriptionIdListener import android.telephony.TelephonyCallback.ActiveDataSubscriptionIdListener
import android.telephony.TelephonyManager import android.telephony.TelephonyManager
import androidx.annotation.VisibleForTesting import androidx.annotation.VisibleForTesting
import com.android.internal.telephony.PhoneConstants
import com.android.settingslib.SignalIcon.MobileIconGroup import com.android.settingslib.SignalIcon.MobileIconGroup
import com.android.settingslib.mobile.MobileMappings.Config import com.android.settingslib.mobile.MobileMappings.Config
import com.android.systemui.R import com.android.systemui.R
@@ -60,7 +59,6 @@ import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.asExecutor import kotlinx.coroutines.asExecutor
import kotlinx.coroutines.channels.awaitClose import kotlinx.coroutines.channels.awaitClose
import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.coroutines.flow.distinctUntilChanged
@@ -142,24 +140,10 @@ constructor(
.logInputChange(logger, "onActiveDataSubscriptionIdChanged") .logInputChange(logger, "onActiveDataSubscriptionIdChanged")
.stateIn(scope, started = SharingStarted.WhileSubscribed(), INVALID_SUBSCRIPTION_ID) .stateIn(scope, started = SharingStarted.WhileSubscribed(), INVALID_SUBSCRIPTION_ID)
private val defaultDataSubIdChangeEvent: MutableSharedFlow<Unit> = private val defaultDataSubIdChangedEvent =
MutableSharedFlow(extraBufferCapacity = 1)
override val defaultDataSubId: StateFlow<Int> =
broadcastDispatcher broadcastDispatcher
.broadcastFlow( .broadcastFlow(IntentFilter(TelephonyManager.ACTION_DEFAULT_DATA_SUBSCRIPTION_CHANGED))
IntentFilter(TelephonyManager.ACTION_DEFAULT_DATA_SUBSCRIPTION_CHANGED)
) { intent, _ ->
intent.getIntExtra(PhoneConstants.SUBSCRIPTION_KEY, INVALID_SUBSCRIPTION_ID)
}
.distinctUntilChanged()
.logInputChange(logger, "ACTION_DEFAULT_DATA_SUBSCRIPTION_CHANGED") .logInputChange(logger, "ACTION_DEFAULT_DATA_SUBSCRIPTION_CHANGED")
.onEach { defaultDataSubIdChangeEvent.tryEmit(Unit) }
.stateIn(
scope,
SharingStarted.WhileSubscribed(),
SubscriptionManager.getDefaultDataSubscriptionId()
)
private val carrierConfigChangedEvent = private val carrierConfigChangedEvent =
broadcastDispatcher broadcastDispatcher
@@ -167,7 +151,7 @@ constructor(
.logInputChange(logger, "ACTION_CARRIER_CONFIG_CHANGED") .logInputChange(logger, "ACTION_CARRIER_CONFIG_CHANGED")
override val defaultDataSubRatConfig: StateFlow<Config> = override val defaultDataSubRatConfig: StateFlow<Config> =
merge(defaultDataSubIdChangeEvent, carrierConfigChangedEvent) merge(defaultDataSubIdChangedEvent, carrierConfigChangedEvent)
.mapLatest { Config.readConfig(context) } .mapLatest { Config.readConfig(context) }
.distinctUntilChanged() .distinctUntilChanged()
.logInputChange(logger, "defaultDataSubRatConfig") .logInputChange(logger, "defaultDataSubRatConfig")
@@ -272,7 +256,6 @@ constructor(
subId, subId,
defaultNetworkName, defaultNetworkName,
networkNameSeparator, networkNameSeparator,
defaultDataSubId,
globalMobileDataSettingChangedEvent, globalMobileDataSettingChangedEvent,
) )
} }

View File

@@ -23,12 +23,11 @@ import com.android.systemui.log.table.TableLogBuffer
import com.android.systemui.statusbar.pipeline.mobile.data.model.DataConnectionState.Connected import com.android.systemui.statusbar.pipeline.mobile.data.model.DataConnectionState.Connected
import com.android.systemui.statusbar.pipeline.mobile.data.model.NetworkNameModel import com.android.systemui.statusbar.pipeline.mobile.data.model.NetworkNameModel
import com.android.systemui.statusbar.pipeline.mobile.data.repository.MobileConnectionRepository import com.android.systemui.statusbar.pipeline.mobile.data.repository.MobileConnectionRepository
import com.android.systemui.statusbar.pipeline.mobile.data.repository.MobileConnectionRepository.Companion.DEFAULT_NUM_LEVELS
import com.android.systemui.statusbar.pipeline.shared.data.model.DataActivityModel import com.android.systemui.statusbar.pipeline.shared.data.model.DataActivityModel
import com.android.systemui.util.CarrierConfigTracker
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.combine
@@ -171,11 +170,12 @@ class MobileIconInteractorImpl(
} }
.stateIn(scope, SharingStarted.WhileSubscribed(), 0) .stateIn(scope, SharingStarted.WhileSubscribed(), 0)
/** override val numberOfLevels: StateFlow<Int> =
* This will become variable based on [CarrierConfigManager.KEY_INFLATE_SIGNAL_STRENGTH_BOOL] connectionRepository.numberOfLevels.stateIn(
* once it's wired up inside of [CarrierConfigTracker] scope,
*/ SharingStarted.WhileSubscribed(),
override val numberOfLevels: StateFlow<Int> = MutableStateFlow(4) connectionRepository.numberOfLevels.value,
)
override val isDataConnected: StateFlow<Boolean> = override val isDataConnected: StateFlow<Boolean> =
connectionInfo connectionInfo

View File

@@ -23,6 +23,33 @@ import com.android.systemui.log.table.Diffable
/** Provides information about the current wifi network. */ /** Provides information about the current wifi network. */
sealed class WifiNetworkModel : Diffable<WifiNetworkModel> { sealed class WifiNetworkModel : Diffable<WifiNetworkModel> {
/**
* A model representing that we couldn't fetch any wifi information.
*
* This is only used with [DisabledWifiRepository], where [WifiManager] is null.
*/
object Unavailable : WifiNetworkModel() {
override fun toString() = "WifiNetwork.Unavailable"
override fun logDiffs(prevVal: WifiNetworkModel, row: TableRowLogger) {
if (prevVal is Unavailable) {
return
}
logFull(row)
}
override fun logFull(row: TableRowLogger) {
row.logChange(COL_NETWORK_TYPE, TYPE_UNAVAILABLE)
row.logChange(COL_NETWORK_ID, NETWORK_ID_DEFAULT)
row.logChange(COL_VALIDATED, false)
row.logChange(COL_LEVEL, LEVEL_DEFAULT)
row.logChange(COL_SSID, null)
row.logChange(COL_PASSPOINT_ACCESS_POINT, false)
row.logChange(COL_ONLINE_SIGN_UP, false)
row.logChange(COL_PASSPOINT_NAME, null)
}
}
/** A model representing that we have no active wifi network. */ /** A model representing that we have no active wifi network. */
object Inactive : WifiNetworkModel() { object Inactive : WifiNetworkModel() {
override fun toString() = "WifiNetwork.Inactive" override fun toString() = "WifiNetwork.Inactive"
@@ -87,13 +114,8 @@ sealed class WifiNetworkModel : Diffable<WifiNetworkModel> {
/** /**
* The wifi signal level, guaranteed to be 0 <= level <= 4. * The wifi signal level, guaranteed to be 0 <= level <= 4.
*
* Null if we couldn't fetch the level for some reason.
*
* TODO(b/238425913): The level will only be null if we have a null WifiManager. Is there a
* way we can guarantee a non-null WifiManager?
*/ */
val level: Int? = null, val level: Int,
/** See [android.net.wifi.WifiInfo.ssid]. */ /** See [android.net.wifi.WifiInfo.ssid]. */
val ssid: String? = null, val ssid: String? = null,
@@ -108,7 +130,7 @@ sealed class WifiNetworkModel : Diffable<WifiNetworkModel> {
val passpointProviderFriendlyName: String? = null, val passpointProviderFriendlyName: String? = null,
) : WifiNetworkModel() { ) : WifiNetworkModel() {
init { init {
require(level == null || level in MIN_VALID_LEVEL..MAX_VALID_LEVEL) { require(level in MIN_VALID_LEVEL..MAX_VALID_LEVEL) {
"0 <= wifi level <= 4 required; level was $level" "0 <= wifi level <= 4 required; level was $level"
} }
} }
@@ -125,11 +147,7 @@ sealed class WifiNetworkModel : Diffable<WifiNetworkModel> {
row.logChange(COL_VALIDATED, isValidated) row.logChange(COL_VALIDATED, isValidated)
} }
if (prevVal !is Active || prevVal.level != level) { if (prevVal !is Active || prevVal.level != level) {
if (level != null) {
row.logChange(COL_LEVEL, level) row.logChange(COL_LEVEL, level)
} else {
row.logChange(COL_LEVEL, LEVEL_DEFAULT)
}
} }
if (prevVal !is Active || prevVal.ssid != ssid) { if (prevVal !is Active || prevVal.ssid != ssid) {
row.logChange(COL_SSID, ssid) row.logChange(COL_SSID, ssid)
@@ -190,6 +208,7 @@ sealed class WifiNetworkModel : Diffable<WifiNetworkModel> {
} }
const val TYPE_CARRIER_MERGED = "CarrierMerged" const val TYPE_CARRIER_MERGED = "CarrierMerged"
const val TYPE_UNAVAILABLE = "Unavailable"
const val TYPE_INACTIVE = "Inactive" const val TYPE_INACTIVE = "Inactive"
const val TYPE_ACTIVE = "Active" const val TYPE_ACTIVE = "Active"

View File

@@ -34,3 +34,13 @@ interface WifiRepository {
/** Observable for the current wifi network activity. */ /** Observable for the current wifi network activity. */
val wifiActivity: StateFlow<DataActivityModel> val wifiActivity: StateFlow<DataActivityModel>
} }
/**
* A no-op interface used for Dagger bindings.
*
* [WifiRepositorySwitcher] needs to inject the "real" wifi repository, which could either be the
* full [WifiRepositoryImpl] or just [DisabledWifiRepository]. Having this interface lets us bind
* [RealWifiRepository], and then [WifiRepositorySwitcher] will automatically get the correct real
* repository.
*/
interface RealWifiRepository : WifiRepository

View File

@@ -58,7 +58,7 @@ import kotlinx.coroutines.flow.stateIn
class WifiRepositorySwitcher class WifiRepositorySwitcher
@Inject @Inject
constructor( constructor(
private val realImpl: WifiRepositoryImpl, private val realImpl: RealWifiRepository,
private val demoImpl: DemoWifiRepository, private val demoImpl: DemoWifiRepository,
private val demoModeController: DemoModeController, private val demoModeController: DemoModeController,
@Application scope: CoroutineScope, @Application scope: CoroutineScope,

View File

@@ -89,7 +89,7 @@ constructor(
WifiNetworkModel.Active( WifiNetworkModel.Active(
networkId = DEMO_NET_ID, networkId = DEMO_NET_ID,
isValidated = validated ?: true, isValidated = validated ?: true,
level = level, level = level ?: 0,
ssid = ssid, ssid = ssid,
// These fields below aren't supported in demo mode, since they aren't needed to satisfy // These fields below aren't supported in demo mode, since they aren't needed to satisfy

View File

@@ -0,0 +1,49 @@
/*
* 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.prod
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.statusbar.pipeline.shared.data.model.DataActivityModel
import com.android.systemui.statusbar.pipeline.wifi.data.model.WifiNetworkModel
import com.android.systemui.statusbar.pipeline.wifi.data.repository.RealWifiRepository
import javax.inject.Inject
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
/**
* Implementation of wifi repository used when wifi is permanently disabled on the device.
*
* This repo should only exist when [WifiManager] is null, which means that we can never fetch any
* wifi information.
*/
@SysUISingleton
class DisabledWifiRepository @Inject constructor() : RealWifiRepository {
override val isWifiEnabled: StateFlow<Boolean> = MutableStateFlow(false).asStateFlow()
override val isWifiDefault: StateFlow<Boolean> = MutableStateFlow(false).asStateFlow()
override val wifiNetwork: StateFlow<WifiNetworkModel> = MutableStateFlow(NETWORK).asStateFlow()
override val wifiActivity: StateFlow<DataActivityModel> =
MutableStateFlow(ACTIVITY).asStateFlow()
companion object {
private val NETWORK = WifiNetworkModel.Unavailable
private val ACTIVITY = DataActivityModel(hasActivityIn = false, hasActivityOut = false)
}
}

View File

@@ -29,7 +29,6 @@ import android.net.NetworkRequest
import android.net.wifi.WifiInfo import android.net.wifi.WifiInfo
import android.net.wifi.WifiManager import android.net.wifi.WifiManager
import android.net.wifi.WifiManager.TrafficStateCallback import android.net.wifi.WifiManager.TrafficStateCallback
import android.util.Log
import com.android.settingslib.Utils import com.android.settingslib.Utils
import com.android.systemui.broadcast.BroadcastDispatcher import com.android.systemui.broadcast.BroadcastDispatcher
import com.android.systemui.common.coroutine.ConflatedCallbackFlow.conflatedCallbackFlow import com.android.systemui.common.coroutine.ConflatedCallbackFlow.conflatedCallbackFlow
@@ -40,11 +39,11 @@ import com.android.systemui.log.table.TableLogBuffer
import com.android.systemui.log.table.logDiffsForTable import com.android.systemui.log.table.logDiffsForTable
import com.android.systemui.statusbar.pipeline.dagger.WifiTableLog import com.android.systemui.statusbar.pipeline.dagger.WifiTableLog
import com.android.systemui.statusbar.pipeline.shared.ConnectivityPipelineLogger import com.android.systemui.statusbar.pipeline.shared.ConnectivityPipelineLogger
import com.android.systemui.statusbar.pipeline.shared.ConnectivityPipelineLogger.Companion.SB_LOGGING_TAG
import com.android.systemui.statusbar.pipeline.shared.ConnectivityPipelineLogger.Companion.logInputChange import com.android.systemui.statusbar.pipeline.shared.ConnectivityPipelineLogger.Companion.logInputChange
import com.android.systemui.statusbar.pipeline.shared.data.model.DataActivityModel import com.android.systemui.statusbar.pipeline.shared.data.model.DataActivityModel
import com.android.systemui.statusbar.pipeline.shared.data.model.toWifiDataActivityModel import com.android.systemui.statusbar.pipeline.shared.data.model.toWifiDataActivityModel
import com.android.systemui.statusbar.pipeline.wifi.data.model.WifiNetworkModel import com.android.systemui.statusbar.pipeline.wifi.data.model.WifiNetworkModel
import com.android.systemui.statusbar.pipeline.wifi.data.repository.RealWifiRepository
import com.android.systemui.statusbar.pipeline.wifi.data.repository.WifiRepository import com.android.systemui.statusbar.pipeline.wifi.data.repository.WifiRepository
import java.util.concurrent.Executor import java.util.concurrent.Executor
import javax.inject.Inject import javax.inject.Inject
@@ -53,12 +52,9 @@ import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.channels.awaitClose import kotlinx.coroutines.channels.awaitClose
import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableSharedFlow import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.flow.mapLatest import kotlinx.coroutines.flow.mapLatest
import kotlinx.coroutines.flow.merge import kotlinx.coroutines.flow.merge
import kotlinx.coroutines.flow.stateIn import kotlinx.coroutines.flow.stateIn
@@ -68,31 +64,30 @@ import kotlinx.coroutines.flow.stateIn
@OptIn(ExperimentalCoroutinesApi::class) @OptIn(ExperimentalCoroutinesApi::class)
@SysUISingleton @SysUISingleton
@SuppressLint("MissingPermission") @SuppressLint("MissingPermission")
class WifiRepositoryImpl @Inject constructor( class WifiRepositoryImpl
@Inject
constructor(
broadcastDispatcher: BroadcastDispatcher, broadcastDispatcher: BroadcastDispatcher,
connectivityManager: ConnectivityManager, connectivityManager: ConnectivityManager,
logger: ConnectivityPipelineLogger, logger: ConnectivityPipelineLogger,
@WifiTableLog wifiTableLogBuffer: TableLogBuffer, @WifiTableLog wifiTableLogBuffer: TableLogBuffer,
@Main mainExecutor: Executor, @Main mainExecutor: Executor,
@Application scope: CoroutineScope, @Application scope: CoroutineScope,
wifiManager: WifiManager?, wifiManager: WifiManager,
) : WifiRepository { ) : RealWifiRepository {
private val wifiStateChangeEvents: Flow<Unit> = broadcastDispatcher.broadcastFlow( private val wifiStateChangeEvents: Flow<Unit> =
IntentFilter(WifiManager.WIFI_STATE_CHANGED_ACTION) broadcastDispatcher
) .broadcastFlow(IntentFilter(WifiManager.WIFI_STATE_CHANGED_ACTION))
.logInputChange(logger, "WIFI_STATE_CHANGED_ACTION intent") .logInputChange(logger, "WIFI_STATE_CHANGED_ACTION intent")
private val wifiNetworkChangeEvents: MutableSharedFlow<Unit> = private val wifiNetworkChangeEvents: MutableSharedFlow<Unit> =
MutableSharedFlow(extraBufferCapacity = 1) MutableSharedFlow(extraBufferCapacity = 1)
override val isWifiEnabled: StateFlow<Boolean> =
if (wifiManager == null) {
MutableStateFlow(false).asStateFlow()
} else {
// Because [WifiManager] doesn't expose a wifi enabled change listener, we do it // Because [WifiManager] doesn't expose a wifi enabled change listener, we do it
// internally by fetching [WifiManager.isWifiEnabled] whenever we think the state may // internally by fetching [WifiManager.isWifiEnabled] whenever we think the state may
// have changed. // have changed.
override val isWifiEnabled: StateFlow<Boolean> =
merge(wifiNetworkChangeEvents, wifiStateChangeEvents) merge(wifiNetworkChangeEvents, wifiStateChangeEvents)
.mapLatest { wifiManager.isWifiEnabled } .mapLatest { wifiManager.isWifiEnabled }
.distinctUntilChanged() .distinctUntilChanged()
@@ -105,28 +100,31 @@ class WifiRepositoryImpl @Inject constructor(
.stateIn( .stateIn(
scope = scope, scope = scope,
started = SharingStarted.WhileSubscribed(), started = SharingStarted.WhileSubscribed(),
initialValue = wifiManager.isWifiEnabled initialValue = wifiManager.isWifiEnabled,
) )
}
override val isWifiDefault: StateFlow<Boolean> = conflatedCallbackFlow { override val isWifiDefault: StateFlow<Boolean> =
// Note: This callback doesn't do any logging because we already log every network change conflatedCallbackFlow {
// in the [wifiNetwork] callback. // Note: This callback doesn't do any logging because we already log every network
val callback = object : ConnectivityManager.NetworkCallback(FLAG_INCLUDE_LOCATION_INFO) { // change in the [wifiNetwork] callback.
val callback =
object : ConnectivityManager.NetworkCallback(FLAG_INCLUDE_LOCATION_INFO) {
override fun onCapabilitiesChanged( override fun onCapabilitiesChanged(
network: Network, network: Network,
networkCapabilities: NetworkCapabilities networkCapabilities: NetworkCapabilities
) { ) {
// This method will always be called immediately after the network becomes the // This method will always be called immediately after the network
// default, in addition to any time the capabilities change while the network is // becomes the default, in addition to any time the capabilities change
// the default. // while the network is the default.
// If this network contains valid wifi info, then wifi is the default network. // If this network contains valid wifi info, then wifi is the default
// network.
val wifiInfo = networkCapabilitiesToWifiInfo(networkCapabilities) val wifiInfo = networkCapabilitiesToWifiInfo(networkCapabilities)
trySend(wifiInfo != null) trySend(wifiInfo != null)
} }
override fun onLost(network: Network) { override fun onLost(network: Network) {
// The system no longer has a default network, so wifi is definitely not default. // The system no longer has a default network, so wifi is definitely not
// default.
trySend(false) trySend(false)
} }
} }
@@ -141,16 +139,14 @@ class WifiRepositoryImpl @Inject constructor(
columnName = "isWifiDefault", columnName = "isWifiDefault",
initialValue = false, initialValue = false,
) )
.stateIn( .stateIn(scope, started = SharingStarted.WhileSubscribed(), initialValue = false)
scope,
started = SharingStarted.WhileSubscribed(),
initialValue = false
)
override val wifiNetwork: StateFlow<WifiNetworkModel> = conflatedCallbackFlow { override val wifiNetwork: StateFlow<WifiNetworkModel> =
conflatedCallbackFlow {
var currentWifi: WifiNetworkModel = WIFI_NETWORK_DEFAULT var currentWifi: WifiNetworkModel = WIFI_NETWORK_DEFAULT
val callback = object : ConnectivityManager.NetworkCallback(FLAG_INCLUDE_LOCATION_INFO) { val callback =
object : ConnectivityManager.NetworkCallback(FLAG_INCLUDE_LOCATION_INFO) {
override fun onCapabilitiesChanged( override fun onCapabilitiesChanged(
network: Network, network: Network,
networkCapabilities: NetworkCapabilities networkCapabilities: NetworkCapabilities
@@ -161,7 +157,8 @@ class WifiRepositoryImpl @Inject constructor(
val wifiInfo = networkCapabilitiesToWifiInfo(networkCapabilities) val wifiInfo = networkCapabilitiesToWifiInfo(networkCapabilities)
if (wifiInfo?.isPrimary == true) { if (wifiInfo?.isPrimary == true) {
val wifiNetworkModel = createWifiNetworkModel( val wifiNetworkModel =
createWifiNetworkModel(
wifiInfo, wifiInfo,
network, network,
networkCapabilities, networkCapabilities,
@@ -170,7 +167,7 @@ class WifiRepositoryImpl @Inject constructor(
logger.logTransformation( logger.logTransformation(
WIFI_NETWORK_CALLBACK_NAME, WIFI_NETWORK_CALLBACK_NAME,
oldValue = currentWifi, oldValue = currentWifi,
newValue = wifiNetworkModel newValue = wifiNetworkModel,
) )
currentWifi = wifiNetworkModel currentWifi = wifiNetworkModel
trySend(wifiNetworkModel) trySend(wifiNetworkModel)
@@ -183,12 +180,15 @@ class WifiRepositoryImpl @Inject constructor(
wifiNetworkChangeEvents.tryEmit(Unit) wifiNetworkChangeEvents.tryEmit(Unit)
val wifi = currentWifi val wifi = currentWifi
if (wifi is WifiNetworkModel.Active && wifi.networkId == network.getNetId()) { if (
wifi is WifiNetworkModel.Active &&
wifi.networkId == network.getNetId()
) {
val newNetworkModel = WifiNetworkModel.Inactive val newNetworkModel = WifiNetworkModel.Inactive
logger.logTransformation( logger.logTransformation(
WIFI_NETWORK_CALLBACK_NAME, WIFI_NETWORK_CALLBACK_NAME,
oldValue = wifi, oldValue = wifi,
newValue = newNetworkModel newValue = newNetworkModel,
) )
currentWifi = newNetworkModel currentWifi = newNetworkModel
trySend(newNetworkModel) trySend(newNetworkModel)
@@ -207,20 +207,16 @@ class WifiRepositoryImpl @Inject constructor(
initialValue = WIFI_NETWORK_DEFAULT, initialValue = WIFI_NETWORK_DEFAULT,
) )
// There will be multiple wifi icons in different places that will frequently // There will be multiple wifi icons in different places that will frequently
// subscribe/unsubscribe to flows as the views attach/detach. Using [stateIn] ensures that // subscribe/unsubscribe to flows as the views attach/detach. Using [stateIn] ensures
// new subscribes will get the latest value immediately upon subscription. Otherwise, the // that new subscribes will get the latest value immediately upon subscription.
// views could show stale data. See b/244173280. // Otherwise, the views could show stale data. See b/244173280.
.stateIn( .stateIn(
scope, scope,
started = SharingStarted.WhileSubscribed(), started = SharingStarted.WhileSubscribed(),
initialValue = WIFI_NETWORK_DEFAULT initialValue = WIFI_NETWORK_DEFAULT,
) )
override val wifiActivity: StateFlow<DataActivityModel> = override val wifiActivity: StateFlow<DataActivityModel> =
if (wifiManager == null) {
Log.w(SB_LOGGING_TAG, "Null WifiManager; skipping activity callback")
flowOf(ACTIVITY_DEFAULT)
} else {
conflatedCallbackFlow { conflatedCallbackFlow {
val callback = TrafficStateCallback { state -> val callback = TrafficStateCallback { state ->
logger.logInputChange("onTrafficStateChange", prettyPrintActivity(state)) logger.logInputChange("onTrafficStateChange", prettyPrintActivity(state))
@@ -229,7 +225,6 @@ class WifiRepositoryImpl @Inject constructor(
wifiManager.registerTrafficStateCallback(mainExecutor, callback) wifiManager.registerTrafficStateCallback(mainExecutor, callback)
awaitClose { wifiManager.unregisterTrafficStateCallback(callback) } awaitClose { wifiManager.unregisterTrafficStateCallback(callback) }
} }
}
.logDiffsForTable( .logDiffsForTable(
wifiTableLogBuffer, wifiTableLogBuffer,
columnPrefix = ACTIVITY_PREFIX, columnPrefix = ACTIVITY_PREFIX,
@@ -238,7 +233,7 @@ class WifiRepositoryImpl @Inject constructor(
.stateIn( .stateIn(
scope, scope,
started = SharingStarted.WhileSubscribed(), started = SharingStarted.WhileSubscribed(),
initialValue = ACTIVITY_DEFAULT initialValue = ACTIVITY_DEFAULT,
) )
companion object { companion object {
@@ -271,7 +266,7 @@ class WifiRepositoryImpl @Inject constructor(
wifiInfo: WifiInfo, wifiInfo: WifiInfo,
network: Network, network: Network,
networkCapabilities: NetworkCapabilities, networkCapabilities: NetworkCapabilities,
wifiManager: WifiManager?, wifiManager: WifiManager,
): WifiNetworkModel { ): WifiNetworkModel {
return if (wifiInfo.isCarrierMerged) { return if (wifiInfo.isCarrierMerged) {
WifiNetworkModel.CarrierMerged WifiNetworkModel.CarrierMerged
@@ -279,7 +274,7 @@ class WifiRepositoryImpl @Inject constructor(
WifiNetworkModel.Active( WifiNetworkModel.Active(
network.getNetId(), network.getNetId(),
isValidated = networkCapabilities.hasCapability(NET_CAPABILITY_VALIDATED), isValidated = networkCapabilities.hasCapability(NET_CAPABILITY_VALIDATED),
level = wifiManager?.calculateSignalLevel(wifiInfo.rssi), level = wifiManager.calculateSignalLevel(wifiInfo.rssi),
wifiInfo.ssid, wifiInfo.ssid,
wifiInfo.isPasspointAp, wifiInfo.isPasspointAp,
wifiInfo.isOsuAp, wifiInfo.isOsuAp,
@@ -308,4 +303,28 @@ class WifiRepositoryImpl @Inject constructor(
private const val WIFI_NETWORK_CALLBACK_NAME = "wifiNetworkModel" private const val WIFI_NETWORK_CALLBACK_NAME = "wifiNetworkModel"
} }
@SysUISingleton
class Factory
@Inject
constructor(
private val broadcastDispatcher: BroadcastDispatcher,
private val connectivityManager: ConnectivityManager,
private val logger: ConnectivityPipelineLogger,
@WifiTableLog private val wifiTableLogBuffer: TableLogBuffer,
@Main private val mainExecutor: Executor,
@Application private val scope: CoroutineScope,
) {
fun create(wifiManager: WifiManager): WifiRepositoryImpl {
return WifiRepositoryImpl(
broadcastDispatcher,
connectivityManager,
logger,
wifiTableLogBuffer,
mainExecutor,
scope,
wifiManager,
)
}
}
} }

View File

@@ -65,6 +65,7 @@ class WifiInteractorImpl @Inject constructor(
override val ssid: Flow<String?> = wifiRepository.wifiNetwork.map { info -> override val ssid: Flow<String?> = wifiRepository.wifiNetwork.map { info ->
when (info) { when (info) {
is WifiNetworkModel.Unavailable -> null
is WifiNetworkModel.Inactive -> null is WifiNetworkModel.Inactive -> null
is WifiNetworkModel.CarrierMerged -> null is WifiNetworkModel.CarrierMerged -> null
is WifiNetworkModel.Active -> when { is WifiNetworkModel.Active -> when {

View File

@@ -82,6 +82,7 @@ constructor(
/** Returns the icon to use based on the given network. */ /** Returns the icon to use based on the given network. */
private fun WifiNetworkModel.icon(): WifiIcon { private fun WifiNetworkModel.icon(): WifiIcon {
return when (this) { return when (this) {
is WifiNetworkModel.Unavailable -> WifiIcon.Hidden
is WifiNetworkModel.CarrierMerged -> WifiIcon.Hidden is WifiNetworkModel.CarrierMerged -> WifiIcon.Hidden
is WifiNetworkModel.Inactive -> WifiIcon.Visible( is WifiNetworkModel.Inactive -> WifiIcon.Visible(
res = WIFI_NO_NETWORK, res = WIFI_NO_NETWORK,
@@ -89,25 +90,21 @@ constructor(
"${context.getString(WIFI_NO_CONNECTION)},${context.getString(NO_INTERNET)}" "${context.getString(WIFI_NO_CONNECTION)},${context.getString(NO_INTERNET)}"
) )
) )
is WifiNetworkModel.Active -> is WifiNetworkModel.Active -> {
when (this.level) {
null -> WifiIcon.Hidden
else -> {
val levelDesc = context.getString(WIFI_CONNECTION_STRENGTH[this.level]) val levelDesc = context.getString(WIFI_CONNECTION_STRENGTH[this.level])
when { when {
this.isValidated -> this.isValidated ->
WifiIcon.Visible( WifiIcon.Visible(
WIFI_FULL_ICONS[this.level], WIFI_FULL_ICONS[this.level],
ContentDescription.Loaded(levelDesc) ContentDescription.Loaded(levelDesc),
) )
else -> else ->
WifiIcon.Visible( WifiIcon.Visible(
WIFI_NO_INTERNET_ICONS[this.level], WIFI_NO_INTERNET_ICONS[this.level],
ContentDescription.Loaded( ContentDescription.Loaded(
"$levelDesc,${context.getString(NO_INTERNET)}" "$levelDesc,${context.getString(NO_INTERNET)}"
),
) )
)
}
} }
} }
} }

View File

@@ -19,6 +19,7 @@ package com.android.systemui.statusbar.pipeline.mobile.data.repository
import com.android.systemui.log.table.TableLogBuffer import com.android.systemui.log.table.TableLogBuffer
import com.android.systemui.statusbar.pipeline.mobile.data.model.MobileConnectionModel import com.android.systemui.statusbar.pipeline.mobile.data.model.MobileConnectionModel
import com.android.systemui.statusbar.pipeline.mobile.data.model.NetworkNameModel import com.android.systemui.statusbar.pipeline.mobile.data.model.NetworkNameModel
import com.android.systemui.statusbar.pipeline.mobile.data.repository.MobileConnectionRepository.Companion.DEFAULT_NUM_LEVELS
import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.MutableStateFlow
// TODO(b/261632894): remove this in favor of the real impl or DemoMobileConnectionRepository // TODO(b/261632894): remove this in favor of the real impl or DemoMobileConnectionRepository
@@ -29,12 +30,11 @@ class FakeMobileConnectionRepository(
private val _connectionInfo = MutableStateFlow(MobileConnectionModel()) private val _connectionInfo = MutableStateFlow(MobileConnectionModel())
override val connectionInfo = _connectionInfo override val connectionInfo = _connectionInfo
override val numberOfLevels = MutableStateFlow(DEFAULT_NUM_LEVELS)
private val _dataEnabled = MutableStateFlow(true) private val _dataEnabled = MutableStateFlow(true)
override val dataEnabled = _dataEnabled override val dataEnabled = _dataEnabled
private val _isDefaultDataSubscription = MutableStateFlow(true)
override val isDefaultDataSubscription = _isDefaultDataSubscription
override val cdmaRoaming = MutableStateFlow(false) override val cdmaRoaming = MutableStateFlow(false)
override val networkName = override val networkName =
@@ -47,8 +47,4 @@ class FakeMobileConnectionRepository(
fun setDataEnabled(enabled: Boolean) { fun setDataEnabled(enabled: Boolean) {
_dataEnabled.value = enabled _dataEnabled.value = enabled
} }
fun setIsDefaultDataSubscription(isDefault: Boolean) {
_isDefaultDataSubscription.value = isDefault
}
} }

View File

@@ -57,9 +57,6 @@ class FakeMobileConnectionsRepository(
private val _activeMobileDataSubscriptionId = MutableStateFlow(INVALID_SUBSCRIPTION_ID) private val _activeMobileDataSubscriptionId = MutableStateFlow(INVALID_SUBSCRIPTION_ID)
override val activeMobileDataSubscriptionId = _activeMobileDataSubscriptionId override val activeMobileDataSubscriptionId = _activeMobileDataSubscriptionId
private val _defaultDataSubId = MutableStateFlow(INVALID_SUBSCRIPTION_ID)
override val defaultDataSubId = _defaultDataSubId
private val _mobileConnectivity = MutableStateFlow(MobileConnectivityModel()) private val _mobileConnectivity = MutableStateFlow(MobileConnectivityModel())
override val defaultMobileNetworkConnectivity = _mobileConnectivity override val defaultMobileNetworkConnectivity = _mobileConnectivity
@@ -84,10 +81,6 @@ class FakeMobileConnectionsRepository(
_subscriptions.value = subs _subscriptions.value = subs
} }
fun setDefaultDataSubId(id: Int) {
_defaultDataSubId.value = id
}
fun setMobileConnectivity(model: MobileConnectivityModel) { fun setMobileConnectivity(model: MobileConnectivityModel) {
_mobileConnectivity.value = model _mobileConnectivity.value = model
} }

View File

@@ -61,6 +61,7 @@ import com.android.systemui.statusbar.pipeline.mobile.data.model.ResolvedNetwork
import com.android.systemui.statusbar.pipeline.mobile.data.model.ResolvedNetworkType.UnknownNetworkType import com.android.systemui.statusbar.pipeline.mobile.data.model.ResolvedNetworkType.UnknownNetworkType
import com.android.systemui.statusbar.pipeline.mobile.data.model.toNetworkNameModel import com.android.systemui.statusbar.pipeline.mobile.data.model.toNetworkNameModel
import com.android.systemui.statusbar.pipeline.mobile.data.repository.FakeMobileConnectionsRepository import com.android.systemui.statusbar.pipeline.mobile.data.repository.FakeMobileConnectionsRepository
import com.android.systemui.statusbar.pipeline.mobile.data.repository.MobileConnectionRepository.Companion.DEFAULT_NUM_LEVELS
import com.android.systemui.statusbar.pipeline.mobile.util.FakeMobileMappingsProxy import com.android.systemui.statusbar.pipeline.mobile.util.FakeMobileMappingsProxy
import com.android.systemui.statusbar.pipeline.shared.ConnectivityPipelineLogger import com.android.systemui.statusbar.pipeline.shared.ConnectivityPipelineLogger
import com.android.systemui.statusbar.pipeline.shared.data.model.DataActivityModel import com.android.systemui.statusbar.pipeline.shared.data.model.DataActivityModel
@@ -117,7 +118,6 @@ class MobileConnectionRepositoryTest : SysuiTestCase() {
telephonyManager, telephonyManager,
globalSettings, globalSettings,
fakeBroadcastDispatcher, fakeBroadcastDispatcher,
connectionsRepo.defaultDataSubId,
connectionsRepo.globalMobileDataSettingChangedEvent, connectionsRepo.globalMobileDataSettingChangedEvent,
mobileMappings, mobileMappings,
IMMEDIATE, IMMEDIATE,
@@ -319,7 +319,7 @@ class MobileConnectionRepositoryTest : SysuiTestCase() {
val callback = getTelephonyCallbackForType<TelephonyCallback.DisplayInfoListener>() val callback = getTelephonyCallbackForType<TelephonyCallback.DisplayInfoListener>()
val type = NETWORK_TYPE_LTE val type = NETWORK_TYPE_LTE
val expected = DefaultNetworkType(type, mobileMappings.toIconKey(type)) val expected = DefaultNetworkType(mobileMappings.toIconKey(type))
val ti = mock<TelephonyDisplayInfo>().also { whenever(it.networkType).thenReturn(type) } val ti = mock<TelephonyDisplayInfo>().also { whenever(it.networkType).thenReturn(type) }
callback.onDisplayInfoChanged(ti) callback.onDisplayInfoChanged(ti)
@@ -336,7 +336,7 @@ class MobileConnectionRepositoryTest : SysuiTestCase() {
val callback = getTelephonyCallbackForType<TelephonyCallback.DisplayInfoListener>() val callback = getTelephonyCallbackForType<TelephonyCallback.DisplayInfoListener>()
val type = OVERRIDE_NETWORK_TYPE_LTE_CA val type = OVERRIDE_NETWORK_TYPE_LTE_CA
val expected = OverrideNetworkType(type, mobileMappings.toIconKeyOverride(type)) val expected = OverrideNetworkType(mobileMappings.toIconKeyOverride(type))
val ti = val ti =
mock<TelephonyDisplayInfo>().also { mock<TelephonyDisplayInfo>().also {
whenever(it.networkType).thenReturn(type) whenever(it.networkType).thenReturn(type)
@@ -379,33 +379,6 @@ class MobileConnectionRepositoryTest : SysuiTestCase() {
job.cancel() job.cancel()
} }
@Test
fun isDefaultDataSubscription_isDefault() =
runBlocking(IMMEDIATE) {
connectionsRepo.setDefaultDataSubId(SUB_1_ID)
var latest: Boolean? = null
val job = underTest.isDefaultDataSubscription.onEach { latest = it }.launchIn(this)
assertThat(latest).isTrue()
job.cancel()
}
@Test
fun isDefaultDataSubscription_isNotDefault() =
runBlocking(IMMEDIATE) {
// Our subId is SUB_1_ID
connectionsRepo.setDefaultDataSubId(123)
var latest: Boolean? = null
val job = underTest.isDefaultDataSubscription.onEach { latest = it }.launchIn(this)
assertThat(latest).isFalse()
job.cancel()
}
@Test @Test
fun isDataConnectionAllowed_subIdSettingUpdate_valueUpdated() = fun isDataConnectionAllowed_subIdSettingUpdate_valueUpdated() =
runBlocking(IMMEDIATE) { runBlocking(IMMEDIATE) {
@@ -430,6 +403,17 @@ class MobileConnectionRepositoryTest : SysuiTestCase() {
job.cancel() job.cancel()
} }
@Test
fun numberOfLevels_isDefault() =
runBlocking(IMMEDIATE) {
var latest: Int? = null
val job = underTest.numberOfLevels.onEach { latest = it }.launchIn(this)
assertThat(latest).isEqualTo(DEFAULT_NUM_LEVELS)
job.cancel()
}
@Test @Test
fun `roaming - cdma - queries telephony manager`() = fun `roaming - cdma - queries telephony manager`() =
runBlocking(IMMEDIATE) { runBlocking(IMMEDIATE) {

View File

@@ -306,35 +306,6 @@ class MobileConnectionsRepositoryTest : SysuiTestCase() {
job.cancel() job.cancel()
} }
@Test
fun testDefaultDataSubId_updatesOnBroadcast() =
runBlocking(IMMEDIATE) {
var latest: Int? = null
val job = underTest.defaultDataSubId.onEach { latest = it }.launchIn(this)
fakeBroadcastDispatcher.registeredReceivers.forEach { receiver ->
receiver.onReceive(
context,
Intent(TelephonyManager.ACTION_DEFAULT_DATA_SUBSCRIPTION_CHANGED)
.putExtra(PhoneConstants.SUBSCRIPTION_KEY, SUB_2_ID)
)
}
assertThat(latest).isEqualTo(SUB_2_ID)
fakeBroadcastDispatcher.registeredReceivers.forEach { receiver ->
receiver.onReceive(
context,
Intent(TelephonyManager.ACTION_DEFAULT_DATA_SUBSCRIPTION_CHANGED)
.putExtra(PhoneConstants.SUBSCRIPTION_KEY, SUB_1_ID)
)
}
assertThat(latest).isEqualTo(SUB_1_ID)
job.cancel()
}
@Test @Test
fun mobileConnectivity_default() { fun mobileConnectivity_default() {
assertThat(underTest.defaultMobileNetworkConnectivity.value) assertThat(underTest.defaultMobileNetworkConnectivity.value)

View File

@@ -21,6 +21,7 @@ import com.android.settingslib.SignalIcon
import com.android.settingslib.mobile.TelephonyIcons import com.android.settingslib.mobile.TelephonyIcons
import com.android.systemui.log.table.TableLogBuffer import com.android.systemui.log.table.TableLogBuffer
import com.android.systemui.statusbar.pipeline.mobile.data.model.NetworkNameModel import com.android.systemui.statusbar.pipeline.mobile.data.model.NetworkNameModel
import com.android.systemui.statusbar.pipeline.mobile.data.repository.MobileConnectionRepository.Companion.DEFAULT_NUM_LEVELS
import com.android.systemui.statusbar.pipeline.shared.data.model.DataActivityModel import com.android.systemui.statusbar.pipeline.shared.data.model.DataActivityModel
import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.MutableStateFlow
@@ -65,7 +66,7 @@ class FakeMobileIconInteractor(
private val _level = MutableStateFlow(CellSignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN) private val _level = MutableStateFlow(CellSignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN)
override val level = _level override val level = _level
private val _numberOfLevels = MutableStateFlow(4) private val _numberOfLevels = MutableStateFlow(DEFAULT_NUM_LEVELS)
override val numberOfLevels = _numberOfLevels override val numberOfLevels = _numberOfLevels
fun setIconGroup(group: SignalIcon.MobileIconGroup) { fun setIconGroup(group: SignalIcon.MobileIconGroup) {

View File

@@ -17,7 +17,6 @@
package com.android.systemui.statusbar.pipeline.mobile.domain.interactor package com.android.systemui.statusbar.pipeline.mobile.domain.interactor
import android.telephony.CellSignalStrength import android.telephony.CellSignalStrength
import android.telephony.SubscriptionInfo
import android.telephony.TelephonyManager.NETWORK_TYPE_UNKNOWN import android.telephony.TelephonyManager.NETWORK_TYPE_UNKNOWN
import androidx.test.filters.SmallTest import androidx.test.filters.SmallTest
import com.android.settingslib.SignalIcon.MobileIconGroup import com.android.settingslib.SignalIcon.MobileIconGroup
@@ -34,7 +33,6 @@ import com.android.systemui.statusbar.pipeline.mobile.domain.interactor.FakeMobi
import com.android.systemui.statusbar.pipeline.mobile.domain.interactor.FakeMobileIconsInteractor.Companion.THREE_G import com.android.systemui.statusbar.pipeline.mobile.domain.interactor.FakeMobileIconsInteractor.Companion.THREE_G
import com.android.systemui.statusbar.pipeline.mobile.util.FakeMobileMappingsProxy import com.android.systemui.statusbar.pipeline.mobile.util.FakeMobileMappingsProxy
import com.android.systemui.util.mockito.mock import com.android.systemui.util.mockito.mock
import com.android.systemui.util.mockito.whenever
import com.google.common.truth.Truth.assertThat import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
@@ -177,13 +175,27 @@ class MobileIconInteractorTest : SysuiTestCase() {
job.cancel() job.cancel()
} }
@Test
fun numberOfLevels_comesFromRepo() =
runBlocking(IMMEDIATE) {
var latest: Int? = null
val job = underTest.numberOfLevels.onEach { latest = it }.launchIn(this)
connectionRepository.numberOfLevels.value = 5
assertThat(latest).isEqualTo(5)
connectionRepository.numberOfLevels.value = 4
assertThat(latest).isEqualTo(4)
job.cancel()
}
@Test @Test
fun iconGroup_three_g() = fun iconGroup_three_g() =
runBlocking(IMMEDIATE) { runBlocking(IMMEDIATE) {
connectionRepository.setConnectionInfo( connectionRepository.setConnectionInfo(
MobileConnectionModel( MobileConnectionModel(
resolvedNetworkType = resolvedNetworkType = DefaultNetworkType(mobileMappingsProxy.toIconKey(THREE_G))
DefaultNetworkType(THREE_G, mobileMappingsProxy.toIconKey(THREE_G))
), ),
) )
@@ -200,8 +212,7 @@ class MobileIconInteractorTest : SysuiTestCase() {
runBlocking(IMMEDIATE) { runBlocking(IMMEDIATE) {
connectionRepository.setConnectionInfo( connectionRepository.setConnectionInfo(
MobileConnectionModel( MobileConnectionModel(
resolvedNetworkType = resolvedNetworkType = DefaultNetworkType(mobileMappingsProxy.toIconKey(THREE_G))
DefaultNetworkType(THREE_G, mobileMappingsProxy.toIconKey(THREE_G))
), ),
) )
@@ -212,7 +223,6 @@ class MobileIconInteractorTest : SysuiTestCase() {
MobileConnectionModel( MobileConnectionModel(
resolvedNetworkType = resolvedNetworkType =
DefaultNetworkType( DefaultNetworkType(
FOUR_G,
mobileMappingsProxy.toIconKey(FOUR_G), mobileMappingsProxy.toIconKey(FOUR_G),
), ),
), ),
@@ -230,10 +240,7 @@ class MobileIconInteractorTest : SysuiTestCase() {
connectionRepository.setConnectionInfo( connectionRepository.setConnectionInfo(
MobileConnectionModel( MobileConnectionModel(
resolvedNetworkType = resolvedNetworkType =
OverrideNetworkType( OverrideNetworkType(mobileMappingsProxy.toIconKeyOverride(FIVE_G_OVERRIDE))
FIVE_G_OVERRIDE,
mobileMappingsProxy.toIconKeyOverride(FIVE_G_OVERRIDE)
)
), ),
) )
@@ -251,10 +258,7 @@ class MobileIconInteractorTest : SysuiTestCase() {
connectionRepository.setConnectionInfo( connectionRepository.setConnectionInfo(
MobileConnectionModel( MobileConnectionModel(
resolvedNetworkType = resolvedNetworkType =
DefaultNetworkType( DefaultNetworkType(mobileMappingsProxy.toIconKey(NETWORK_TYPE_UNKNOWN)),
NETWORK_TYPE_UNKNOWN,
mobileMappingsProxy.toIconKey(NETWORK_TYPE_UNKNOWN)
),
), ),
) )
@@ -509,8 +513,6 @@ class MobileIconInteractorTest : SysuiTestCase() {
private const val CDMA_LEVEL = 2 private const val CDMA_LEVEL = 2
private const val SUB_1_ID = 1 private const val SUB_1_ID = 1
private val SUB_1 =
mock<SubscriptionInfo>().also { whenever(it.subscriptionId).thenReturn(SUB_1_ID) }
private val DEFAULT_NAME = NetworkNameModel.Default("test default name") private val DEFAULT_NAME = NetworkNameModel.Default("test default name")
private val DERIVED_NAME = NetworkNameModel.Derived("test derived name") private val DERIVED_NAME = NetworkNameModel.Derived("test derived name")

View File

@@ -34,12 +34,6 @@ class WifiNetworkModelTest : SysuiTestCase() {
} }
} }
@Test
fun active_levelNull_noException() {
WifiNetworkModel.Active(NETWORK_ID, level = null)
// No assert, just need no crash
}
@Test(expected = IllegalArgumentException::class) @Test(expected = IllegalArgumentException::class)
fun active_levelNegative_exceptionThrown() { fun active_levelNegative_exceptionThrown() {
WifiNetworkModel.Active(NETWORK_ID, level = MIN_VALID_LEVEL - 1) WifiNetworkModel.Active(NETWORK_ID, level = MIN_VALID_LEVEL - 1)

View File

@@ -0,0 +1,57 @@
/*
* 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.prod
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.statusbar.pipeline.shared.data.model.DataActivityModel
import com.android.systemui.statusbar.pipeline.wifi.data.model.WifiNetworkModel
import com.google.common.truth.Truth.assertThat
import org.junit.Before
import org.junit.Test
@SmallTest
class DisabledWifiRepositoryTest : SysuiTestCase() {
private lateinit var underTest: DisabledWifiRepository
@Before
fun setUp() {
underTest = DisabledWifiRepository()
}
@Test
fun enabled_alwaysFalse() {
assertThat(underTest.isWifiEnabled.value).isEqualTo(false)
}
@Test
fun default_alwaysFalse() {
assertThat(underTest.isWifiDefault.value).isEqualTo(false)
}
@Test
fun network_alwaysUnavailable() {
assertThat(underTest.wifiNetwork.value).isEqualTo(WifiNetworkModel.Unavailable)
}
@Test
fun activity_alwaysFalse() {
assertThat(underTest.wifiActivity.value)
.isEqualTo(DataActivityModel(hasActivityIn = false, hasActivityOut = false))
}
}

View File

@@ -33,7 +33,6 @@ import com.android.systemui.log.table.TableLogBuffer
import com.android.systemui.statusbar.pipeline.shared.ConnectivityPipelineLogger import com.android.systemui.statusbar.pipeline.shared.ConnectivityPipelineLogger
import com.android.systemui.statusbar.pipeline.shared.data.model.DataActivityModel import com.android.systemui.statusbar.pipeline.shared.data.model.DataActivityModel
import com.android.systemui.statusbar.pipeline.wifi.data.model.WifiNetworkModel import com.android.systemui.statusbar.pipeline.wifi.data.model.WifiNetworkModel
import com.android.systemui.statusbar.pipeline.wifi.data.repository.prod.WifiRepositoryImpl.Companion.ACTIVITY_DEFAULT
import com.android.systemui.statusbar.pipeline.wifi.data.repository.prod.WifiRepositoryImpl.Companion.WIFI_NETWORK_DEFAULT import com.android.systemui.statusbar.pipeline.wifi.data.repository.prod.WifiRepositoryImpl.Companion.WIFI_NETWORK_DEFAULT
import com.android.systemui.util.concurrency.FakeExecutor import com.android.systemui.util.concurrency.FakeExecutor
import com.android.systemui.util.mockito.any import com.android.systemui.util.mockito.any
@@ -97,13 +96,6 @@ class WifiRepositoryImplTest : SysuiTestCase() {
scope.cancel() scope.cancel()
} }
@Test
fun isWifiEnabled_nullWifiManager_getsFalse() = runBlocking(IMMEDIATE) {
underTest = createRepo(wifiManagerToUse = null)
assertThat(underTest.isWifiEnabled.value).isFalse()
}
@Test @Test
fun isWifiEnabled_initiallyGetsWifiManagerValue() = runBlocking(IMMEDIATE) { fun isWifiEnabled_initiallyGetsWifiManagerValue() = runBlocking(IMMEDIATE) {
whenever(wifiManager.isWifiEnabled).thenReturn(true) whenever(wifiManager.isWifiEnabled).thenReturn(true)
@@ -720,21 +712,6 @@ class WifiRepositoryImplTest : SysuiTestCase() {
job2.cancel() job2.cancel()
} }
@Test
fun wifiActivity_nullWifiManager_receivesDefault() = runBlocking(IMMEDIATE) {
underTest = createRepo(wifiManagerToUse = null)
var latest: DataActivityModel? = null
val job = underTest
.wifiActivity
.onEach { latest = it }
.launchIn(this)
assertThat(latest).isEqualTo(ACTIVITY_DEFAULT)
job.cancel()
}
@Test @Test
fun wifiActivity_callbackGivesNone_activityFlowHasNone() = runBlocking(IMMEDIATE) { fun wifiActivity_callbackGivesNone_activityFlowHasNone() = runBlocking(IMMEDIATE) {
var latest: DataActivityModel? = null var latest: DataActivityModel? = null
@@ -801,7 +778,7 @@ class WifiRepositoryImplTest : SysuiTestCase() {
job.cancel() job.cancel()
} }
private fun createRepo(wifiManagerToUse: WifiManager? = wifiManager): WifiRepositoryImpl { private fun createRepo(): WifiRepositoryImpl {
return WifiRepositoryImpl( return WifiRepositoryImpl(
broadcastDispatcher, broadcastDispatcher,
connectivityManager, connectivityManager,
@@ -809,7 +786,7 @@ class WifiRepositoryImplTest : SysuiTestCase() {
tableLogger, tableLogger,
executor, executor,
scope, scope,
wifiManagerToUse, wifiManager,
) )
} }

View File

@@ -51,6 +51,22 @@ class WifiInteractorImplTest : SysuiTestCase() {
underTest = WifiInteractorImpl(connectivityRepository, wifiRepository) underTest = WifiInteractorImpl(connectivityRepository, wifiRepository)
} }
@Test
fun ssid_unavailableNetwork_outputsNull() =
runBlocking(IMMEDIATE) {
wifiRepository.setWifiNetwork(WifiNetworkModel.Unavailable)
var latest: String? = "default"
val job = underTest
.ssid
.onEach { latest = it }
.launchIn(this)
assertThat(latest).isNull()
job.cancel()
}
@Test @Test
fun ssid_inactiveNetwork_outputsNull() = runBlocking(IMMEDIATE) { fun ssid_inactiveNetwork_outputsNull() = runBlocking(IMMEDIATE) {
wifiRepository.setWifiNetwork(WifiNetworkModel.Inactive) wifiRepository.setWifiNetwork(WifiNetworkModel.Inactive)
@@ -85,6 +101,7 @@ class WifiInteractorImplTest : SysuiTestCase() {
fun ssid_isPasspointAccessPoint_outputsPasspointName() = runBlocking(IMMEDIATE) { fun ssid_isPasspointAccessPoint_outputsPasspointName() = runBlocking(IMMEDIATE) {
wifiRepository.setWifiNetwork(WifiNetworkModel.Active( wifiRepository.setWifiNetwork(WifiNetworkModel.Active(
networkId = 1, networkId = 1,
level = 1,
isPasspointAccessPoint = true, isPasspointAccessPoint = true,
passpointProviderFriendlyName = "friendly", passpointProviderFriendlyName = "friendly",
)) ))
@@ -104,6 +121,7 @@ class WifiInteractorImplTest : SysuiTestCase() {
fun ssid_isOnlineSignUpForPasspoint_outputsPasspointName() = runBlocking(IMMEDIATE) { fun ssid_isOnlineSignUpForPasspoint_outputsPasspointName() = runBlocking(IMMEDIATE) {
wifiRepository.setWifiNetwork(WifiNetworkModel.Active( wifiRepository.setWifiNetwork(WifiNetworkModel.Active(
networkId = 1, networkId = 1,
level = 1,
isOnlineSignUpForPasspointAccessPoint = true, isOnlineSignUpForPasspointAccessPoint = true,
passpointProviderFriendlyName = "friendly", passpointProviderFriendlyName = "friendly",
)) ))
@@ -123,6 +141,7 @@ class WifiInteractorImplTest : SysuiTestCase() {
fun ssid_unknownSsid_outputsNull() = runBlocking(IMMEDIATE) { fun ssid_unknownSsid_outputsNull() = runBlocking(IMMEDIATE) {
wifiRepository.setWifiNetwork(WifiNetworkModel.Active( wifiRepository.setWifiNetwork(WifiNetworkModel.Active(
networkId = 1, networkId = 1,
level = 1,
ssid = WifiManager.UNKNOWN_SSID, ssid = WifiManager.UNKNOWN_SSID,
)) ))
@@ -141,6 +160,7 @@ class WifiInteractorImplTest : SysuiTestCase() {
fun ssid_validSsid_outputsSsid() = runBlocking(IMMEDIATE) { fun ssid_validSsid_outputsSsid() = runBlocking(IMMEDIATE) {
wifiRepository.setWifiNetwork(WifiNetworkModel.Active( wifiRepository.setWifiNetwork(WifiNetworkModel.Active(
networkId = 1, networkId = 1,
level = 1,
ssid = "MyAwesomeWifiNetwork", ssid = "MyAwesomeWifiNetwork",
)) ))

View File

@@ -379,6 +379,12 @@ internal class WifiViewModelIconParameterizedTest(private val testCase: TestCase
expected = null, expected = null,
), ),
// network = Unavailable => not shown
TestCase(
network = WifiNetworkModel.Unavailable,
expected = null,
),
// network = Active & validated = false => not shown // network = Active & validated = false => not shown
TestCase( TestCase(
network = WifiNetworkModel.Active(NETWORK_ID, isValidated = false, level = 3), network = WifiNetworkModel.Active(NETWORK_ID, isValidated = false, level = 3),
@@ -397,12 +403,6 @@ internal class WifiViewModelIconParameterizedTest(private val testCase: TestCase
description = "Full internet level 4 icon", description = "Full internet level 4 icon",
), ),
), ),
// network has null level => not shown
TestCase(
network = WifiNetworkModel.Active(NETWORK_ID, isValidated = true, level = null),
expected = null,
),
) )
} }
} }

View File

@@ -228,7 +228,7 @@ class WifiViewModelTest : SysuiTestCase() {
whenever(connectivityConstants.shouldShowActivityConfig).thenReturn(true) whenever(connectivityConstants.shouldShowActivityConfig).thenReturn(true)
createAndSetViewModel() createAndSetViewModel()
wifiRepository.setWifiNetwork(WifiNetworkModel.Active(NETWORK_ID, ssid = null)) wifiRepository.setWifiNetwork(WifiNetworkModel.Active(NETWORK_ID, ssid = null, level = 1))
var activityIn: Boolean? = null var activityIn: Boolean? = null
val activityInJob = underTest val activityInJob = underTest
@@ -553,7 +553,8 @@ class WifiViewModelTest : SysuiTestCase() {
companion object { companion object {
private const val NETWORK_ID = 2 private const val NETWORK_ID = 2
private val ACTIVE_VALID_WIFI_NETWORK = WifiNetworkModel.Active(NETWORK_ID, ssid = "AB") private val ACTIVE_VALID_WIFI_NETWORK =
WifiNetworkModel.Active(NETWORK_ID, ssid = "AB", level = 1)
} }
} }