summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Caitlin Cassidy <ccassidy@google.com> 2022-08-12 18:58:37 +0000
committer Caitlin Shkuratov <ccassidy@google.com> 2022-08-22 17:42:37 +0000
commitdb2c8323ef437b60baaa5cb5a0fc8e1f28583a45 (patch)
tree111fbd3432ccff60eb59777ae1f2766299a378c8
parent829e25dfd3be305ccc87e98ecf3b264515575357 (diff)
[SB Refactor] Implement the wifi network flow using the
NetworkCallback. This migrates the information from NetworkCapabilitiesRepo into WifiRepositoryImpl. So, we can now delete NetworkCapabilitiesRepo and CollectivityInfoCollector (which was just listening to NCR). This implementation should approximately mimic WifiStatusTracker.mNetworkCallback, but in a hopefully much more straightfoward way! Test: manual: compared logs from old system and new system and verified the wifi updates are the same in both Test: manual: verified new pipeline output logs Test: WifiRepositoryImplTest Bug: 238425913 Change-Id: I8bbe6cc21cd1c1ae2c1d364b94a2fb87d0a7821e
-rw-r--r--packages/SettingsLib/src/com/android/settingslib/Utils.java3
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/pipeline/ConnectivityInfoCollector.kt49
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/pipeline/ConnectivityInfoCollectorImpl.kt46
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/pipeline/ConnectivityInfoProcessor.kt44
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/pipeline/dagger/StatusBarPipelineModule.kt7
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ConnectivityPipelineLogger.kt38
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/model/WifiModel.kt29
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/model/WifiNetworkModel.kt46
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/NetworkCapabilitiesRepo.kt94
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/WifiRepository.kt106
-rw-r--r--packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/domain/interactor/WifiInteractor.kt17
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/ConnectivityInfoProcessorTest.kt88
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/FakeConnectivityInfoCollector.kt33
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/FakeWifiRepository.kt11
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/NetworkCapabilitiesRepoTest.kt252
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/WifiRepositoryImplTest.kt396
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/domain/interactor/WifiInteractorTest.kt18
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/ui/viewmodel/WifiViewModelTest.kt4
18 files changed, 591 insertions, 690 deletions
diff --git a/packages/SettingsLib/src/com/android/settingslib/Utils.java b/packages/SettingsLib/src/com/android/settingslib/Utils.java
index b9c4030d9d0e..a822e185479a 100644
--- a/packages/SettingsLib/src/com/android/settingslib/Utils.java
+++ b/packages/SettingsLib/src/com/android/settingslib/Utils.java
@@ -600,6 +600,9 @@ public class Utils {
* Returns the WifiInfo for the underlying WiFi network of the VCN network, returns null if the
* input NetworkCapabilities is not for a VCN network with underlying WiFi network.
*
+ * TODO(b/238425913): Move this method to be inside systemui not settingslib once we've migrated
+ * off of {@link WifiStatusTracker} and {@link NetworkControllerImpl}.
+ *
* @param networkCapabilities NetworkCapabilities of the network.
*/
@Nullable
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/ConnectivityInfoCollector.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/ConnectivityInfoCollector.kt
deleted file mode 100644
index 780a02da3410..000000000000
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/ConnectivityInfoCollector.kt
+++ /dev/null
@@ -1,49 +0,0 @@
-/*
- * 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
-
-import com.android.systemui.statusbar.pipeline.wifi.data.repository.NetworkCapabilityInfo
-import kotlinx.coroutines.flow.StateFlow
-
-/**
- * Interface exposing a flow for raw connectivity information. Clients should collect on
- * [rawConnectivityInfoFlow] to get updates on connectivity information.
- *
- * Note: [rawConnectivityInfoFlow] should be a *hot* flow, so that we only create one instance of it
- * and all clients get references to the same flow.
- *
- * This will be used for the new status bar pipeline to compile information we need to display some
- * of the icons in the RHS of the status bar.
- */
-interface ConnectivityInfoCollector {
- val rawConnectivityInfoFlow: StateFlow<RawConnectivityInfo>
-}
-
-/**
- * An object containing all of the raw connectivity information.
- *
- * Importantly, all the information in this object should not be processed at all (i.e., the data
- * that we receive from callbacks should be piped straight into this object and not be filtered,
- * manipulated, or processed in any way). Instead, any listeners on
- * [ConnectivityInfoCollector.rawConnectivityInfoFlow] can do the processing.
- *
- * This allows us to keep all the processing in one place which is beneficial for logging and
- * debugging purposes.
- */
-data class RawConnectivityInfo(
- val networkCapabilityInfo: Map<Int, NetworkCapabilityInfo> = emptyMap(),
-)
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/ConnectivityInfoCollectorImpl.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/ConnectivityInfoCollectorImpl.kt
deleted file mode 100644
index 99798f9b38d3..000000000000
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/ConnectivityInfoCollectorImpl.kt
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * 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
-
-import com.android.systemui.dagger.SysUISingleton
-import com.android.systemui.dagger.qualifiers.Application
-import com.android.systemui.statusbar.pipeline.wifi.data.repository.NetworkCapabilitiesRepo
-import javax.inject.Inject
-import kotlinx.coroutines.CoroutineScope
-import kotlinx.coroutines.flow.SharingStarted.Companion.Lazily
-import kotlinx.coroutines.flow.StateFlow
-import kotlinx.coroutines.flow.map
-import kotlinx.coroutines.flow.stateIn
-
-/**
- * The real implementation of [ConnectivityInfoCollector] that will collect information from all the
- * relevant connectivity callbacks and compile it into [rawConnectivityInfoFlow].
- */
-@SysUISingleton
-class ConnectivityInfoCollectorImpl @Inject constructor(
- networkCapabilitiesRepo: NetworkCapabilitiesRepo,
- @Application scope: CoroutineScope,
-) : ConnectivityInfoCollector {
- override val rawConnectivityInfoFlow: StateFlow<RawConnectivityInfo> =
- // TODO(b/238425913): Collect all the separate flows for individual raw information into
- // this final flow.
- networkCapabilitiesRepo.dataStream
- .map {
- RawConnectivityInfo(networkCapabilityInfo = it)
- }
- .stateIn(scope, started = Lazily, initialValue = RawConnectivityInfo())
-}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/ConnectivityInfoProcessor.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/ConnectivityInfoProcessor.kt
index 64c47f679142..0b018168fbd5 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/ConnectivityInfoProcessor.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/ConnectivityInfoProcessor.kt
@@ -20,31 +20,21 @@ import android.content.Context
import com.android.systemui.CoreStartable
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Application
-import com.android.systemui.statusbar.pipeline.wifi.data.repository.NetworkCapabilityInfo
import com.android.systemui.statusbar.pipeline.wifi.ui.viewmodel.WifiViewModel
import javax.inject.Inject
import javax.inject.Provider
import kotlinx.coroutines.CoroutineScope
-import kotlinx.coroutines.flow.Flow
-import kotlinx.coroutines.flow.SharingStarted.Companion.Lazily
import kotlinx.coroutines.flow.collect
-import kotlinx.coroutines.flow.emptyFlow
-import kotlinx.coroutines.flow.map
-import kotlinx.coroutines.flow.stateIn
import kotlinx.coroutines.launch
/**
- * A processor that transforms raw connectivity information that we get from callbacks and turns it
- * into a list of displayable connectivity information.
+ * A temporary object that collects on [WifiViewModel] flows for debugging purposes.
*
- * This will be used for the new status bar pipeline to calculate the list of icons that should be
- * displayed in the RHS of the status bar.
- *
- * Anyone can listen to [processedInfoFlow] to get updates to the processed data.
+ * This will eventually get migrated to a view binder that will use the flow outputs to set state on
+ * views. For now, this just collects on flows so that the information gets logged.
*/
@SysUISingleton
class ConnectivityInfoProcessor @Inject constructor(
- connectivityInfoCollector: ConnectivityInfoCollector,
context: Context,
// TODO(b/238425913): Don't use the application scope; instead, use the status bar view's
// scope so we only do work when there's UI that cares about it.
@@ -52,21 +42,6 @@ class ConnectivityInfoProcessor @Inject constructor(
private val statusBarPipelineFlags: StatusBarPipelineFlags,
private val wifiViewModelProvider: Provider<WifiViewModel>,
) : CoreStartable(context) {
- // Note: This flow will not start running until a client calls `collect` on it, which means that
- // [connectivityInfoCollector]'s flow will also not start anything until that `collect` call
- // happens.
- // TODO(b/238425913): Delete this.
- val processedInfoFlow: Flow<ProcessedConnectivityInfo> =
- if (!statusBarPipelineFlags.isNewPipelineEnabled())
- emptyFlow()
- else connectivityInfoCollector.rawConnectivityInfoFlow
- .map { it.process() }
- .stateIn(
- scope,
- started = Lazily,
- initialValue = ProcessedConnectivityInfo()
- )
-
override fun start() {
if (!statusBarPipelineFlags.isNewPipelineEnabled()) {
return
@@ -77,17 +52,4 @@ class ConnectivityInfoProcessor @Inject constructor(
wifiViewModelProvider.get().isActivityInVisible.collect { }
}
}
-
- private fun RawConnectivityInfo.process(): ProcessedConnectivityInfo {
- // TODO(b/238425913): Actually process the raw info into meaningful data.
- return ProcessedConnectivityInfo(this.networkCapabilityInfo)
- }
}
-
-/**
- * An object containing connectivity info that has been processed into data that can be directly
- * used by the status bar (and potentially other SysUI areas) to display icons.
- */
-data class ProcessedConnectivityInfo(
- val networkCapabilityInfo: Map<Int, NetworkCapabilityInfo> = emptyMap(),
-)
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/dagger/StatusBarPipelineModule.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/dagger/StatusBarPipelineModule.kt
index 7abe19e7bbe0..88eccb5ba47f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/dagger/StatusBarPipelineModule.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/dagger/StatusBarPipelineModule.kt
@@ -17,8 +17,6 @@
package com.android.systemui.statusbar.pipeline.dagger
import com.android.systemui.CoreStartable
-import com.android.systemui.statusbar.pipeline.ConnectivityInfoCollector
-import com.android.systemui.statusbar.pipeline.ConnectivityInfoCollectorImpl
import com.android.systemui.statusbar.pipeline.ConnectivityInfoProcessor
import com.android.systemui.statusbar.pipeline.wifi.data.repository.WifiRepository
import com.android.systemui.statusbar.pipeline.wifi.data.repository.WifiRepositoryImpl
@@ -36,10 +34,5 @@ abstract class StatusBarPipelineModule {
abstract fun bindConnectivityInfoProcessor(cip: ConnectivityInfoProcessor): CoreStartable
@Binds
- abstract fun provideConnectivityInfoCollector(
- impl: ConnectivityInfoCollectorImpl
- ): ConnectivityInfoCollector
-
- @Binds
abstract fun wifiRepository(impl: WifiRepositoryImpl): WifiRepository
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ConnectivityPipelineLogger.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ConnectivityPipelineLogger.kt
index a5fff5e65ebc..2a89309f7200 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ConnectivityPipelineLogger.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ConnectivityPipelineLogger.kt
@@ -31,6 +31,9 @@ import kotlinx.coroutines.flow.onEach
class ConnectivityPipelineLogger @Inject constructor(
@StatusBarConnectivityLog private val buffer: LogBuffer,
) {
+ /**
+ * Logs a change in one of the **raw inputs** to the connectivity pipeline.
+ */
fun logInputChange(callbackName: String, changeInfo: String) {
buffer.log(
SB_LOGGING_TAG,
@@ -45,6 +48,41 @@ class ConnectivityPipelineLogger @Inject constructor(
)
}
+ /**
+ * Logs a **data transformation** that we performed within the connectivity pipeline.
+ */
+ fun logTransformation(transformationName: String, oldValue: Any?, newValue: Any?) {
+ if (oldValue == newValue) {
+ buffer.log(
+ SB_LOGGING_TAG,
+ LogLevel.INFO,
+ {
+ str1 = transformationName
+ str2 = oldValue.toString()
+ },
+ {
+ "Transform: $str1: $str2 (transformation didn't change it)"
+ }
+ )
+ } else {
+ buffer.log(
+ SB_LOGGING_TAG,
+ LogLevel.INFO,
+ {
+ str1 = transformationName
+ str2 = oldValue.toString()
+ str3 = newValue.toString()
+ },
+ {
+ "Transform: $str1: $str2 -> $str3"
+ }
+ )
+ }
+ }
+
+ /**
+ * Logs a change in one of the **outputs** to the connectivity pipeline.
+ */
fun logOutputChange(outputParamName: String, changeInfo: String) {
buffer.log(
SB_LOGGING_TAG,
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/model/WifiModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/model/WifiModel.kt
deleted file mode 100644
index 1b7332265b7a..000000000000
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/model/WifiModel.kt
+++ /dev/null
@@ -1,29 +0,0 @@
-/*
- * 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.model
-
-/** Provides information about the current wifi state. */
-data class WifiModel(
- /** See [android.net.wifi.WifiInfo.ssid]. */
- val ssid: String? = null,
- /** See [android.net.wifi.WifiInfo.isPasspointAp]. */
- val isPasspointAccessPoint: Boolean = false,
- /** See [android.net.wifi.WifiInfo.isOsuAp]. */
- val isOnlineSignUpForPasspointAccessPoint: Boolean = false,
- /** See [android.net.wifi.WifiInfo.passpointProviderFriendlyName]. */
- val passpointProviderFriendlyName: String? = null,
-)
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/model/WifiNetworkModel.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/model/WifiNetworkModel.kt
new file mode 100644
index 000000000000..5566fa6b5835
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/model/WifiNetworkModel.kt
@@ -0,0 +1,46 @@
+/*
+ * 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.model
+
+/** Provides information about the current wifi network. */
+sealed class WifiNetworkModel {
+ /** A model representing that we have no active wifi network. */
+ object Inactive : WifiNetworkModel()
+
+ /** Provides information about an active wifi network. */
+ class Active(
+ /**
+ * The [android.net.Network.netId] we received from
+ * [android.net.ConnectivityManager.NetworkCallback] in association with this wifi network.
+ *
+ * Importantly, **not** [android.net.wifi.WifiInfo.getNetworkId].
+ */
+ val networkId: Int,
+
+ /** See [android.net.wifi.WifiInfo.ssid]. */
+ val ssid: String? = null,
+
+ /** See [android.net.wifi.WifiInfo.isPasspointAp]. */
+ val isPasspointAccessPoint: Boolean = false,
+
+ /** See [android.net.wifi.WifiInfo.isOsuAp]. */
+ val isOnlineSignUpForPasspointAccessPoint: Boolean = false,
+
+ /** See [android.net.wifi.WifiInfo.passpointProviderFriendlyName]. */
+ val passpointProviderFriendlyName: String? = null,
+ ) : WifiNetworkModel()
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/NetworkCapabilitiesRepo.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/NetworkCapabilitiesRepo.kt
deleted file mode 100644
index 6c0a44524e3a..000000000000
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/NetworkCapabilitiesRepo.kt
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * Copyright (C) 2021 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.
- */
-
-@file:OptIn(ExperimentalCoroutinesApi::class)
-
-package com.android.systemui.statusbar.pipeline.wifi.data.repository
-
-import android.annotation.SuppressLint
-import android.net.ConnectivityManager
-import android.net.Network
-import android.net.NetworkCapabilities
-import android.net.NetworkRequest
-import com.android.systemui.dagger.SysUISingleton
-import com.android.systemui.dagger.qualifiers.Application
-import com.android.systemui.statusbar.pipeline.shared.ConnectivityPipelineLogger
-import javax.inject.Inject
-import kotlinx.coroutines.CoroutineScope
-import kotlinx.coroutines.ExperimentalCoroutinesApi
-import kotlinx.coroutines.channels.awaitClose
-import kotlinx.coroutines.flow.SharingStarted.Companion.Lazily
-import kotlinx.coroutines.flow.StateFlow
-import kotlinx.coroutines.flow.callbackFlow
-import kotlinx.coroutines.flow.stateIn
-
-/**
- * Repository that contains all relevant [NetworkCapabilities] for the current networks.
- *
- * TODO(b/238425913): Figure out how to merge this with [WifiRepository].
- */
-@SysUISingleton
-class NetworkCapabilitiesRepo @Inject constructor(
- connectivityManager: ConnectivityManager,
- @Application scope: CoroutineScope,
- logger: ConnectivityPipelineLogger,
-) {
- @SuppressLint("MissingPermission")
- val dataStream: StateFlow<Map<Int, NetworkCapabilityInfo>> = run {
- var state = emptyMap<Int, NetworkCapabilityInfo>()
- callbackFlow {
- val networkRequest: NetworkRequest =
- NetworkRequest.Builder()
- .clearCapabilities()
- .addCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VPN)
- .addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
- .addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR)
- .build()
- val callback =
- // TODO (b/240569788): log these using [LogBuffer]
- object : ConnectivityManager.NetworkCallback(FLAG_INCLUDE_LOCATION_INFO) {
- override fun onCapabilitiesChanged(
- network: Network,
- networkCapabilities: NetworkCapabilities
- ) {
- logger.logOnCapabilitiesChanged(network, networkCapabilities)
- state =
- state.toMutableMap().also {
- it[network.getNetId()] =
- NetworkCapabilityInfo(network, networkCapabilities)
- }
- trySend(state)
- }
-
- override fun onLost(network: Network) {
- logger.logOnLost(network)
- state = state.toMutableMap().also { it.remove(network.getNetId()) }
- trySend(state)
- }
- }
- connectivityManager.registerNetworkCallback(networkRequest, callback)
-
- awaitClose { connectivityManager.unregisterNetworkCallback(callback) }
- }
- .stateIn(scope, started = Lazily, initialValue = state)
- }
-}
-
-/** contains info about network capabilities. */
-data class NetworkCapabilityInfo(
- val network: Network,
- val capabilities: NetworkCapabilities,
-)
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/WifiRepository.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/WifiRepository.kt
index 012dde5fb8f2..43fbabca823f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/WifiRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/WifiRepository.kt
@@ -16,16 +16,26 @@
package com.android.systemui.statusbar.pipeline.wifi.data.repository
+import android.annotation.SuppressLint
+import android.net.ConnectivityManager
+import android.net.Network
+import android.net.NetworkCapabilities
+import android.net.NetworkCapabilities.NET_CAPABILITY_NOT_VPN
+import android.net.NetworkCapabilities.TRANSPORT_CELLULAR
+import android.net.NetworkCapabilities.TRANSPORT_WIFI
+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.common.coroutine.ConflatedCallbackFlow.conflatedCallbackFlow
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Main
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.wifi.data.model.WifiActivityModel
-import com.android.systemui.statusbar.pipeline.wifi.data.model.WifiModel
+import com.android.systemui.statusbar.pipeline.wifi.data.model.WifiNetworkModel
import java.util.concurrent.Executor
import javax.inject.Inject
import kotlinx.coroutines.ExperimentalCoroutinesApi
@@ -38,9 +48,9 @@ import kotlinx.coroutines.flow.flowOf
*/
interface WifiRepository {
/**
- * Observable for the current state of wifi; `null` when there is no active wifi.
+ * Observable for the current wifi network.
*/
- val wifiModel: Flow<WifiModel?>
+ val wifiNetwork: Flow<WifiNetworkModel>
/**
* Observable for the current wifi network activity.
@@ -51,14 +61,57 @@ interface WifiRepository {
/** Real implementation of [WifiRepository]. */
@OptIn(ExperimentalCoroutinesApi::class)
@SysUISingleton
+@SuppressLint("MissingPermission")
class WifiRepositoryImpl @Inject constructor(
+ connectivityManager: ConnectivityManager,
wifiManager: WifiManager?,
@Main mainExecutor: Executor,
logger: ConnectivityPipelineLogger,
) : WifiRepository {
+ override val wifiNetwork: Flow<WifiNetworkModel> = conflatedCallbackFlow {
+ var currentWifi: WifiNetworkModel = WIFI_NETWORK_DEFAULT
- // TODO(b/238425913): Actually implement the wifiModel flow.
- override val wifiModel: Flow<WifiModel?> = flowOf(WifiModel(ssid = "AB"))
+ val callback = object : ConnectivityManager.NetworkCallback(FLAG_INCLUDE_LOCATION_INFO) {
+ override fun onCapabilitiesChanged(
+ network: Network,
+ networkCapabilities: NetworkCapabilities
+ ) {
+ logger.logOnCapabilitiesChanged(network, networkCapabilities)
+
+ val wifiInfo = networkCapabilitiesToWifiInfo(networkCapabilities)
+ if (wifiInfo?.isPrimary == true) {
+ val wifiNetworkModel = wifiInfoToModel(wifiInfo, network.getNetId())
+ logger.logTransformation(
+ WIFI_NETWORK_CALLBACK_NAME,
+ oldValue = currentWifi,
+ newValue = wifiNetworkModel
+ )
+ currentWifi = wifiNetworkModel
+ trySend(wifiNetworkModel)
+ }
+ }
+
+ override fun onLost(network: Network) {
+ logger.logOnLost(network)
+ 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)
+ }
+ }
+ }
+
+ trySend(WIFI_NETWORK_DEFAULT)
+ connectivityManager.registerNetworkCallback(WIFI_NETWORK_CALLBACK_REQUEST, callback)
+
+ awaitClose { connectivityManager.unregisterNetworkCallback(callback) }
+ }
override val wifiActivity: Flow<WifiActivityModel> =
if (wifiManager == null) {
@@ -71,8 +124,8 @@ class WifiRepositoryImpl @Inject constructor(
trySend(trafficStateToWifiActivityModel(state))
}
- wifiManager.registerTrafficStateCallback(mainExecutor, callback)
trySend(ACTIVITY_DEFAULT)
+ wifiManager.registerTrafficStateCallback(mainExecutor, callback)
awaitClose { wifiManager.unregisterTrafficStateCallback(callback) }
}
@@ -80,6 +133,13 @@ class WifiRepositoryImpl @Inject constructor(
companion object {
val ACTIVITY_DEFAULT = WifiActivityModel(hasActivityIn = false, hasActivityOut = false)
+ // Start out with no known wifi network.
+ // Note: [WifiStatusTracker] (the old implementation of connectivity logic) does do an
+ // initial fetch to get a starting wifi network. But, it uses a deprecated API
+ // [WifiManager.getConnectionInfo()], and the deprecation doc indicates to just use
+ // [ConnectivityManager.NetworkCallback] results instead. So, for now we'll just rely on the
+ // NetworkCallback inside [wifiNetwork] for our wifi network information.
+ val WIFI_NETWORK_DEFAULT = WifiNetworkModel.Inactive
private fun trafficStateToWifiActivityModel(state: Int): WifiActivityModel {
return WifiActivityModel(
@@ -90,6 +150,30 @@ class WifiRepositoryImpl @Inject constructor(
)
}
+ private fun networkCapabilitiesToWifiInfo(
+ networkCapabilities: NetworkCapabilities
+ ): WifiInfo? {
+ return when {
+ networkCapabilities.hasTransport(TRANSPORT_WIFI) ->
+ networkCapabilities.transportInfo as WifiInfo?
+ networkCapabilities.hasTransport(TRANSPORT_CELLULAR) ->
+ // Sometimes, cellular networks can act as wifi networks (known as VCN --
+ // virtual carrier network). So, see if this cellular network has wifi info.
+ Utils.tryGetWifiInfoForVcn(networkCapabilities)
+ else -> null
+ }
+ }
+
+ private fun wifiInfoToModel(wifiInfo: WifiInfo, networkId: Int): WifiNetworkModel {
+ return WifiNetworkModel.Active(
+ networkId,
+ wifiInfo.ssid,
+ wifiInfo.isPasspointAp,
+ wifiInfo.isOsuAp,
+ wifiInfo.passpointProviderFriendlyName
+ )
+ }
+
private fun prettyPrintActivity(activity: Int): String {
return when (activity) {
TrafficStateCallback.DATA_ACTIVITY_NONE -> "NONE"
@@ -99,5 +183,15 @@ class WifiRepositoryImpl @Inject constructor(
else -> "INVALID"
}
}
+
+ private val WIFI_NETWORK_CALLBACK_REQUEST: NetworkRequest =
+ NetworkRequest.Builder()
+ .clearCapabilities()
+ .addCapability(NET_CAPABILITY_NOT_VPN)
+ .addTransportType(TRANSPORT_WIFI)
+ .addTransportType(TRANSPORT_CELLULAR)
+ .build()
+
+ private const val WIFI_NETWORK_CALLBACK_NAME = "wifiNetworkModel"
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/domain/interactor/WifiInteractor.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/domain/interactor/WifiInteractor.kt
index f705399af85d..a9da63b43aa4 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/domain/interactor/WifiInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/domain/interactor/WifiInteractor.kt
@@ -18,6 +18,7 @@ package com.android.systemui.statusbar.pipeline.wifi.domain.interactor
import android.net.wifi.WifiManager
import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.statusbar.pipeline.wifi.data.model.WifiNetworkModel
import com.android.systemui.statusbar.pipeline.wifi.data.repository.WifiRepository
import javax.inject.Inject
import kotlinx.coroutines.flow.Flow
@@ -34,13 +35,15 @@ import kotlinx.coroutines.flow.map
class WifiInteractor @Inject constructor(
repository: WifiRepository,
) {
- private val ssid: Flow<String?> = repository.wifiModel.map { info ->
- when {
- info == null -> null
- info.isPasspointAccessPoint || info.isOnlineSignUpForPasspointAccessPoint ->
- info.passpointProviderFriendlyName
- info.ssid != WifiManager.UNKNOWN_SSID -> info.ssid
- else -> null
+ private val ssid: Flow<String?> = repository.wifiNetwork.map { info ->
+ when (info) {
+ is WifiNetworkModel.Inactive -> null
+ is WifiNetworkModel.Active -> when {
+ info.isPasspointAccessPoint || info.isOnlineSignUpForPasspointAccessPoint ->
+ info.passpointProviderFriendlyName
+ info.ssid != WifiManager.UNKNOWN_SSID -> info.ssid
+ else -> null
+ }
}
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/ConnectivityInfoProcessorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/ConnectivityInfoProcessorTest.kt
deleted file mode 100644
index 7b492cb7ddd1..000000000000
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/ConnectivityInfoProcessorTest.kt
+++ /dev/null
@@ -1,88 +0,0 @@
-/*
- * 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
-
-import android.net.NetworkCapabilities
-import android.testing.AndroidTestingRunner
-import androidx.test.filters.SmallTest
-import com.android.systemui.SysuiTestCase
-import com.android.systemui.statusbar.pipeline.wifi.data.repository.NetworkCapabilityInfo
-import com.android.systemui.util.mockito.mock
-import com.google.common.truth.Truth.assertThat
-import kotlinx.coroutines.CoroutineScope
-import kotlinx.coroutines.CoroutineStart
-import kotlinx.coroutines.Dispatchers
-import kotlinx.coroutines.InternalCoroutinesApi
-import kotlinx.coroutines.cancel
-import kotlinx.coroutines.flow.collect
-import kotlinx.coroutines.launch
-import kotlinx.coroutines.runBlocking
-import kotlinx.coroutines.yield
-import org.junit.Before
-import org.junit.Test
-import org.junit.runner.RunWith
-import org.mockito.Mockito.`when` as whenever
-
-@OptIn(InternalCoroutinesApi::class)
-@SmallTest
-@RunWith(AndroidTestingRunner::class)
-class ConnectivityInfoProcessorTest : SysuiTestCase() {
-
- private val statusBarPipelineFlags = mock<StatusBarPipelineFlags>()
-
- @Before
- fun setUp() {
- whenever(statusBarPipelineFlags.isNewPipelineEnabled()).thenReturn(true)
- }
-
- @Test
- fun collectorInfoUpdated_processedInfoAlsoUpdated() = runBlocking {
- // GIVEN a processor hooked up to a collector
- val scope = CoroutineScope(Dispatchers.Unconfined)
- val collector = FakeConnectivityInfoCollector()
- val processor = ConnectivityInfoProcessor(
- collector,
- context,
- scope,
- statusBarPipelineFlags,
- mock(),
- )
-
- var mostRecentValue: ProcessedConnectivityInfo? = null
- val job = launch(start = CoroutineStart.UNDISPATCHED) {
- processor.processedInfoFlow.collect {
- mostRecentValue = it
- }
- }
-
- // WHEN the collector emits a value
- val networkCapabilityInfo = mapOf(
- 10 to NetworkCapabilityInfo(mock(), NetworkCapabilities.Builder().build())
- )
- collector.emitValue(RawConnectivityInfo(networkCapabilityInfo))
- // Because our job uses [CoroutineStart.UNDISPATCHED], it executes in the same thread as
- // this test. So, our test needs to yield to let the job run.
- // Note: Once we upgrade our Kotlin coroutines testing library, we won't need this.
- yield()
-
- // THEN the processor receives it
- assertThat(mostRecentValue?.networkCapabilityInfo).isEqualTo(networkCapabilityInfo)
-
- job.cancel()
- scope.cancel()
- }
-}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/FakeConnectivityInfoCollector.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/FakeConnectivityInfoCollector.kt
deleted file mode 100644
index 710e5f6eacd3..000000000000
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/FakeConnectivityInfoCollector.kt
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- * 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
-
-import kotlinx.coroutines.flow.MutableStateFlow
-import kotlinx.coroutines.flow.asStateFlow
-
-/**
- * A test-friendly implementation of [ConnectivityInfoCollector] that just emits whatever value it
- * receives in [emitValue].
- */
-class FakeConnectivityInfoCollector : ConnectivityInfoCollector {
- private val _rawConnectivityInfoFlow = MutableStateFlow(RawConnectivityInfo())
- override val rawConnectivityInfoFlow = _rawConnectivityInfoFlow.asStateFlow()
-
- suspend fun emitValue(value: RawConnectivityInfo) {
- _rawConnectivityInfoFlow.emit(value)
- }
-}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/FakeWifiRepository.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/FakeWifiRepository.kt
index df389bc52664..6b8d4aa7c51f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/FakeWifiRepository.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/FakeWifiRepository.kt
@@ -17,21 +17,22 @@
package com.android.systemui.statusbar.pipeline.wifi.data.repository
import com.android.systemui.statusbar.pipeline.wifi.data.model.WifiActivityModel
-import com.android.systemui.statusbar.pipeline.wifi.data.model.WifiModel
+import com.android.systemui.statusbar.pipeline.wifi.data.model.WifiNetworkModel
import com.android.systemui.statusbar.pipeline.wifi.data.repository.WifiRepositoryImpl.Companion.ACTIVITY_DEFAULT
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow
/** Fake implementation of [WifiRepository] exposing set methods for all the flows. */
class FakeWifiRepository : WifiRepository {
- private val _wifiModel: MutableStateFlow<WifiModel?> = MutableStateFlow(null)
- override val wifiModel: Flow<WifiModel?> = _wifiModel
+ private val _wifiNetwork: MutableStateFlow<WifiNetworkModel> =
+ MutableStateFlow(WifiNetworkModel.Inactive)
+ override val wifiNetwork: Flow<WifiNetworkModel> = _wifiNetwork
private val _wifiActivity = MutableStateFlow(ACTIVITY_DEFAULT)
override val wifiActivity: Flow<WifiActivityModel> = _wifiActivity
- fun setWifiModel(wifiModel: WifiModel?) {
- _wifiModel.value = wifiModel
+ fun setWifiNetwork(wifiNetworkModel: WifiNetworkModel) {
+ _wifiNetwork.value = wifiNetworkModel
}
fun setWifiActivity(activity: WifiActivityModel) {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/NetworkCapabilitiesRepoTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/NetworkCapabilitiesRepoTest.kt
deleted file mode 100644
index 6edf76ce77c9..000000000000
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/NetworkCapabilitiesRepoTest.kt
+++ /dev/null
@@ -1,252 +0,0 @@
-/*
- * Copyright (C) 2022 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.statusbar.pipeline.wifi.data.repository
-
-import android.net.ConnectivityManager
-import android.net.ConnectivityManager.NetworkCallback
-import android.net.Network
-import android.net.NetworkCapabilities
-import android.net.NetworkCapabilities.NET_CAPABILITY_NOT_METERED
-import android.net.NetworkCapabilities.NET_CAPABILITY_VALIDATED
-import android.net.NetworkCapabilities.TRANSPORT_CELLULAR
-import android.net.NetworkCapabilities.TRANSPORT_WIFI
-import android.net.NetworkRequest
-import android.test.suitebuilder.annotation.SmallTest
-import android.testing.AndroidTestingRunner
-import com.android.systemui.SysuiTestCase
-import com.android.systemui.statusbar.pipeline.shared.ConnectivityPipelineLogger
-import com.android.systemui.util.mockito.mock
-import com.android.systemui.util.mockito.withArgCaptor
-import com.google.common.truth.Truth.assertThat
-import kotlinx.coroutines.CoroutineScope
-import kotlinx.coroutines.CoroutineStart
-import kotlinx.coroutines.Dispatchers
-import kotlinx.coroutines.cancel
-import kotlinx.coroutines.flow.collect
-import kotlinx.coroutines.launch
-import kotlinx.coroutines.runBlocking
-import org.junit.Before
-import org.junit.Test
-import org.junit.runner.RunWith
-import org.mockito.ArgumentMatchers.any
-import org.mockito.Mock
-import org.mockito.Mockito.verify
-import org.mockito.Mockito.`when` as whenever
-import org.mockito.MockitoAnnotations
-
-// TODO(b/240619365): Update this test to use `runTest` when we update the testing library
-@SmallTest
-@RunWith(AndroidTestingRunner::class)
-class NetworkCapabilitiesRepoTest : SysuiTestCase() {
- @Mock private lateinit var connectivityManager: ConnectivityManager
- @Mock private lateinit var logger: ConnectivityPipelineLogger
-
- @Before
- fun setup() {
- MockitoAnnotations.initMocks(this)
- }
-
- @Test
- fun testOnCapabilitiesChanged_oneNewNetwork_networkStored() = runBlocking {
- // GIVEN a repo hooked up to [ConnectivityManager]
- val scope = CoroutineScope(Dispatchers.Unconfined)
- val repo = NetworkCapabilitiesRepo(
- connectivityManager = connectivityManager,
- scope = scope,
- logger = logger,
- )
-
- val job = launch(start = CoroutineStart.UNDISPATCHED) {
- repo.dataStream.collect {
- }
- }
-
- val callback: NetworkCallback = withArgCaptor {
- verify(connectivityManager)
- .registerNetworkCallback(any(NetworkRequest::class.java), capture())
- }
-
- // WHEN a new network is added
- callback.onCapabilitiesChanged(NET_1, NET_1_CAPS)
-
- val currentMap = repo.dataStream.value
-
- // THEN it is emitted from the flow
- assertThat(currentMap[NET_1_ID]?.network).isEqualTo(NET_1)
- assertThat(currentMap[NET_1_ID]?.capabilities).isEqualTo(NET_1_CAPS)
-
- job.cancel()
- scope.cancel()
- }
-
- @Test
- fun testOnCapabilitiesChanged_twoNewNetworks_bothStored() = runBlocking {
- // GIVEN a repo hooked up to [ConnectivityManager]
- val scope = CoroutineScope(Dispatchers.Unconfined)
- val repo = NetworkCapabilitiesRepo(
- connectivityManager = connectivityManager,
- scope = scope,
- logger = logger,
- )
-
- val job = launch(start = CoroutineStart.UNDISPATCHED) {
- repo.dataStream.collect {
- }
- }
-
- val callback: NetworkCallback = withArgCaptor {
- verify(connectivityManager)
- .registerNetworkCallback(any(NetworkRequest::class.java), capture())
- }
-
- // WHEN two new networks are added
- callback.onCapabilitiesChanged(NET_1, NET_1_CAPS)
- callback.onCapabilitiesChanged(NET_2, NET_2_CAPS)
-
- val currentMap = repo.dataStream.value
-
- // THEN the current state of the flow reflects 2 networks
- assertThat(currentMap[NET_1_ID]?.network).isEqualTo(NET_1)
- assertThat(currentMap[NET_1_ID]?.capabilities).isEqualTo(NET_1_CAPS)
- assertThat(currentMap[NET_2_ID]?.network).isEqualTo(NET_2)
- assertThat(currentMap[NET_2_ID]?.capabilities).isEqualTo(NET_2_CAPS)
-
- job.cancel()
- scope.cancel()
- }
-
- @Test
- fun testOnCapabilitesChanged_newCapabilitiesForExistingNetwork_areCaptured() = runBlocking {
- // GIVEN a repo hooked up to [ConnectivityManager]
- val scope = CoroutineScope(Dispatchers.Unconfined)
- val repo = NetworkCapabilitiesRepo(
- connectivityManager = connectivityManager,
- scope = scope,
- logger = logger,
- )
-
- val job = launch(start = CoroutineStart.UNDISPATCHED) {
- repo.dataStream.collect {
- }
- }
-
- val callback: NetworkCallback = withArgCaptor {
- verify(connectivityManager)
- .registerNetworkCallback(any(NetworkRequest::class.java), capture())
- }
-
- // WHEN a network is added, and then its capabilities are changed
- callback.onCapabilitiesChanged(NET_1, NET_1_CAPS)
- callback.onCapabilitiesChanged(NET_1, NET_2_CAPS)
-
- val currentMap = repo.dataStream.value
-
- // THEN the current state of the flow reflects the new capabilities
- assertThat(currentMap[NET_1_ID]?.capabilities).isEqualTo(NET_2_CAPS)
-
- job.cancel()
- scope.cancel()
- }
-
- @Test
- fun testOnLost_networkIsRemoved() = runBlocking {
- // GIVEN a repo hooked up to [ConnectivityManager]
- val scope = CoroutineScope(Dispatchers.Unconfined)
- val repo = NetworkCapabilitiesRepo(
- connectivityManager = connectivityManager,
- scope = scope,
- logger = logger,
- )
-
- val job = launch(start = CoroutineStart.UNDISPATCHED) {
- repo.dataStream.collect {
- }
- }
-
- val callback: NetworkCallback = withArgCaptor {
- verify(connectivityManager)
- .registerNetworkCallback(any(NetworkRequest::class.java), capture())
- }
-
- // WHEN two new networks are added, and one is removed
- callback.onCapabilitiesChanged(NET_1, NET_1_CAPS)
- callback.onCapabilitiesChanged(NET_2, NET_2_CAPS)
- callback.onLost(NET_1)
-
- val currentMap = repo.dataStream.value
-
- // THEN the current state of the flow reflects only the remaining network
- assertThat(currentMap[NET_1_ID]).isNull()
- assertThat(currentMap[NET_2_ID]?.network).isEqualTo(NET_2)
- assertThat(currentMap[NET_2_ID]?.capabilities).isEqualTo(NET_2_CAPS)
-
- job.cancel()
- scope.cancel()
- }
-
- @Test
- fun testOnLost_noNetworks_doesNotCrash() = runBlocking {
- // GIVEN a repo hooked up to [ConnectivityManager]
- val scope = CoroutineScope(Dispatchers.Unconfined)
- val repo = NetworkCapabilitiesRepo(
- connectivityManager = connectivityManager,
- scope = scope,
- logger = logger,
- )
-
- val job = launch(start = CoroutineStart.UNDISPATCHED) {
- repo.dataStream.collect {
- }
- }
-
- val callback: NetworkCallback = withArgCaptor {
- verify(connectivityManager)
- .registerNetworkCallback(any(NetworkRequest::class.java), capture())
- }
-
- // WHEN no networks are added, and one is removed
- callback.onLost(NET_1)
-
- val currentMap = repo.dataStream.value
-
- // THEN the current state of the flow shows no networks
- assertThat(currentMap).isEmpty()
-
- job.cancel()
- scope.cancel()
- }
-
- private val NET_1_ID = 100
- private val NET_1 = mock<Network>().also {
- whenever(it.getNetId()).thenReturn(NET_1_ID)
- }
- private val NET_2_ID = 200
- private val NET_2 = mock<Network>().also {
- whenever(it.getNetId()).thenReturn(NET_2_ID)
- }
-
- private val NET_1_CAPS = NetworkCapabilities.Builder()
- .addTransportType(TRANSPORT_CELLULAR)
- .addCapability(NET_CAPABILITY_VALIDATED)
- .build()
-
- private val NET_2_CAPS = NetworkCapabilities.Builder()
- .addTransportType(TRANSPORT_WIFI)
- .addCapability(NET_CAPABILITY_NOT_METERED)
- .addCapability(NET_CAPABILITY_VALIDATED)
- .build()
-}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/WifiRepositoryImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/WifiRepositoryImplTest.kt
index 8b61364a2ac9..d0a38084af76 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/WifiRepositoryImplTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/WifiRepositoryImplTest.kt
@@ -16,16 +16,26 @@
package com.android.systemui.statusbar.pipeline.wifi.data.repository
+import android.net.ConnectivityManager
+import android.net.Network
+import android.net.NetworkCapabilities
+import android.net.NetworkCapabilities.TRANSPORT_CELLULAR
+import android.net.NetworkCapabilities.TRANSPORT_WIFI
+import android.net.vcn.VcnTransportInfo
+import android.net.wifi.WifiInfo
import android.net.wifi.WifiManager
import android.net.wifi.WifiManager.TrafficStateCallback
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.statusbar.pipeline.shared.ConnectivityPipelineLogger
import com.android.systemui.statusbar.pipeline.wifi.data.model.WifiActivityModel
+import com.android.systemui.statusbar.pipeline.wifi.data.model.WifiNetworkModel
import com.android.systemui.statusbar.pipeline.wifi.data.repository.WifiRepositoryImpl.Companion.ACTIVITY_DEFAULT
+import com.android.systemui.statusbar.pipeline.wifi.data.repository.WifiRepositoryImpl.Companion.WIFI_NETWORK_DEFAULT
import com.android.systemui.util.concurrency.FakeExecutor
import com.android.systemui.util.mockito.any
import com.android.systemui.util.mockito.argumentCaptor
+import com.android.systemui.util.mockito.mock
import com.android.systemui.util.time.FakeSystemClock
import com.google.common.truth.Truth.assertThat
import java.util.concurrent.Executor
@@ -38,6 +48,7 @@ import org.junit.Before
import org.junit.Test
import org.mockito.Mock
import org.mockito.Mockito.verify
+import org.mockito.Mockito.`when` as whenever
import org.mockito.MockitoAnnotations
@OptIn(ExperimentalCoroutinesApi::class)
@@ -47,6 +58,7 @@ class WifiRepositoryImplTest : SysuiTestCase() {
private lateinit var underTest: WifiRepositoryImpl
@Mock private lateinit var logger: ConnectivityPipelineLogger
+ @Mock private lateinit var connectivityManager: ConnectivityManager
@Mock private lateinit var wifiManager: WifiManager
private lateinit var executor: Executor
@@ -54,11 +66,347 @@ class WifiRepositoryImplTest : SysuiTestCase() {
fun setUp() {
MockitoAnnotations.initMocks(this)
executor = FakeExecutor(FakeSystemClock())
+
+ underTest = WifiRepositoryImpl(
+ connectivityManager,
+ wifiManager,
+ executor,
+ logger,
+ )
+ }
+
+ @Test
+ fun wifiNetwork_initiallyGetsDefault() = runBlocking(IMMEDIATE) {
+ var latest: WifiNetworkModel? = null
+ val job = underTest
+ .wifiNetwork
+ .onEach { latest = it }
+ .launchIn(this)
+
+ assertThat(latest).isEqualTo(WIFI_NETWORK_DEFAULT)
+
+ job.cancel()
+ }
+
+ @Test
+ fun wifiNetwork_primaryWifiNetworkAdded_flowHasNetwork() = runBlocking(IMMEDIATE) {
+ var latest: WifiNetworkModel? = null
+ val job = underTest
+ .wifiNetwork
+ .onEach { latest = it }
+ .launchIn(this)
+
+ val wifiInfo = mock<WifiInfo>().apply {
+ whenever(this.ssid).thenReturn(SSID)
+ whenever(this.isPrimary).thenReturn(true)
+ }
+ val network = mock<Network>().apply {
+ whenever(this.getNetId()).thenReturn(NETWORK_ID)
+ }
+
+ getNetworkCallback().onCapabilitiesChanged(network, createWifiNetworkCapabilities(wifiInfo))
+
+ assertThat(latest is WifiNetworkModel.Active).isTrue()
+ val latestActive = latest as WifiNetworkModel.Active
+ assertThat(latestActive.networkId).isEqualTo(NETWORK_ID)
+ assertThat(latestActive.ssid).isEqualTo(SSID)
+
+ job.cancel()
+ }
+
+ @Test
+ fun wifiNetwork_nonPrimaryWifiNetworkAdded_flowHasNoNetwork() = runBlocking(IMMEDIATE) {
+ var latest: WifiNetworkModel? = null
+ val job = underTest
+ .wifiNetwork
+ .onEach { latest = it }
+ .launchIn(this)
+
+ val wifiInfo = mock<WifiInfo>().apply {
+ whenever(this.ssid).thenReturn(SSID)
+ whenever(this.isPrimary).thenReturn(false)
+ }
+
+ getNetworkCallback().onCapabilitiesChanged(NETWORK, createWifiNetworkCapabilities(wifiInfo))
+
+ assertThat(latest is WifiNetworkModel.Inactive).isTrue()
+
+ job.cancel()
+ }
+
+ @Test
+ fun wifiNetwork_cellularVcnNetworkAdded_flowHasNetwork() = runBlocking(IMMEDIATE) {
+ var latest: WifiNetworkModel? = null
+ val job = underTest
+ .wifiNetwork
+ .onEach { latest = it }
+ .launchIn(this)
+
+ val capabilities = mock<NetworkCapabilities>().apply {
+ whenever(this.hasTransport(TRANSPORT_CELLULAR)).thenReturn(true)
+ whenever(this.transportInfo).thenReturn(VcnTransportInfo(PRIMARY_WIFI_INFO))
+ }
+
+ getNetworkCallback().onCapabilitiesChanged(NETWORK, capabilities)
+
+ assertThat(latest is WifiNetworkModel.Active).isTrue()
+ val latestActive = latest as WifiNetworkModel.Active
+ assertThat(latestActive.networkId).isEqualTo(NETWORK_ID)
+ assertThat(latestActive.ssid).isEqualTo(SSID)
+
+ job.cancel()
+ }
+
+ @Test
+ fun wifiNetwork_nonPrimaryCellularVcnNetworkAdded_flowHasNoNetwork() = runBlocking(IMMEDIATE) {
+ var latest: WifiNetworkModel? = null
+ val job = underTest
+ .wifiNetwork
+ .onEach { latest = it }
+ .launchIn(this)
+
+ val wifiInfo = mock<WifiInfo>().apply {
+ whenever(this.ssid).thenReturn(SSID)
+ whenever(this.isPrimary).thenReturn(false)
+ }
+ val capabilities = mock<NetworkCapabilities>().apply {
+ whenever(this.hasTransport(TRANSPORT_CELLULAR)).thenReturn(true)
+ whenever(this.transportInfo).thenReturn(VcnTransportInfo(wifiInfo))
+ }
+
+ getNetworkCallback().onCapabilitiesChanged(NETWORK, capabilities)
+
+ assertThat(latest is WifiNetworkModel.Inactive).isTrue()
+
+ job.cancel()
+ }
+
+ @Test
+ fun wifiNetwork_cellularNotVcnNetworkAdded_flowHasNoNetwork() = runBlocking(IMMEDIATE) {
+ var latest: WifiNetworkModel? = null
+ val job = underTest
+ .wifiNetwork
+ .onEach { latest = it }
+ .launchIn(this)
+
+ val capabilities = mock<NetworkCapabilities>().apply {
+ whenever(this.hasTransport(TRANSPORT_CELLULAR)).thenReturn(true)
+ whenever(this.transportInfo).thenReturn(mock())
+ }
+
+ getNetworkCallback().onCapabilitiesChanged(NETWORK, capabilities)
+
+ assertThat(latest is WifiNetworkModel.Inactive).isTrue()
+
+ job.cancel()
+ }
+
+ @Test
+ fun wifiNetwork_newPrimaryWifiNetwork_flowHasNewNetwork() = runBlocking(IMMEDIATE) {
+ var latest: WifiNetworkModel? = null
+ val job = underTest
+ .wifiNetwork
+ .onEach { latest = it }
+ .launchIn(this)
+
+ // Start with the original network
+ getNetworkCallback()
+ .onCapabilitiesChanged(NETWORK, createWifiNetworkCapabilities(PRIMARY_WIFI_INFO))
+
+ // WHEN we update to a new primary network
+ val newNetworkId = 456
+ val newNetwork = mock<Network>().apply {
+ whenever(this.getNetId()).thenReturn(newNetworkId)
+ }
+ val newSsid = "CD"
+ val newWifiInfo = mock<WifiInfo>().apply {
+ whenever(this.ssid).thenReturn(newSsid)
+ whenever(this.isPrimary).thenReturn(true)
+ }
+
+ getNetworkCallback().onCapabilitiesChanged(
+ newNetwork, createWifiNetworkCapabilities(newWifiInfo)
+ )
+
+ // THEN we use the new network
+ assertThat(latest is WifiNetworkModel.Active).isTrue()
+ val latestActive = latest as WifiNetworkModel.Active
+ assertThat(latestActive.networkId).isEqualTo(newNetworkId)
+ assertThat(latestActive.ssid).isEqualTo(newSsid)
+
+ job.cancel()
+ }
+
+ @Test
+ fun wifiNetwork_newNonPrimaryWifiNetwork_flowHasOldNetwork() = runBlocking(IMMEDIATE) {
+ var latest: WifiNetworkModel? = null
+ val job = underTest
+ .wifiNetwork
+ .onEach { latest = it }
+ .launchIn(this)
+
+ // Start with the original network
+ getNetworkCallback()
+ .onCapabilitiesChanged(NETWORK, createWifiNetworkCapabilities(PRIMARY_WIFI_INFO))
+
+ // WHEN we notify of a new but non-primary network
+ val newNetworkId = 456
+ val newNetwork = mock<Network>().apply {
+ whenever(this.getNetId()).thenReturn(newNetworkId)
+ }
+ val newSsid = "EF"
+ val newWifiInfo = mock<WifiInfo>().apply {
+ whenever(this.ssid).thenReturn(newSsid)
+ whenever(this.isPrimary).thenReturn(false)
+ }
+
+ getNetworkCallback().onCapabilitiesChanged(
+ newNetwork, createWifiNetworkCapabilities(newWifiInfo)
+ )
+
+ // THEN we still use the original network
+ assertThat(latest is WifiNetworkModel.Active).isTrue()
+ val latestActive = latest as WifiNetworkModel.Active
+ assertThat(latestActive.networkId).isEqualTo(NETWORK_ID)
+ assertThat(latestActive.ssid).isEqualTo(SSID)
+
+ job.cancel()
+ }
+
+ @Test
+ fun wifiNetwork_newNetworkCapabilities_flowHasNewData() = runBlocking(IMMEDIATE) {
+ var latest: WifiNetworkModel? = null
+ val job = underTest
+ .wifiNetwork
+ .onEach { latest = it }
+ .launchIn(this)
+
+ val wifiInfo = mock<WifiInfo>().apply {
+ whenever(this.ssid).thenReturn(SSID)
+ whenever(this.isPrimary).thenReturn(true)
+ }
+
+ // Start with the original network
+ getNetworkCallback()
+ .onCapabilitiesChanged(NETWORK, createWifiNetworkCapabilities(wifiInfo))
+
+ // WHEN we keep the same network ID but change the SSID
+ val newSsid = "CD"
+ val newWifiInfo = mock<WifiInfo>().apply {
+ whenever(this.ssid).thenReturn(newSsid)
+ whenever(this.isPrimary).thenReturn(true)
+ }
+
+ getNetworkCallback()
+ .onCapabilitiesChanged(NETWORK, createWifiNetworkCapabilities(newWifiInfo))
+
+ // THEN we've updated to the new SSID
+ assertThat(latest is WifiNetworkModel.Active).isTrue()
+ val latestActive = latest as WifiNetworkModel.Active
+ assertThat(latestActive.networkId).isEqualTo(NETWORK_ID)
+ assertThat(latestActive.ssid).isEqualTo(newSsid)
+
+ job.cancel()
+ }
+
+ @Test
+ fun wifiNetwork_noCurrentNetwork_networkLost_flowHasNoNetwork() = runBlocking(IMMEDIATE) {
+ var latest: WifiNetworkModel? = null
+ val job = underTest
+ .wifiNetwork
+ .onEach { latest = it }
+ .launchIn(this)
+
+ // WHEN we receive #onLost without any #onCapabilitiesChanged beforehand
+ getNetworkCallback().onLost(NETWORK)
+
+ // THEN there's no crash and we still have no network
+ assertThat(latest is WifiNetworkModel.Inactive).isTrue()
+
+ job.cancel()
+ }
+
+ @Test
+ fun wifiNetwork_currentNetworkLost_flowHasNoNetwork() = runBlocking(IMMEDIATE) {
+ var latest: WifiNetworkModel? = null
+ val job = underTest
+ .wifiNetwork
+ .onEach { latest = it }
+ .launchIn(this)
+
+ getNetworkCallback()
+ .onCapabilitiesChanged(NETWORK, createWifiNetworkCapabilities(PRIMARY_WIFI_INFO))
+ assertThat((latest as WifiNetworkModel.Active).networkId).isEqualTo(NETWORK_ID)
+
+ // WHEN we lose our current network
+ getNetworkCallback().onLost(NETWORK)
+
+ // THEN we update to no network
+ assertThat(latest is WifiNetworkModel.Inactive).isTrue()
+
+ job.cancel()
+ }
+
+ @Test
+ fun wifiNetwork_unknownNetworkLost_flowHasPreviousNetwork() = runBlocking(IMMEDIATE) {
+ var latest: WifiNetworkModel? = null
+ val job = underTest
+ .wifiNetwork
+ .onEach { latest = it }
+ .launchIn(this)
+
+ getNetworkCallback()
+ .onCapabilitiesChanged(NETWORK, createWifiNetworkCapabilities(PRIMARY_WIFI_INFO))
+ assertThat((latest as WifiNetworkModel.Active).networkId).isEqualTo(NETWORK_ID)
+
+ // WHEN we lose an unknown network
+ val unknownNetwork = mock<Network>().apply {
+ whenever(this.getNetId()).thenReturn(543)
+ }
+ getNetworkCallback().onLost(unknownNetwork)
+
+ // THEN we still have our previous network
+ assertThat(latest is WifiNetworkModel.Active).isTrue()
+ val latestActive = latest as WifiNetworkModel.Active
+ assertThat(latestActive.networkId).isEqualTo(NETWORK_ID)
+ assertThat(latestActive.ssid).isEqualTo(SSID)
+
+ job.cancel()
+ }
+
+ @Test
+ fun wifiNetwork_notCurrentNetworkLost_flowHasCurrentNetwork() = runBlocking(IMMEDIATE) {
+ var latest: WifiNetworkModel? = null
+ val job = underTest
+ .wifiNetwork
+ .onEach { latest = it }
+ .launchIn(this)
+
+ getNetworkCallback()
+ .onCapabilitiesChanged(NETWORK, createWifiNetworkCapabilities(PRIMARY_WIFI_INFO))
+ assertThat((latest as WifiNetworkModel.Active).networkId).isEqualTo(NETWORK_ID)
+
+ // WHEN we update to a new network...
+ val newNetworkId = 89
+ val newNetwork = mock<Network>().apply {
+ whenever(this.getNetId()).thenReturn(newNetworkId)
+ }
+ getNetworkCallback().onCapabilitiesChanged(
+ newNetwork, createWifiNetworkCapabilities(PRIMARY_WIFI_INFO)
+ )
+ // ...and lose the old network
+ getNetworkCallback().onLost(NETWORK)
+
+ // THEN we still have the new network
+ assertThat((latest as WifiNetworkModel.Active).networkId).isEqualTo(newNetworkId)
+
+ job.cancel()
}
@Test
fun wifiActivity_nullWifiManager_receivesDefault() = runBlocking(IMMEDIATE) {
underTest = WifiRepositoryImpl(
+ connectivityManager,
wifiManager = null,
executor,
logger,
@@ -77,12 +425,6 @@ class WifiRepositoryImplTest : SysuiTestCase() {
@Test
fun wifiActivity_callbackGivesNone_activityFlowHasNone() = runBlocking(IMMEDIATE) {
- underTest = WifiRepositoryImpl(
- wifiManager,
- executor,
- logger,
- )
-
var latest: WifiActivityModel? = null
val job = underTest
.wifiActivity
@@ -100,12 +442,6 @@ class WifiRepositoryImplTest : SysuiTestCase() {
@Test
fun wifiActivity_callbackGivesIn_activityFlowHasIn() = runBlocking(IMMEDIATE) {
- underTest = WifiRepositoryImpl(
- wifiManager,
- executor,
- logger,
- )
-
var latest: WifiActivityModel? = null
val job = underTest
.wifiActivity
@@ -123,12 +459,6 @@ class WifiRepositoryImplTest : SysuiTestCase() {
@Test
fun wifiActivity_callbackGivesOut_activityFlowHasOut() = runBlocking(IMMEDIATE) {
- underTest = WifiRepositoryImpl(
- wifiManager,
- executor,
- logger,
- )
-
var latest: WifiActivityModel? = null
val job = underTest
.wifiActivity
@@ -146,12 +476,6 @@ class WifiRepositoryImplTest : SysuiTestCase() {
@Test
fun wifiActivity_callbackGivesInout_activityFlowHasInAndOut() = runBlocking(IMMEDIATE) {
- underTest = WifiRepositoryImpl(
- wifiManager,
- executor,
- logger,
- )
-
var latest: WifiActivityModel? = null
val job = underTest
.wifiActivity
@@ -170,6 +494,30 @@ class WifiRepositoryImplTest : SysuiTestCase() {
verify(wifiManager).registerTrafficStateCallback(any(), callbackCaptor.capture())
return callbackCaptor.value!!
}
+
+ private fun getNetworkCallback(): ConnectivityManager.NetworkCallback {
+ val callbackCaptor = argumentCaptor<ConnectivityManager.NetworkCallback>()
+ verify(connectivityManager).registerNetworkCallback(any(), callbackCaptor.capture())
+ return callbackCaptor.value!!
+ }
+
+ private fun createWifiNetworkCapabilities(wifiInfo: WifiInfo) =
+ mock<NetworkCapabilities>().apply {
+ whenever(this.hasTransport(TRANSPORT_WIFI)).thenReturn(true)
+ whenever(this.transportInfo).thenReturn(wifiInfo)
+ }
+
+ private companion object {
+ const val NETWORK_ID = 45
+ val NETWORK = mock<Network>().apply {
+ whenever(this.getNetId()).thenReturn(NETWORK_ID)
+ }
+ const val SSID = "AB"
+ val PRIMARY_WIFI_INFO: WifiInfo = mock<WifiInfo>().apply {
+ whenever(this.ssid).thenReturn(SSID)
+ whenever(this.isPrimary).thenReturn(true)
+ }
+ }
}
private val IMMEDIATE = Dispatchers.Main.immediate
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/domain/interactor/WifiInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/domain/interactor/WifiInteractorTest.kt
index c52f347a605a..5f1b1dbb19dc 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/domain/interactor/WifiInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/domain/interactor/WifiInteractorTest.kt
@@ -19,7 +19,7 @@ package com.android.systemui.statusbar.pipeline.wifi.domain.interactor
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.statusbar.pipeline.wifi.data.model.WifiActivityModel
-import com.android.systemui.statusbar.pipeline.wifi.data.model.WifiModel
+import com.android.systemui.statusbar.pipeline.wifi.data.model.WifiNetworkModel
import com.android.systemui.statusbar.pipeline.wifi.data.repository.FakeWifiRepository
import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.Dispatchers
@@ -47,7 +47,7 @@ class WifiInteractorTest : SysuiTestCase() {
@Test
fun hasActivityIn_noInOrOut_outputsFalse() = runBlocking(IMMEDIATE) {
- repository.setWifiModel(WifiModel(ssid = "AB"))
+ repository.setWifiNetwork(VALID_WIFI_NETWORK_MODEL)
repository.setWifiActivity(WifiActivityModel(hasActivityIn = false, hasActivityOut = false))
var latest: Boolean? = null
@@ -63,7 +63,7 @@ class WifiInteractorTest : SysuiTestCase() {
@Test
fun hasActivityIn_onlyOut_outputsFalse() = runBlocking(IMMEDIATE) {
- repository.setWifiModel(WifiModel(ssid = "AB"))
+ repository.setWifiNetwork(VALID_WIFI_NETWORK_MODEL)
repository.setWifiActivity(WifiActivityModel(hasActivityIn = false, hasActivityOut = true))
var latest: Boolean? = null
@@ -79,7 +79,7 @@ class WifiInteractorTest : SysuiTestCase() {
@Test
fun hasActivityIn_onlyIn_outputsTrue() = runBlocking(IMMEDIATE) {
- repository.setWifiModel(WifiModel(ssid = "AB"))
+ repository.setWifiNetwork(VALID_WIFI_NETWORK_MODEL)
repository.setWifiActivity(WifiActivityModel(hasActivityIn = true, hasActivityOut = false))
var latest: Boolean? = null
@@ -95,7 +95,7 @@ class WifiInteractorTest : SysuiTestCase() {
@Test
fun hasActivityIn_inAndOut_outputsTrue() = runBlocking(IMMEDIATE) {
- repository.setWifiModel(WifiModel(ssid = "AB"))
+ repository.setWifiNetwork(VALID_WIFI_NETWORK_MODEL)
repository.setWifiActivity(WifiActivityModel(hasActivityIn = true, hasActivityOut = true))
var latest: Boolean? = null
@@ -111,7 +111,7 @@ class WifiInteractorTest : SysuiTestCase() {
@Test
fun hasActivityIn_ssidNull_outputsFalse() = runBlocking(IMMEDIATE) {
- repository.setWifiModel(WifiModel(ssid = null))
+ repository.setWifiNetwork(WifiNetworkModel.Active(networkId = 1, ssid = null))
repository.setWifiActivity(WifiActivityModel(hasActivityIn = true, hasActivityOut = true))
var latest: Boolean? = null
@@ -127,7 +127,7 @@ class WifiInteractorTest : SysuiTestCase() {
@Test
fun hasActivityIn_multipleChanges_multipleOutputChanges() = runBlocking(IMMEDIATE) {
- repository.setWifiModel(WifiModel(ssid = "AB"))
+ repository.setWifiNetwork(VALID_WIFI_NETWORK_MODEL)
var latest: Boolean? = null
val job = underTest
@@ -158,6 +158,10 @@ class WifiInteractorTest : SysuiTestCase() {
job.cancel()
}
+
+ companion object {
+ val VALID_WIFI_NETWORK_MODEL = WifiNetworkModel.Active(networkId = 1, ssid = "AB")
+ }
}
private val IMMEDIATE = Dispatchers.Main.immediate
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/ui/viewmodel/WifiViewModelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/ui/viewmodel/WifiViewModelTest.kt
index e9259b071e0b..fae4b1055968 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/ui/viewmodel/WifiViewModelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/ui/viewmodel/WifiViewModelTest.kt
@@ -20,7 +20,7 @@ import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.statusbar.pipeline.shared.ConnectivityPipelineLogger
import com.android.systemui.statusbar.pipeline.wifi.data.model.WifiActivityModel
-import com.android.systemui.statusbar.pipeline.wifi.data.model.WifiModel
+import com.android.systemui.statusbar.pipeline.wifi.data.model.WifiNetworkModel
import com.android.systemui.statusbar.pipeline.wifi.data.repository.FakeWifiRepository
import com.android.systemui.statusbar.pipeline.wifi.domain.interactor.WifiInteractor
import com.android.systemui.statusbar.pipeline.wifi.shared.WifiConstants
@@ -61,7 +61,7 @@ class WifiViewModelTest : SysuiTestCase() {
)
// Set up with a valid SSID
- repository.setWifiModel(WifiModel(ssid = "AB"))
+ repository.setWifiNetwork(WifiNetworkModel.Active(networkId = 1, ssid = "AB"))
}
@Test