Merge changes Ieb73c357,I7f5bc07b,I01b33b24,I873e57bf,I8de76ad5 into tm-qpr-dev
* changes: [SB Refactor] Remove `type` from ResolvedNetworkType. [SB Refactor] Make `numberOfLevels` a flow at the repo level. [SB Refactor] Remove unused `isDefaultDataSubscription` flow. [SB Refactor] Run the linter on WifiRepositoryImpl. [SB Refactor] Provide a disabled wifi repo if there's no wifi manager.
This commit is contained in:
committed by
Android (Google) Code Review
commit
b9115ca03b
@@ -460,7 +460,6 @@
|
||||
-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/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/shared/WifiConstants.kt
|
||||
-packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/ui/view/ModernStatusBarWifiView.kt
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package com.android.systemui.statusbar.pipeline.dagger
|
||||
|
||||
import android.net.wifi.WifiManager
|
||||
import com.android.systemui.CoreStartable
|
||||
import com.android.systemui.dagger.SysUISingleton
|
||||
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.shared.data.repository.ConnectivityRepository
|
||||
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.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.WifiInteractorImpl
|
||||
import dagger.Binds
|
||||
@@ -78,9 +82,23 @@ abstract class StatusBarPipelineModule {
|
||||
@ClassKey(MobileUiAdapter::class)
|
||||
abstract fun bindFeature(impl: MobileUiAdapter): CoreStartable
|
||||
|
||||
@Module
|
||||
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
|
||||
@SysUISingleton
|
||||
@WifiTableLog
|
||||
@@ -88,7 +106,6 @@ abstract class StatusBarPipelineModule {
|
||||
return factory.create("WifiTableLog", 100)
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
@Provides
|
||||
@SysUISingleton
|
||||
@AirplaneTableLog
|
||||
|
||||
@@ -17,7 +17,6 @@
|
||||
package com.android.systemui.statusbar.pipeline.mobile.data.model
|
||||
|
||||
import android.telephony.Annotation.NetworkType
|
||||
import android.telephony.TelephonyManager.NETWORK_TYPE_UNKNOWN
|
||||
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.
|
||||
*/
|
||||
sealed interface ResolvedNetworkType {
|
||||
@NetworkType val type: Int
|
||||
val lookupKey: String
|
||||
|
||||
object UnknownNetworkType : ResolvedNetworkType {
|
||||
override val type: Int = NETWORK_TYPE_UNKNOWN
|
||||
override val lookupKey: String = "unknown"
|
||||
}
|
||||
|
||||
data class DefaultNetworkType(
|
||||
@NetworkType override val type: Int,
|
||||
override val lookupKey: String,
|
||||
) : ResolvedNetworkType
|
||||
|
||||
data class OverrideNetworkType(
|
||||
@NetworkType override val type: Int,
|
||||
override val lookupKey: String,
|
||||
) : ResolvedNetworkType
|
||||
}
|
||||
|
||||
@@ -17,7 +17,6 @@
|
||||
package com.android.systemui.statusbar.pipeline.mobile.data.repository
|
||||
|
||||
import android.telephony.SubscriptionInfo
|
||||
import android.telephony.SubscriptionManager
|
||||
import android.telephony.TelephonyCallback
|
||||
import android.telephony.TelephonyManager
|
||||
import com.android.systemui.log.table.TableLogBuffer
|
||||
@@ -52,13 +51,12 @@ interface MobileConnectionRepository {
|
||||
* listener + model.
|
||||
*/
|
||||
val connectionInfo: Flow<MobileConnectionModel>
|
||||
|
||||
/** The total number of levels. Used with [SignalDrawable]. */
|
||||
val numberOfLevels: StateFlow<Int>
|
||||
|
||||
/** Observable tracking [TelephonyManager.isDataConnectionAllowed] */
|
||||
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
|
||||
@@ -70,4 +68,9 @@ interface MobileConnectionRepository {
|
||||
|
||||
/** The service provider name for this network connection, or the default name */
|
||||
val networkName: StateFlow<NetworkNameModel>
|
||||
|
||||
companion object {
|
||||
/** The default number of levels to use for [numberOfLevels]. */
|
||||
const val DEFAULT_NUM_LEVELS = 4
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,7 +18,6 @@ package com.android.systemui.statusbar.pipeline.mobile.data.repository
|
||||
|
||||
import android.provider.Settings
|
||||
import android.telephony.CarrierConfigManager
|
||||
import android.telephony.SubscriptionManager
|
||||
import com.android.settingslib.SignalIcon.MobileIconGroup
|
||||
import com.android.settingslib.mobile.MobileMappings
|
||||
import com.android.settingslib.mobile.MobileMappings.Config
|
||||
@@ -38,9 +37,6 @@ interface MobileConnectionsRepository {
|
||||
/** Observable for the subscriptionId of the current mobile data connection */
|
||||
val activeMobileDataSubscriptionId: StateFlow<Int>
|
||||
|
||||
/** Tracks [SubscriptionManager.getDefaultDataSubscriptionId] */
|
||||
val defaultDataSubId: StateFlow<Int>
|
||||
|
||||
/** The current connectivity status for the default mobile network connection */
|
||||
val defaultMobileNetworkConnectivity: StateFlow<MobileConnectivityModel>
|
||||
|
||||
|
||||
@@ -139,11 +139,6 @@ constructor(
|
||||
override val defaultMobileIconGroup: Flow<SignalIcon.MobileIconGroup> =
|
||||
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> =
|
||||
activeRepo
|
||||
.flatMapLatest { it.defaultMobileNetworkConnectivity }
|
||||
|
||||
@@ -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.SubscriptionModel
|
||||
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.demo.model.FakeNetworkEventModel
|
||||
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 }
|
||||
|
||||
// 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
|
||||
override val defaultMobileNetworkConnectivity = MutableStateFlow(MobileConnectivityModel())
|
||||
|
||||
@@ -199,7 +192,6 @@ constructor(
|
||||
val connection = getRepoForSubId(subId)
|
||||
// This is always true here, because we split out disabled states at the data-source level
|
||||
connection.dataEnabled.value = true
|
||||
connection.isDefaultDataSubscription.value = state.dataType != null
|
||||
connection.networkName.value = NetworkNameModel.Derived(state.name)
|
||||
|
||||
connection.cdmaRoaming.value = state.roaming
|
||||
@@ -261,15 +253,13 @@ constructor(
|
||||
|
||||
private fun SignalIcon.MobileIconGroup?.toResolvedNetworkType(): ResolvedNetworkType {
|
||||
val key = mobileMappingsReverseLookup.value[this] ?: "dis"
|
||||
return DefaultNetworkType(DEMO_NET_TYPE, key)
|
||||
return DefaultNetworkType(key)
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val TAG = "DemoMobileConnectionsRepo"
|
||||
|
||||
private const val DEFAULT_SUB_ID = 1
|
||||
|
||||
private const val DEMO_NET_TYPE = 1234
|
||||
}
|
||||
}
|
||||
|
||||
@@ -279,9 +269,9 @@ class DemoMobileConnectionRepository(
|
||||
) : MobileConnectionRepository {
|
||||
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)
|
||||
|
||||
|
||||
@@ -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.toNetworkNameModel
|
||||
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.shared.ConnectivityPipelineLogger
|
||||
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.StateFlow
|
||||
import kotlinx.coroutines.flow.distinctUntilChanged
|
||||
import kotlinx.coroutines.flow.flowOf
|
||||
import kotlinx.coroutines.flow.mapLatest
|
||||
import kotlinx.coroutines.flow.merge
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
@@ -78,7 +80,6 @@ class MobileConnectionRepositoryImpl(
|
||||
private val telephonyManager: TelephonyManager,
|
||||
private val globalSettings: GlobalSettings,
|
||||
broadcastDispatcher: BroadcastDispatcher,
|
||||
defaultDataSubId: StateFlow<Int>,
|
||||
globalMobileDataSettingChangedEvent: Flow<Unit>,
|
||||
mobileMappingsProxy: MobileMappingsProxy,
|
||||
bgDispatcher: CoroutineDispatcher,
|
||||
@@ -185,14 +186,12 @@ class MobileConnectionRepositoryImpl(
|
||||
OVERRIDE_NETWORK_TYPE_NONE
|
||||
) {
|
||||
DefaultNetworkType(
|
||||
telephonyDisplayInfo.networkType,
|
||||
mobileMappingsProxy.toIconKey(
|
||||
telephonyDisplayInfo.networkType
|
||||
)
|
||||
)
|
||||
} else {
|
||||
OverrideNetworkType(
|
||||
telephonyDisplayInfo.overrideNetworkType,
|
||||
mobileMappingsProxy.toIconKeyOverride(
|
||||
telephonyDisplayInfo.overrideNetworkType
|
||||
)
|
||||
@@ -214,6 +213,12 @@ class MobileConnectionRepositoryImpl(
|
||||
.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 */
|
||||
private val localMobileDataSettingChangedEvent: Flow<Unit> = conflatedCallbackFlow {
|
||||
val observer =
|
||||
@@ -284,20 +289,6 @@ class MobileConnectionRepositoryImpl(
|
||||
|
||||
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
|
||||
@Inject
|
||||
constructor(
|
||||
@@ -315,7 +306,6 @@ class MobileConnectionRepositoryImpl(
|
||||
subId: Int,
|
||||
defaultNetworkName: NetworkNameModel,
|
||||
networkNameSeparator: String,
|
||||
defaultDataSubId: StateFlow<Int>,
|
||||
globalMobileDataSettingChangedEvent: Flow<Unit>,
|
||||
): MobileConnectionRepository {
|
||||
val mobileLogger = logFactory.create(tableBufferLogName(subId), 100)
|
||||
@@ -328,7 +318,6 @@ class MobileConnectionRepositoryImpl(
|
||||
telephonyManager.createForSubscriptionId(subId),
|
||||
globalSettings,
|
||||
broadcastDispatcher,
|
||||
defaultDataSubId,
|
||||
globalMobileDataSettingChangedEvent,
|
||||
mobileMappingsProxy,
|
||||
bgDispatcher,
|
||||
|
||||
@@ -35,7 +35,6 @@ import android.telephony.TelephonyCallback
|
||||
import android.telephony.TelephonyCallback.ActiveDataSubscriptionIdListener
|
||||
import android.telephony.TelephonyManager
|
||||
import androidx.annotation.VisibleForTesting
|
||||
import com.android.internal.telephony.PhoneConstants
|
||||
import com.android.settingslib.SignalIcon.MobileIconGroup
|
||||
import com.android.settingslib.mobile.MobileMappings.Config
|
||||
import com.android.systemui.R
|
||||
@@ -60,7 +59,6 @@ import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
import kotlinx.coroutines.asExecutor
|
||||
import kotlinx.coroutines.channels.awaitClose
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.MutableSharedFlow
|
||||
import kotlinx.coroutines.flow.SharingStarted
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
import kotlinx.coroutines.flow.distinctUntilChanged
|
||||
@@ -142,24 +140,10 @@ constructor(
|
||||
.logInputChange(logger, "onActiveDataSubscriptionIdChanged")
|
||||
.stateIn(scope, started = SharingStarted.WhileSubscribed(), INVALID_SUBSCRIPTION_ID)
|
||||
|
||||
private val defaultDataSubIdChangeEvent: MutableSharedFlow<Unit> =
|
||||
MutableSharedFlow(extraBufferCapacity = 1)
|
||||
|
||||
override val defaultDataSubId: StateFlow<Int> =
|
||||
private val defaultDataSubIdChangedEvent =
|
||||
broadcastDispatcher
|
||||
.broadcastFlow(
|
||||
IntentFilter(TelephonyManager.ACTION_DEFAULT_DATA_SUBSCRIPTION_CHANGED)
|
||||
) { intent, _ ->
|
||||
intent.getIntExtra(PhoneConstants.SUBSCRIPTION_KEY, INVALID_SUBSCRIPTION_ID)
|
||||
}
|
||||
.distinctUntilChanged()
|
||||
.broadcastFlow(IntentFilter(TelephonyManager.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 =
|
||||
broadcastDispatcher
|
||||
@@ -167,7 +151,7 @@ constructor(
|
||||
.logInputChange(logger, "ACTION_CARRIER_CONFIG_CHANGED")
|
||||
|
||||
override val defaultDataSubRatConfig: StateFlow<Config> =
|
||||
merge(defaultDataSubIdChangeEvent, carrierConfigChangedEvent)
|
||||
merge(defaultDataSubIdChangedEvent, carrierConfigChangedEvent)
|
||||
.mapLatest { Config.readConfig(context) }
|
||||
.distinctUntilChanged()
|
||||
.logInputChange(logger, "defaultDataSubRatConfig")
|
||||
@@ -272,7 +256,6 @@ constructor(
|
||||
subId,
|
||||
defaultNetworkName,
|
||||
networkNameSeparator,
|
||||
defaultDataSubId,
|
||||
globalMobileDataSettingChangedEvent,
|
||||
)
|
||||
}
|
||||
|
||||
@@ -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.NetworkNameModel
|
||||
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.util.CarrierConfigTracker
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.SharingStarted
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
import kotlinx.coroutines.flow.combine
|
||||
@@ -171,11 +170,12 @@ class MobileIconInteractorImpl(
|
||||
}
|
||||
.stateIn(scope, SharingStarted.WhileSubscribed(), 0)
|
||||
|
||||
/**
|
||||
* 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> = MutableStateFlow(4)
|
||||
override val numberOfLevels: StateFlow<Int> =
|
||||
connectionRepository.numberOfLevels.stateIn(
|
||||
scope,
|
||||
SharingStarted.WhileSubscribed(),
|
||||
connectionRepository.numberOfLevels.value,
|
||||
)
|
||||
|
||||
override val isDataConnected: StateFlow<Boolean> =
|
||||
connectionInfo
|
||||
|
||||
@@ -23,6 +23,33 @@ import com.android.systemui.log.table.Diffable
|
||||
/** Provides information about the current wifi network. */
|
||||
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. */
|
||||
object Inactive : WifiNetworkModel() {
|
||||
override fun toString() = "WifiNetwork.Inactive"
|
||||
@@ -87,13 +114,8 @@ sealed class WifiNetworkModel : Diffable<WifiNetworkModel> {
|
||||
|
||||
/**
|
||||
* 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]. */
|
||||
val ssid: String? = null,
|
||||
@@ -108,7 +130,7 @@ sealed class WifiNetworkModel : Diffable<WifiNetworkModel> {
|
||||
val passpointProviderFriendlyName: String? = null,
|
||||
) : WifiNetworkModel() {
|
||||
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"
|
||||
}
|
||||
}
|
||||
@@ -125,11 +147,7 @@ sealed class WifiNetworkModel : Diffable<WifiNetworkModel> {
|
||||
row.logChange(COL_VALIDATED, isValidated)
|
||||
}
|
||||
if (prevVal !is Active || prevVal.level != level) {
|
||||
if (level != null) {
|
||||
row.logChange(COL_LEVEL, level)
|
||||
} else {
|
||||
row.logChange(COL_LEVEL, LEVEL_DEFAULT)
|
||||
}
|
||||
row.logChange(COL_LEVEL, level)
|
||||
}
|
||||
if (prevVal !is Active || prevVal.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_UNAVAILABLE = "Unavailable"
|
||||
const val TYPE_INACTIVE = "Inactive"
|
||||
const val TYPE_ACTIVE = "Active"
|
||||
|
||||
|
||||
@@ -34,3 +34,13 @@ interface WifiRepository {
|
||||
/** Observable for the current wifi network activity. */
|
||||
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
|
||||
|
||||
@@ -58,7 +58,7 @@ import kotlinx.coroutines.flow.stateIn
|
||||
class WifiRepositorySwitcher
|
||||
@Inject
|
||||
constructor(
|
||||
private val realImpl: WifiRepositoryImpl,
|
||||
private val realImpl: RealWifiRepository,
|
||||
private val demoImpl: DemoWifiRepository,
|
||||
private val demoModeController: DemoModeController,
|
||||
@Application scope: CoroutineScope,
|
||||
|
||||
@@ -89,7 +89,7 @@ constructor(
|
||||
WifiNetworkModel.Active(
|
||||
networkId = DEMO_NET_ID,
|
||||
isValidated = validated ?: true,
|
||||
level = level,
|
||||
level = level ?: 0,
|
||||
ssid = ssid,
|
||||
|
||||
// These fields below aren't supported in demo mode, since they aren't needed to satisfy
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
@@ -29,7 +29,6 @@ import android.net.NetworkRequest
|
||||
import android.net.wifi.WifiInfo
|
||||
import android.net.wifi.WifiManager
|
||||
import android.net.wifi.WifiManager.TrafficStateCallback
|
||||
import android.util.Log
|
||||
import com.android.settingslib.Utils
|
||||
import com.android.systemui.broadcast.BroadcastDispatcher
|
||||
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.statusbar.pipeline.dagger.WifiTableLog
|
||||
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.data.model.DataActivityModel
|
||||
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.repository.RealWifiRepository
|
||||
import com.android.systemui.statusbar.pipeline.wifi.data.repository.WifiRepository
|
||||
import java.util.concurrent.Executor
|
||||
import javax.inject.Inject
|
||||
@@ -53,12 +52,9 @@ import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
import kotlinx.coroutines.channels.awaitClose
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
import kotlinx.coroutines.flow.MutableSharedFlow
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.SharingStarted
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
import kotlinx.coroutines.flow.asStateFlow
|
||||
import kotlinx.coroutines.flow.distinctUntilChanged
|
||||
import kotlinx.coroutines.flow.flowOf
|
||||
import kotlinx.coroutines.flow.mapLatest
|
||||
import kotlinx.coroutines.flow.merge
|
||||
import kotlinx.coroutines.flow.stateIn
|
||||
@@ -68,178 +64,177 @@ import kotlinx.coroutines.flow.stateIn
|
||||
@OptIn(ExperimentalCoroutinesApi::class)
|
||||
@SysUISingleton
|
||||
@SuppressLint("MissingPermission")
|
||||
class WifiRepositoryImpl @Inject constructor(
|
||||
class WifiRepositoryImpl
|
||||
@Inject
|
||||
constructor(
|
||||
broadcastDispatcher: BroadcastDispatcher,
|
||||
connectivityManager: ConnectivityManager,
|
||||
logger: ConnectivityPipelineLogger,
|
||||
@WifiTableLog wifiTableLogBuffer: TableLogBuffer,
|
||||
@Main mainExecutor: Executor,
|
||||
@Application scope: CoroutineScope,
|
||||
wifiManager: WifiManager?,
|
||||
) : WifiRepository {
|
||||
wifiManager: WifiManager,
|
||||
) : RealWifiRepository {
|
||||
|
||||
private val wifiStateChangeEvents: Flow<Unit> = broadcastDispatcher.broadcastFlow(
|
||||
IntentFilter(WifiManager.WIFI_STATE_CHANGED_ACTION)
|
||||
)
|
||||
.logInputChange(logger, "WIFI_STATE_CHANGED_ACTION intent")
|
||||
private val wifiStateChangeEvents: Flow<Unit> =
|
||||
broadcastDispatcher
|
||||
.broadcastFlow(IntentFilter(WifiManager.WIFI_STATE_CHANGED_ACTION))
|
||||
.logInputChange(logger, "WIFI_STATE_CHANGED_ACTION intent")
|
||||
|
||||
private val wifiNetworkChangeEvents: MutableSharedFlow<Unit> =
|
||||
MutableSharedFlow(extraBufferCapacity = 1)
|
||||
|
||||
// Because [WifiManager] doesn't expose a wifi enabled change listener, we do it
|
||||
// internally by fetching [WifiManager.isWifiEnabled] whenever we think the state may
|
||||
// have changed.
|
||||
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
|
||||
// internally by fetching [WifiManager.isWifiEnabled] whenever we think the state may
|
||||
// have changed.
|
||||
merge(wifiNetworkChangeEvents, wifiStateChangeEvents)
|
||||
.mapLatest { wifiManager.isWifiEnabled }
|
||||
.distinctUntilChanged()
|
||||
.logDiffsForTable(
|
||||
wifiTableLogBuffer,
|
||||
columnPrefix = "",
|
||||
columnName = "isWifiEnabled",
|
||||
initialValue = wifiManager.isWifiEnabled,
|
||||
)
|
||||
.stateIn(
|
||||
scope = scope,
|
||||
started = SharingStarted.WhileSubscribed(),
|
||||
initialValue = wifiManager.isWifiEnabled
|
||||
)
|
||||
}
|
||||
merge(wifiNetworkChangeEvents, wifiStateChangeEvents)
|
||||
.mapLatest { wifiManager.isWifiEnabled }
|
||||
.distinctUntilChanged()
|
||||
.logDiffsForTable(
|
||||
wifiTableLogBuffer,
|
||||
columnPrefix = "",
|
||||
columnName = "isWifiEnabled",
|
||||
initialValue = wifiManager.isWifiEnabled,
|
||||
)
|
||||
.stateIn(
|
||||
scope = scope,
|
||||
started = SharingStarted.WhileSubscribed(),
|
||||
initialValue = wifiManager.isWifiEnabled,
|
||||
)
|
||||
|
||||
override val isWifiDefault: StateFlow<Boolean> = conflatedCallbackFlow {
|
||||
// Note: This callback doesn't do any logging because we already log every network change
|
||||
// in the [wifiNetwork] callback.
|
||||
val callback = object : ConnectivityManager.NetworkCallback(FLAG_INCLUDE_LOCATION_INFO) {
|
||||
override fun onCapabilitiesChanged(
|
||||
network: Network,
|
||||
networkCapabilities: NetworkCapabilities
|
||||
) {
|
||||
// This method will always be called immediately after the network becomes the
|
||||
// default, in addition to any time the capabilities change while the network is
|
||||
// the default.
|
||||
// If this network contains valid wifi info, then wifi is the default network.
|
||||
val wifiInfo = networkCapabilitiesToWifiInfo(networkCapabilities)
|
||||
trySend(wifiInfo != null)
|
||||
override val isWifiDefault: StateFlow<Boolean> =
|
||||
conflatedCallbackFlow {
|
||||
// Note: This callback doesn't do any logging because we already log every network
|
||||
// change in the [wifiNetwork] callback.
|
||||
val callback =
|
||||
object : ConnectivityManager.NetworkCallback(FLAG_INCLUDE_LOCATION_INFO) {
|
||||
override fun onCapabilitiesChanged(
|
||||
network: Network,
|
||||
networkCapabilities: NetworkCapabilities
|
||||
) {
|
||||
// This method will always be called immediately after the network
|
||||
// becomes the default, in addition to any time the capabilities change
|
||||
// while the network is the default.
|
||||
// If this network contains valid wifi info, then wifi is the default
|
||||
// network.
|
||||
val wifiInfo = networkCapabilitiesToWifiInfo(networkCapabilities)
|
||||
trySend(wifiInfo != null)
|
||||
}
|
||||
|
||||
override fun onLost(network: Network) {
|
||||
// The system no longer has a default network, so wifi is definitely not
|
||||
// default.
|
||||
trySend(false)
|
||||
}
|
||||
}
|
||||
|
||||
connectivityManager.registerDefaultNetworkCallback(callback)
|
||||
awaitClose { connectivityManager.unregisterNetworkCallback(callback) }
|
||||
}
|
||||
.distinctUntilChanged()
|
||||
.logDiffsForTable(
|
||||
wifiTableLogBuffer,
|
||||
columnPrefix = "",
|
||||
columnName = "isWifiDefault",
|
||||
initialValue = false,
|
||||
)
|
||||
.stateIn(scope, started = SharingStarted.WhileSubscribed(), initialValue = false)
|
||||
|
||||
override fun onLost(network: Network) {
|
||||
// The system no longer has a default network, so wifi is definitely not default.
|
||||
trySend(false)
|
||||
override val wifiNetwork: StateFlow<WifiNetworkModel> =
|
||||
conflatedCallbackFlow {
|
||||
var currentWifi: WifiNetworkModel = WIFI_NETWORK_DEFAULT
|
||||
|
||||
val callback =
|
||||
object : ConnectivityManager.NetworkCallback(FLAG_INCLUDE_LOCATION_INFO) {
|
||||
override fun onCapabilitiesChanged(
|
||||
network: Network,
|
||||
networkCapabilities: NetworkCapabilities
|
||||
) {
|
||||
logger.logOnCapabilitiesChanged(network, networkCapabilities)
|
||||
|
||||
wifiNetworkChangeEvents.tryEmit(Unit)
|
||||
|
||||
val wifiInfo = networkCapabilitiesToWifiInfo(networkCapabilities)
|
||||
if (wifiInfo?.isPrimary == true) {
|
||||
val wifiNetworkModel =
|
||||
createWifiNetworkModel(
|
||||
wifiInfo,
|
||||
network,
|
||||
networkCapabilities,
|
||||
wifiManager,
|
||||
)
|
||||
logger.logTransformation(
|
||||
WIFI_NETWORK_CALLBACK_NAME,
|
||||
oldValue = currentWifi,
|
||||
newValue = wifiNetworkModel,
|
||||
)
|
||||
currentWifi = wifiNetworkModel
|
||||
trySend(wifiNetworkModel)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onLost(network: Network) {
|
||||
logger.logOnLost(network)
|
||||
|
||||
wifiNetworkChangeEvents.tryEmit(Unit)
|
||||
|
||||
val wifi = currentWifi
|
||||
if (
|
||||
wifi is WifiNetworkModel.Active &&
|
||||
wifi.networkId == network.getNetId()
|
||||
) {
|
||||
val newNetworkModel = WifiNetworkModel.Inactive
|
||||
logger.logTransformation(
|
||||
WIFI_NETWORK_CALLBACK_NAME,
|
||||
oldValue = wifi,
|
||||
newValue = newNetworkModel,
|
||||
)
|
||||
currentWifi = newNetworkModel
|
||||
trySend(newNetworkModel)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
connectivityManager.registerNetworkCallback(WIFI_NETWORK_CALLBACK_REQUEST, callback)
|
||||
|
||||
awaitClose { connectivityManager.unregisterNetworkCallback(callback) }
|
||||
}
|
||||
}
|
||||
|
||||
connectivityManager.registerDefaultNetworkCallback(callback)
|
||||
awaitClose { connectivityManager.unregisterNetworkCallback(callback) }
|
||||
}
|
||||
.distinctUntilChanged()
|
||||
.logDiffsForTable(
|
||||
wifiTableLogBuffer,
|
||||
columnPrefix = "",
|
||||
columnName = "isWifiDefault",
|
||||
initialValue = false,
|
||||
)
|
||||
.stateIn(
|
||||
scope,
|
||||
started = SharingStarted.WhileSubscribed(),
|
||||
initialValue = false
|
||||
)
|
||||
|
||||
override val wifiNetwork: StateFlow<WifiNetworkModel> = conflatedCallbackFlow {
|
||||
var currentWifi: WifiNetworkModel = WIFI_NETWORK_DEFAULT
|
||||
|
||||
val callback = object : ConnectivityManager.NetworkCallback(FLAG_INCLUDE_LOCATION_INFO) {
|
||||
override fun onCapabilitiesChanged(
|
||||
network: Network,
|
||||
networkCapabilities: NetworkCapabilities
|
||||
) {
|
||||
logger.logOnCapabilitiesChanged(network, networkCapabilities)
|
||||
|
||||
wifiNetworkChangeEvents.tryEmit(Unit)
|
||||
|
||||
val wifiInfo = networkCapabilitiesToWifiInfo(networkCapabilities)
|
||||
if (wifiInfo?.isPrimary == true) {
|
||||
val wifiNetworkModel = createWifiNetworkModel(
|
||||
wifiInfo,
|
||||
network,
|
||||
networkCapabilities,
|
||||
wifiManager,
|
||||
)
|
||||
logger.logTransformation(
|
||||
WIFI_NETWORK_CALLBACK_NAME,
|
||||
oldValue = currentWifi,
|
||||
newValue = wifiNetworkModel
|
||||
)
|
||||
currentWifi = wifiNetworkModel
|
||||
trySend(wifiNetworkModel)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onLost(network: Network) {
|
||||
logger.logOnLost(network)
|
||||
|
||||
wifiNetworkChangeEvents.tryEmit(Unit)
|
||||
|
||||
val wifi = currentWifi
|
||||
if (wifi is WifiNetworkModel.Active && wifi.networkId == network.getNetId()) {
|
||||
val newNetworkModel = WifiNetworkModel.Inactive
|
||||
logger.logTransformation(
|
||||
WIFI_NETWORK_CALLBACK_NAME,
|
||||
oldValue = wifi,
|
||||
newValue = newNetworkModel
|
||||
)
|
||||
currentWifi = newNetworkModel
|
||||
trySend(newNetworkModel)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
connectivityManager.registerNetworkCallback(WIFI_NETWORK_CALLBACK_REQUEST, callback)
|
||||
|
||||
awaitClose { connectivityManager.unregisterNetworkCallback(callback) }
|
||||
}
|
||||
.distinctUntilChanged()
|
||||
.logDiffsForTable(
|
||||
wifiTableLogBuffer,
|
||||
columnPrefix = "wifiNetwork",
|
||||
initialValue = WIFI_NETWORK_DEFAULT,
|
||||
)
|
||||
// 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
|
||||
// new subscribes will get the latest value immediately upon subscription. Otherwise, the
|
||||
// views could show stale data. See b/244173280.
|
||||
.stateIn(
|
||||
scope,
|
||||
started = SharingStarted.WhileSubscribed(),
|
||||
initialValue = WIFI_NETWORK_DEFAULT
|
||||
)
|
||||
.distinctUntilChanged()
|
||||
.logDiffsForTable(
|
||||
wifiTableLogBuffer,
|
||||
columnPrefix = "wifiNetwork",
|
||||
initialValue = WIFI_NETWORK_DEFAULT,
|
||||
)
|
||||
// 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 new subscribes will get the latest value immediately upon subscription.
|
||||
// Otherwise, the views could show stale data. See b/244173280.
|
||||
.stateIn(
|
||||
scope,
|
||||
started = SharingStarted.WhileSubscribed(),
|
||||
initialValue = WIFI_NETWORK_DEFAULT,
|
||||
)
|
||||
|
||||
override val wifiActivity: StateFlow<DataActivityModel> =
|
||||
if (wifiManager == null) {
|
||||
Log.w(SB_LOGGING_TAG, "Null WifiManager; skipping activity callback")
|
||||
flowOf(ACTIVITY_DEFAULT)
|
||||
} else {
|
||||
conflatedCallbackFlow {
|
||||
val callback = TrafficStateCallback { state ->
|
||||
logger.logInputChange("onTrafficStateChange", prettyPrintActivity(state))
|
||||
trySend(state.toWifiDataActivityModel())
|
||||
}
|
||||
wifiManager.registerTrafficStateCallback(mainExecutor, callback)
|
||||
awaitClose { wifiManager.unregisterTrafficStateCallback(callback) }
|
||||
conflatedCallbackFlow {
|
||||
val callback = TrafficStateCallback { state ->
|
||||
logger.logInputChange("onTrafficStateChange", prettyPrintActivity(state))
|
||||
trySend(state.toWifiDataActivityModel())
|
||||
}
|
||||
wifiManager.registerTrafficStateCallback(mainExecutor, callback)
|
||||
awaitClose { wifiManager.unregisterTrafficStateCallback(callback) }
|
||||
}
|
||||
.logDiffsForTable(
|
||||
wifiTableLogBuffer,
|
||||
columnPrefix = ACTIVITY_PREFIX,
|
||||
initialValue = ACTIVITY_DEFAULT,
|
||||
)
|
||||
.stateIn(
|
||||
scope,
|
||||
started = SharingStarted.WhileSubscribed(),
|
||||
initialValue = ACTIVITY_DEFAULT
|
||||
)
|
||||
.logDiffsForTable(
|
||||
wifiTableLogBuffer,
|
||||
columnPrefix = ACTIVITY_PREFIX,
|
||||
initialValue = ACTIVITY_DEFAULT,
|
||||
)
|
||||
.stateIn(
|
||||
scope,
|
||||
started = SharingStarted.WhileSubscribed(),
|
||||
initialValue = ACTIVITY_DEFAULT,
|
||||
)
|
||||
|
||||
companion object {
|
||||
private const val ACTIVITY_PREFIX = "wifiActivity"
|
||||
@@ -271,19 +266,19 @@ class WifiRepositoryImpl @Inject constructor(
|
||||
wifiInfo: WifiInfo,
|
||||
network: Network,
|
||||
networkCapabilities: NetworkCapabilities,
|
||||
wifiManager: WifiManager?,
|
||||
wifiManager: WifiManager,
|
||||
): WifiNetworkModel {
|
||||
return if (wifiInfo.isCarrierMerged) {
|
||||
WifiNetworkModel.CarrierMerged
|
||||
} else {
|
||||
WifiNetworkModel.Active(
|
||||
network.getNetId(),
|
||||
isValidated = networkCapabilities.hasCapability(NET_CAPABILITY_VALIDATED),
|
||||
level = wifiManager?.calculateSignalLevel(wifiInfo.rssi),
|
||||
wifiInfo.ssid,
|
||||
wifiInfo.isPasspointAp,
|
||||
wifiInfo.isOsuAp,
|
||||
wifiInfo.passpointProviderFriendlyName
|
||||
network.getNetId(),
|
||||
isValidated = networkCapabilities.hasCapability(NET_CAPABILITY_VALIDATED),
|
||||
level = wifiManager.calculateSignalLevel(wifiInfo.rssi),
|
||||
wifiInfo.ssid,
|
||||
wifiInfo.isPasspointAp,
|
||||
wifiInfo.isOsuAp,
|
||||
wifiInfo.passpointProviderFriendlyName
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -308,4 +303,28 @@ class WifiRepositoryImpl @Inject constructor(
|
||||
|
||||
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,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -65,6 +65,7 @@ class WifiInteractorImpl @Inject constructor(
|
||||
|
||||
override val ssid: Flow<String?> = wifiRepository.wifiNetwork.map { info ->
|
||||
when (info) {
|
||||
is WifiNetworkModel.Unavailable -> null
|
||||
is WifiNetworkModel.Inactive -> null
|
||||
is WifiNetworkModel.CarrierMerged -> null
|
||||
is WifiNetworkModel.Active -> when {
|
||||
|
||||
@@ -82,6 +82,7 @@ constructor(
|
||||
/** Returns the icon to use based on the given network. */
|
||||
private fun WifiNetworkModel.icon(): WifiIcon {
|
||||
return when (this) {
|
||||
is WifiNetworkModel.Unavailable -> WifiIcon.Hidden
|
||||
is WifiNetworkModel.CarrierMerged -> WifiIcon.Hidden
|
||||
is WifiNetworkModel.Inactive -> WifiIcon.Visible(
|
||||
res = WIFI_NO_NETWORK,
|
||||
@@ -89,27 +90,23 @@ constructor(
|
||||
"${context.getString(WIFI_NO_CONNECTION)},${context.getString(NO_INTERNET)}"
|
||||
)
|
||||
)
|
||||
is WifiNetworkModel.Active ->
|
||||
when (this.level) {
|
||||
null -> WifiIcon.Hidden
|
||||
else -> {
|
||||
val levelDesc = context.getString(WIFI_CONNECTION_STRENGTH[this.level])
|
||||
when {
|
||||
this.isValidated ->
|
||||
WifiIcon.Visible(
|
||||
WIFI_FULL_ICONS[this.level],
|
||||
ContentDescription.Loaded(levelDesc)
|
||||
)
|
||||
else ->
|
||||
WifiIcon.Visible(
|
||||
WIFI_NO_INTERNET_ICONS[this.level],
|
||||
ContentDescription.Loaded(
|
||||
"$levelDesc,${context.getString(NO_INTERNET)}"
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
is WifiNetworkModel.Active -> {
|
||||
val levelDesc = context.getString(WIFI_CONNECTION_STRENGTH[this.level])
|
||||
when {
|
||||
this.isValidated ->
|
||||
WifiIcon.Visible(
|
||||
WIFI_FULL_ICONS[this.level],
|
||||
ContentDescription.Loaded(levelDesc),
|
||||
)
|
||||
else ->
|
||||
WifiIcon.Visible(
|
||||
WIFI_NO_INTERNET_ICONS[this.level],
|
||||
ContentDescription.Loaded(
|
||||
"$levelDesc,${context.getString(NO_INTERNET)}"
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -19,6 +19,7 @@ package com.android.systemui.statusbar.pipeline.mobile.data.repository
|
||||
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.NetworkNameModel
|
||||
import com.android.systemui.statusbar.pipeline.mobile.data.repository.MobileConnectionRepository.Companion.DEFAULT_NUM_LEVELS
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
|
||||
// TODO(b/261632894): remove this in favor of the real impl or DemoMobileConnectionRepository
|
||||
@@ -29,12 +30,11 @@ class FakeMobileConnectionRepository(
|
||||
private val _connectionInfo = MutableStateFlow(MobileConnectionModel())
|
||||
override val connectionInfo = _connectionInfo
|
||||
|
||||
override val numberOfLevels = MutableStateFlow(DEFAULT_NUM_LEVELS)
|
||||
|
||||
private val _dataEnabled = MutableStateFlow(true)
|
||||
override val dataEnabled = _dataEnabled
|
||||
|
||||
private val _isDefaultDataSubscription = MutableStateFlow(true)
|
||||
override val isDefaultDataSubscription = _isDefaultDataSubscription
|
||||
|
||||
override val cdmaRoaming = MutableStateFlow(false)
|
||||
|
||||
override val networkName =
|
||||
@@ -47,8 +47,4 @@ class FakeMobileConnectionRepository(
|
||||
fun setDataEnabled(enabled: Boolean) {
|
||||
_dataEnabled.value = enabled
|
||||
}
|
||||
|
||||
fun setIsDefaultDataSubscription(isDefault: Boolean) {
|
||||
_isDefaultDataSubscription.value = isDefault
|
||||
}
|
||||
}
|
||||
|
||||
@@ -57,9 +57,6 @@ class FakeMobileConnectionsRepository(
|
||||
private val _activeMobileDataSubscriptionId = MutableStateFlow(INVALID_SUBSCRIPTION_ID)
|
||||
override val activeMobileDataSubscriptionId = _activeMobileDataSubscriptionId
|
||||
|
||||
private val _defaultDataSubId = MutableStateFlow(INVALID_SUBSCRIPTION_ID)
|
||||
override val defaultDataSubId = _defaultDataSubId
|
||||
|
||||
private val _mobileConnectivity = MutableStateFlow(MobileConnectivityModel())
|
||||
override val defaultMobileNetworkConnectivity = _mobileConnectivity
|
||||
|
||||
@@ -84,10 +81,6 @@ class FakeMobileConnectionsRepository(
|
||||
_subscriptions.value = subs
|
||||
}
|
||||
|
||||
fun setDefaultDataSubId(id: Int) {
|
||||
_defaultDataSubId.value = id
|
||||
}
|
||||
|
||||
fun setMobileConnectivity(model: MobileConnectivityModel) {
|
||||
_mobileConnectivity.value = model
|
||||
}
|
||||
|
||||
@@ -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.toNetworkNameModel
|
||||
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.shared.ConnectivityPipelineLogger
|
||||
import com.android.systemui.statusbar.pipeline.shared.data.model.DataActivityModel
|
||||
@@ -117,7 +118,6 @@ class MobileConnectionRepositoryTest : SysuiTestCase() {
|
||||
telephonyManager,
|
||||
globalSettings,
|
||||
fakeBroadcastDispatcher,
|
||||
connectionsRepo.defaultDataSubId,
|
||||
connectionsRepo.globalMobileDataSettingChangedEvent,
|
||||
mobileMappings,
|
||||
IMMEDIATE,
|
||||
@@ -319,7 +319,7 @@ class MobileConnectionRepositoryTest : SysuiTestCase() {
|
||||
|
||||
val callback = getTelephonyCallbackForType<TelephonyCallback.DisplayInfoListener>()
|
||||
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) }
|
||||
callback.onDisplayInfoChanged(ti)
|
||||
|
||||
@@ -336,7 +336,7 @@ class MobileConnectionRepositoryTest : SysuiTestCase() {
|
||||
|
||||
val callback = getTelephonyCallbackForType<TelephonyCallback.DisplayInfoListener>()
|
||||
val type = OVERRIDE_NETWORK_TYPE_LTE_CA
|
||||
val expected = OverrideNetworkType(type, mobileMappings.toIconKeyOverride(type))
|
||||
val expected = OverrideNetworkType(mobileMappings.toIconKeyOverride(type))
|
||||
val ti =
|
||||
mock<TelephonyDisplayInfo>().also {
|
||||
whenever(it.networkType).thenReturn(type)
|
||||
@@ -379,33 +379,6 @@ class MobileConnectionRepositoryTest : SysuiTestCase() {
|
||||
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
|
||||
fun isDataConnectionAllowed_subIdSettingUpdate_valueUpdated() =
|
||||
runBlocking(IMMEDIATE) {
|
||||
@@ -430,6 +403,17 @@ class MobileConnectionRepositoryTest : SysuiTestCase() {
|
||||
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
|
||||
fun `roaming - cdma - queries telephony manager`() =
|
||||
runBlocking(IMMEDIATE) {
|
||||
|
||||
@@ -306,35 +306,6 @@ class MobileConnectionsRepositoryTest : SysuiTestCase() {
|
||||
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
|
||||
fun mobileConnectivity_default() {
|
||||
assertThat(underTest.defaultMobileNetworkConnectivity.value)
|
||||
|
||||
@@ -21,6 +21,7 @@ import com.android.settingslib.SignalIcon
|
||||
import com.android.settingslib.mobile.TelephonyIcons
|
||||
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.repository.MobileConnectionRepository.Companion.DEFAULT_NUM_LEVELS
|
||||
import com.android.systemui.statusbar.pipeline.shared.data.model.DataActivityModel
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
|
||||
@@ -65,7 +66,7 @@ class FakeMobileIconInteractor(
|
||||
private val _level = MutableStateFlow(CellSignalStrength.SIGNAL_STRENGTH_NONE_OR_UNKNOWN)
|
||||
override val level = _level
|
||||
|
||||
private val _numberOfLevels = MutableStateFlow(4)
|
||||
private val _numberOfLevels = MutableStateFlow(DEFAULT_NUM_LEVELS)
|
||||
override val numberOfLevels = _numberOfLevels
|
||||
|
||||
fun setIconGroup(group: SignalIcon.MobileIconGroup) {
|
||||
|
||||
@@ -17,7 +17,6 @@
|
||||
package com.android.systemui.statusbar.pipeline.mobile.domain.interactor
|
||||
|
||||
import android.telephony.CellSignalStrength
|
||||
import android.telephony.SubscriptionInfo
|
||||
import android.telephony.TelephonyManager.NETWORK_TYPE_UNKNOWN
|
||||
import androidx.test.filters.SmallTest
|
||||
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.util.FakeMobileMappingsProxy
|
||||
import com.android.systemui.util.mockito.mock
|
||||
import com.android.systemui.util.mockito.whenever
|
||||
import com.google.common.truth.Truth.assertThat
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
@@ -177,13 +175,27 @@ class MobileIconInteractorTest : SysuiTestCase() {
|
||||
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
|
||||
fun iconGroup_three_g() =
|
||||
runBlocking(IMMEDIATE) {
|
||||
connectionRepository.setConnectionInfo(
|
||||
MobileConnectionModel(
|
||||
resolvedNetworkType =
|
||||
DefaultNetworkType(THREE_G, mobileMappingsProxy.toIconKey(THREE_G))
|
||||
resolvedNetworkType = DefaultNetworkType(mobileMappingsProxy.toIconKey(THREE_G))
|
||||
),
|
||||
)
|
||||
|
||||
@@ -200,8 +212,7 @@ class MobileIconInteractorTest : SysuiTestCase() {
|
||||
runBlocking(IMMEDIATE) {
|
||||
connectionRepository.setConnectionInfo(
|
||||
MobileConnectionModel(
|
||||
resolvedNetworkType =
|
||||
DefaultNetworkType(THREE_G, mobileMappingsProxy.toIconKey(THREE_G))
|
||||
resolvedNetworkType = DefaultNetworkType(mobileMappingsProxy.toIconKey(THREE_G))
|
||||
),
|
||||
)
|
||||
|
||||
@@ -212,7 +223,6 @@ class MobileIconInteractorTest : SysuiTestCase() {
|
||||
MobileConnectionModel(
|
||||
resolvedNetworkType =
|
||||
DefaultNetworkType(
|
||||
FOUR_G,
|
||||
mobileMappingsProxy.toIconKey(FOUR_G),
|
||||
),
|
||||
),
|
||||
@@ -230,10 +240,7 @@ class MobileIconInteractorTest : SysuiTestCase() {
|
||||
connectionRepository.setConnectionInfo(
|
||||
MobileConnectionModel(
|
||||
resolvedNetworkType =
|
||||
OverrideNetworkType(
|
||||
FIVE_G_OVERRIDE,
|
||||
mobileMappingsProxy.toIconKeyOverride(FIVE_G_OVERRIDE)
|
||||
)
|
||||
OverrideNetworkType(mobileMappingsProxy.toIconKeyOverride(FIVE_G_OVERRIDE))
|
||||
),
|
||||
)
|
||||
|
||||
@@ -251,10 +258,7 @@ class MobileIconInteractorTest : SysuiTestCase() {
|
||||
connectionRepository.setConnectionInfo(
|
||||
MobileConnectionModel(
|
||||
resolvedNetworkType =
|
||||
DefaultNetworkType(
|
||||
NETWORK_TYPE_UNKNOWN,
|
||||
mobileMappingsProxy.toIconKey(NETWORK_TYPE_UNKNOWN)
|
||||
),
|
||||
DefaultNetworkType(mobileMappingsProxy.toIconKey(NETWORK_TYPE_UNKNOWN)),
|
||||
),
|
||||
)
|
||||
|
||||
@@ -509,8 +513,6 @@ class MobileIconInteractorTest : SysuiTestCase() {
|
||||
private const val CDMA_LEVEL = 2
|
||||
|
||||
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 DERIVED_NAME = NetworkNameModel.Derived("test derived name")
|
||||
|
||||
@@ -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)
|
||||
fun active_levelNegative_exceptionThrown() {
|
||||
WifiNetworkModel.Active(NETWORK_ID, level = MIN_VALID_LEVEL - 1)
|
||||
|
||||
@@ -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))
|
||||
}
|
||||
}
|
||||
@@ -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.data.model.DataActivityModel
|
||||
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.util.concurrency.FakeExecutor
|
||||
import com.android.systemui.util.mockito.any
|
||||
@@ -97,13 +96,6 @@ class WifiRepositoryImplTest : SysuiTestCase() {
|
||||
scope.cancel()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun isWifiEnabled_nullWifiManager_getsFalse() = runBlocking(IMMEDIATE) {
|
||||
underTest = createRepo(wifiManagerToUse = null)
|
||||
|
||||
assertThat(underTest.isWifiEnabled.value).isFalse()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun isWifiEnabled_initiallyGetsWifiManagerValue() = runBlocking(IMMEDIATE) {
|
||||
whenever(wifiManager.isWifiEnabled).thenReturn(true)
|
||||
@@ -720,21 +712,6 @@ class WifiRepositoryImplTest : SysuiTestCase() {
|
||||
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
|
||||
fun wifiActivity_callbackGivesNone_activityFlowHasNone() = runBlocking(IMMEDIATE) {
|
||||
var latest: DataActivityModel? = null
|
||||
@@ -801,7 +778,7 @@ class WifiRepositoryImplTest : SysuiTestCase() {
|
||||
job.cancel()
|
||||
}
|
||||
|
||||
private fun createRepo(wifiManagerToUse: WifiManager? = wifiManager): WifiRepositoryImpl {
|
||||
private fun createRepo(): WifiRepositoryImpl {
|
||||
return WifiRepositoryImpl(
|
||||
broadcastDispatcher,
|
||||
connectivityManager,
|
||||
@@ -809,7 +786,7 @@ class WifiRepositoryImplTest : SysuiTestCase() {
|
||||
tableLogger,
|
||||
executor,
|
||||
scope,
|
||||
wifiManagerToUse,
|
||||
wifiManager,
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -51,6 +51,22 @@ class WifiInteractorImplTest : SysuiTestCase() {
|
||||
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
|
||||
fun ssid_inactiveNetwork_outputsNull() = runBlocking(IMMEDIATE) {
|
||||
wifiRepository.setWifiNetwork(WifiNetworkModel.Inactive)
|
||||
@@ -85,6 +101,7 @@ class WifiInteractorImplTest : SysuiTestCase() {
|
||||
fun ssid_isPasspointAccessPoint_outputsPasspointName() = runBlocking(IMMEDIATE) {
|
||||
wifiRepository.setWifiNetwork(WifiNetworkModel.Active(
|
||||
networkId = 1,
|
||||
level = 1,
|
||||
isPasspointAccessPoint = true,
|
||||
passpointProviderFriendlyName = "friendly",
|
||||
))
|
||||
@@ -104,6 +121,7 @@ class WifiInteractorImplTest : SysuiTestCase() {
|
||||
fun ssid_isOnlineSignUpForPasspoint_outputsPasspointName() = runBlocking(IMMEDIATE) {
|
||||
wifiRepository.setWifiNetwork(WifiNetworkModel.Active(
|
||||
networkId = 1,
|
||||
level = 1,
|
||||
isOnlineSignUpForPasspointAccessPoint = true,
|
||||
passpointProviderFriendlyName = "friendly",
|
||||
))
|
||||
@@ -123,6 +141,7 @@ class WifiInteractorImplTest : SysuiTestCase() {
|
||||
fun ssid_unknownSsid_outputsNull() = runBlocking(IMMEDIATE) {
|
||||
wifiRepository.setWifiNetwork(WifiNetworkModel.Active(
|
||||
networkId = 1,
|
||||
level = 1,
|
||||
ssid = WifiManager.UNKNOWN_SSID,
|
||||
))
|
||||
|
||||
@@ -141,6 +160,7 @@ class WifiInteractorImplTest : SysuiTestCase() {
|
||||
fun ssid_validSsid_outputsSsid() = runBlocking(IMMEDIATE) {
|
||||
wifiRepository.setWifiNetwork(WifiNetworkModel.Active(
|
||||
networkId = 1,
|
||||
level = 1,
|
||||
ssid = "MyAwesomeWifiNetwork",
|
||||
))
|
||||
|
||||
|
||||
@@ -379,6 +379,12 @@ internal class WifiViewModelIconParameterizedTest(private val testCase: TestCase
|
||||
expected = null,
|
||||
),
|
||||
|
||||
// network = Unavailable => not shown
|
||||
TestCase(
|
||||
network = WifiNetworkModel.Unavailable,
|
||||
expected = null,
|
||||
),
|
||||
|
||||
// network = Active & validated = false => not shown
|
||||
TestCase(
|
||||
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",
|
||||
),
|
||||
),
|
||||
|
||||
// network has null level => not shown
|
||||
TestCase(
|
||||
network = WifiNetworkModel.Active(NETWORK_ID, isValidated = true, level = null),
|
||||
expected = null,
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -228,7 +228,7 @@ class WifiViewModelTest : SysuiTestCase() {
|
||||
whenever(connectivityConstants.shouldShowActivityConfig).thenReturn(true)
|
||||
createAndSetViewModel()
|
||||
|
||||
wifiRepository.setWifiNetwork(WifiNetworkModel.Active(NETWORK_ID, ssid = null))
|
||||
wifiRepository.setWifiNetwork(WifiNetworkModel.Active(NETWORK_ID, ssid = null, level = 1))
|
||||
|
||||
var activityIn: Boolean? = null
|
||||
val activityInJob = underTest
|
||||
@@ -553,7 +553,8 @@ class WifiViewModelTest : SysuiTestCase() {
|
||||
|
||||
companion object {
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user