Merge "[SB Refactor] Implement the wifi icon flow in the new pipeline." into tm-qpr-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
a9b3416a87
@@ -31,7 +31,7 @@ public class WifiIcons {
|
|||||||
com.android.internal.R.drawable.ic_wifi_signal_4
|
com.android.internal.R.drawable.ic_wifi_signal_4
|
||||||
};
|
};
|
||||||
|
|
||||||
private static final int[] WIFI_NO_INTERNET_ICONS = {
|
public static final int[] WIFI_NO_INTERNET_ICONS = {
|
||||||
R.drawable.ic_no_internet_wifi_signal_0,
|
R.drawable.ic_no_internet_wifi_signal_0,
|
||||||
R.drawable.ic_no_internet_wifi_signal_1,
|
R.drawable.ic_no_internet_wifi_signal_1,
|
||||||
R.drawable.ic_no_internet_wifi_signal_2,
|
R.drawable.ic_no_internet_wifi_signal_2,
|
||||||
@@ -48,7 +48,7 @@ public class WifiIcons {
|
|||||||
|
|
||||||
public static final int QS_WIFI_DISABLED = com.android.internal.R.drawable.ic_wifi_signal_0;
|
public static final int QS_WIFI_DISABLED = com.android.internal.R.drawable.ic_wifi_signal_0;
|
||||||
public static final int QS_WIFI_NO_NETWORK = com.android.internal.R.drawable.ic_wifi_signal_0;
|
public static final int QS_WIFI_NO_NETWORK = com.android.internal.R.drawable.ic_wifi_signal_0;
|
||||||
static final int WIFI_NO_NETWORK = QS_WIFI_NO_NETWORK;
|
public static final int WIFI_NO_NETWORK = QS_WIFI_NO_NETWORK;
|
||||||
|
|
||||||
static final int WIFI_LEVEL_COUNT = WIFI_SIGNAL_STRENGTH[0].length;
|
static final int WIFI_LEVEL_COUNT = WIFI_SIGNAL_STRENGTH[0].length;
|
||||||
|
|
||||||
|
|||||||
@@ -16,13 +16,23 @@
|
|||||||
|
|
||||||
package com.android.systemui.statusbar.pipeline.wifi.data.model
|
package com.android.systemui.statusbar.pipeline.wifi.data.model
|
||||||
|
|
||||||
|
import androidx.annotation.VisibleForTesting
|
||||||
|
|
||||||
/** Provides information about the current wifi network. */
|
/** Provides information about the current wifi network. */
|
||||||
sealed class WifiNetworkModel {
|
sealed class WifiNetworkModel {
|
||||||
/** A model representing that we have no active wifi network. */
|
/** A model representing that we have no active wifi network. */
|
||||||
object Inactive : WifiNetworkModel()
|
object Inactive : WifiNetworkModel()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A model representing that our wifi network is actually a carrier merged network, meaning it's
|
||||||
|
* treated as more of a mobile network.
|
||||||
|
*
|
||||||
|
* See [android.net.wifi.WifiInfo.isCarrierMerged] for more information.
|
||||||
|
*/
|
||||||
|
object CarrierMerged : WifiNetworkModel()
|
||||||
|
|
||||||
/** Provides information about an active wifi network. */
|
/** Provides information about an active wifi network. */
|
||||||
class Active(
|
data class Active(
|
||||||
/**
|
/**
|
||||||
* The [android.net.Network.netId] we received from
|
* The [android.net.Network.netId] we received from
|
||||||
* [android.net.ConnectivityManager.NetworkCallback] in association with this wifi network.
|
* [android.net.ConnectivityManager.NetworkCallback] in association with this wifi network.
|
||||||
@@ -31,6 +41,19 @@ sealed class WifiNetworkModel {
|
|||||||
*/
|
*/
|
||||||
val networkId: Int,
|
val networkId: Int,
|
||||||
|
|
||||||
|
/** See [android.net.NetworkCapabilities.NET_CAPABILITY_VALIDATED]. */
|
||||||
|
val isValidated: Boolean = false,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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,
|
||||||
|
|
||||||
/** See [android.net.wifi.WifiInfo.ssid]. */
|
/** See [android.net.wifi.WifiInfo.ssid]. */
|
||||||
val ssid: String? = null,
|
val ssid: String? = null,
|
||||||
|
|
||||||
@@ -42,5 +65,18 @@ sealed class WifiNetworkModel {
|
|||||||
|
|
||||||
/** See [android.net.wifi.WifiInfo.passpointProviderFriendlyName]. */
|
/** See [android.net.wifi.WifiInfo.passpointProviderFriendlyName]. */
|
||||||
val passpointProviderFriendlyName: String? = null,
|
val passpointProviderFriendlyName: String? = null,
|
||||||
) : WifiNetworkModel()
|
) : WifiNetworkModel() {
|
||||||
|
init {
|
||||||
|
require(level == null || level in MIN_VALID_LEVEL..MAX_VALID_LEVEL) {
|
||||||
|
"0 <= wifi level <= 4 required; level was $level"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
@VisibleForTesting
|
||||||
|
internal const val MIN_VALID_LEVEL = 0
|
||||||
|
@VisibleForTesting
|
||||||
|
internal const val MAX_VALID_LEVEL = 4
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ import android.net.ConnectivityManager
|
|||||||
import android.net.Network
|
import android.net.Network
|
||||||
import android.net.NetworkCapabilities
|
import android.net.NetworkCapabilities
|
||||||
import android.net.NetworkCapabilities.NET_CAPABILITY_NOT_VPN
|
import android.net.NetworkCapabilities.NET_CAPABILITY_NOT_VPN
|
||||||
|
import android.net.NetworkCapabilities.NET_CAPABILITY_VALIDATED
|
||||||
import android.net.NetworkCapabilities.TRANSPORT_CELLULAR
|
import android.net.NetworkCapabilities.TRANSPORT_CELLULAR
|
||||||
import android.net.NetworkCapabilities.TRANSPORT_WIFI
|
import android.net.NetworkCapabilities.TRANSPORT_WIFI
|
||||||
import android.net.NetworkRequest
|
import android.net.NetworkRequest
|
||||||
@@ -31,6 +32,7 @@ import android.util.Log
|
|||||||
import com.android.settingslib.Utils
|
import com.android.settingslib.Utils
|
||||||
import com.android.systemui.common.coroutine.ConflatedCallbackFlow.conflatedCallbackFlow
|
import com.android.systemui.common.coroutine.ConflatedCallbackFlow.conflatedCallbackFlow
|
||||||
import com.android.systemui.dagger.SysUISingleton
|
import com.android.systemui.dagger.SysUISingleton
|
||||||
|
import com.android.systemui.dagger.qualifiers.Application
|
||||||
import com.android.systemui.dagger.qualifiers.Main
|
import com.android.systemui.dagger.qualifiers.Main
|
||||||
import com.android.systemui.statusbar.pipeline.shared.ConnectivityPipelineLogger
|
import com.android.systemui.statusbar.pipeline.shared.ConnectivityPipelineLogger
|
||||||
import com.android.systemui.statusbar.pipeline.shared.ConnectivityPipelineLogger.Companion.SB_LOGGING_TAG
|
import com.android.systemui.statusbar.pipeline.shared.ConnectivityPipelineLogger.Companion.SB_LOGGING_TAG
|
||||||
@@ -38,10 +40,13 @@ 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.model.WifiNetworkModel
|
||||||
import java.util.concurrent.Executor
|
import java.util.concurrent.Executor
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||||
import kotlinx.coroutines.channels.awaitClose
|
import kotlinx.coroutines.channels.awaitClose
|
||||||
import kotlinx.coroutines.flow.Flow
|
import kotlinx.coroutines.flow.Flow
|
||||||
|
import kotlinx.coroutines.flow.SharingStarted
|
||||||
import kotlinx.coroutines.flow.flowOf
|
import kotlinx.coroutines.flow.flowOf
|
||||||
|
import kotlinx.coroutines.flow.shareIn
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Provides data related to the wifi state.
|
* Provides data related to the wifi state.
|
||||||
@@ -63,10 +68,11 @@ interface WifiRepository {
|
|||||||
@SysUISingleton
|
@SysUISingleton
|
||||||
@SuppressLint("MissingPermission")
|
@SuppressLint("MissingPermission")
|
||||||
class WifiRepositoryImpl @Inject constructor(
|
class WifiRepositoryImpl @Inject constructor(
|
||||||
connectivityManager: ConnectivityManager,
|
connectivityManager: ConnectivityManager,
|
||||||
wifiManager: WifiManager?,
|
logger: ConnectivityPipelineLogger,
|
||||||
@Main mainExecutor: Executor,
|
@Main mainExecutor: Executor,
|
||||||
logger: ConnectivityPipelineLogger,
|
@Application scope: CoroutineScope,
|
||||||
|
wifiManager: WifiManager?,
|
||||||
) : WifiRepository {
|
) : WifiRepository {
|
||||||
override val wifiNetwork: Flow<WifiNetworkModel> = conflatedCallbackFlow {
|
override val wifiNetwork: Flow<WifiNetworkModel> = conflatedCallbackFlow {
|
||||||
var currentWifi: WifiNetworkModel = WIFI_NETWORK_DEFAULT
|
var currentWifi: WifiNetworkModel = WIFI_NETWORK_DEFAULT
|
||||||
@@ -80,7 +86,12 @@ class WifiRepositoryImpl @Inject constructor(
|
|||||||
|
|
||||||
val wifiInfo = networkCapabilitiesToWifiInfo(networkCapabilities)
|
val wifiInfo = networkCapabilitiesToWifiInfo(networkCapabilities)
|
||||||
if (wifiInfo?.isPrimary == true) {
|
if (wifiInfo?.isPrimary == true) {
|
||||||
val wifiNetworkModel = wifiInfoToModel(wifiInfo, network.getNetId())
|
val wifiNetworkModel = createWifiNetworkModel(
|
||||||
|
wifiInfo,
|
||||||
|
network,
|
||||||
|
networkCapabilities,
|
||||||
|
wifiManager,
|
||||||
|
)
|
||||||
logger.logTransformation(
|
logger.logTransformation(
|
||||||
WIFI_NETWORK_CALLBACK_NAME,
|
WIFI_NETWORK_CALLBACK_NAME,
|
||||||
oldValue = currentWifi,
|
oldValue = currentWifi,
|
||||||
@@ -112,6 +123,7 @@ class WifiRepositoryImpl @Inject constructor(
|
|||||||
|
|
||||||
awaitClose { connectivityManager.unregisterNetworkCallback(callback) }
|
awaitClose { connectivityManager.unregisterNetworkCallback(callback) }
|
||||||
}
|
}
|
||||||
|
.shareIn(scope, started = SharingStarted.WhileSubscribed())
|
||||||
|
|
||||||
override val wifiActivity: Flow<WifiActivityModel> =
|
override val wifiActivity: Flow<WifiActivityModel> =
|
||||||
if (wifiManager == null) {
|
if (wifiManager == null) {
|
||||||
@@ -164,14 +176,25 @@ class WifiRepositoryImpl @Inject constructor(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun wifiInfoToModel(wifiInfo: WifiInfo, networkId: Int): WifiNetworkModel {
|
private fun createWifiNetworkModel(
|
||||||
return WifiNetworkModel.Active(
|
wifiInfo: WifiInfo,
|
||||||
networkId,
|
network: Network,
|
||||||
wifiInfo.ssid,
|
networkCapabilities: NetworkCapabilities,
|
||||||
wifiInfo.isPasspointAp,
|
wifiManager: WifiManager?,
|
||||||
wifiInfo.isOsuAp,
|
): WifiNetworkModel {
|
||||||
wifiInfo.passpointProviderFriendlyName
|
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
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun prettyPrintActivity(activity: Int): String {
|
private fun prettyPrintActivity(activity: Int): String {
|
||||||
|
|||||||
@@ -33,11 +33,12 @@ import kotlinx.coroutines.flow.map
|
|||||||
*/
|
*/
|
||||||
@SysUISingleton
|
@SysUISingleton
|
||||||
class WifiInteractor @Inject constructor(
|
class WifiInteractor @Inject constructor(
|
||||||
repository: WifiRepository,
|
repository: WifiRepository,
|
||||||
) {
|
) {
|
||||||
private val ssid: Flow<String?> = repository.wifiNetwork.map { info ->
|
private val ssid: Flow<String?> = repository.wifiNetwork.map { info ->
|
||||||
when (info) {
|
when (info) {
|
||||||
is WifiNetworkModel.Inactive -> null
|
is WifiNetworkModel.Inactive -> null
|
||||||
|
is WifiNetworkModel.CarrierMerged -> null
|
||||||
is WifiNetworkModel.Active -> when {
|
is WifiNetworkModel.Active -> when {
|
||||||
info.isPasspointAccessPoint || info.isOnlineSignUpForPasspointAccessPoint ->
|
info.isPasspointAccessPoint || info.isOnlineSignUpForPasspointAccessPoint ->
|
||||||
info.passpointProviderFriendlyName
|
info.passpointProviderFriendlyName
|
||||||
@@ -47,6 +48,10 @@ class WifiInteractor @Inject constructor(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Our current wifi network. See [WifiNetworkModel]. */
|
||||||
|
val wifiNetwork: Flow<WifiNetworkModel> = repository.wifiNetwork
|
||||||
|
|
||||||
|
/** True if our wifi network has activity in (download), and false otherwise. */
|
||||||
val hasActivityIn: Flow<Boolean> = combine(repository.wifiActivity, ssid) { activity, ssid ->
|
val hasActivityIn: Flow<Boolean> = combine(repository.wifiActivity, ssid) { activity, ssid ->
|
||||||
activity.hasActivityIn && ssid != null
|
activity.hasActivityIn && ssid != null
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,10 +25,10 @@ import androidx.lifecycle.Lifecycle
|
|||||||
import androidx.lifecycle.repeatOnLifecycle
|
import androidx.lifecycle.repeatOnLifecycle
|
||||||
import com.android.systemui.R
|
import com.android.systemui.R
|
||||||
import com.android.systemui.lifecycle.repeatWhenAttached
|
import com.android.systemui.lifecycle.repeatWhenAttached
|
||||||
import com.android.systemui.statusbar.connectivity.WifiIcons.WIFI_FULL_ICONS
|
|
||||||
import com.android.systemui.statusbar.pipeline.wifi.ui.viewmodel.WifiViewModel
|
import com.android.systemui.statusbar.pipeline.wifi.ui.viewmodel.WifiViewModel
|
||||||
import kotlinx.coroutines.InternalCoroutinesApi
|
import kotlinx.coroutines.InternalCoroutinesApi
|
||||||
import kotlinx.coroutines.flow.collect
|
import kotlinx.coroutines.flow.collect
|
||||||
|
import kotlinx.coroutines.flow.distinctUntilChanged
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -50,10 +50,21 @@ object WifiViewBinder {
|
|||||||
|
|
||||||
view.isVisible = true
|
view.isVisible = true
|
||||||
iconView.isVisible = true
|
iconView.isVisible = true
|
||||||
iconView.setImageDrawable(view.context.getDrawable(WIFI_FULL_ICONS[2]))
|
|
||||||
|
|
||||||
view.repeatWhenAttached {
|
view.repeatWhenAttached {
|
||||||
repeatOnLifecycle(Lifecycle.State.STARTED) {
|
repeatOnLifecycle(Lifecycle.State.STARTED) {
|
||||||
|
launch {
|
||||||
|
viewModel.wifiIconResId.distinctUntilChanged().collect { iconResId ->
|
||||||
|
iconView.setImageDrawable(
|
||||||
|
if (iconResId != null && iconResId > 0) {
|
||||||
|
iconView.context.getDrawable(iconResId)
|
||||||
|
} else {
|
||||||
|
null
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
launch {
|
launch {
|
||||||
viewModel.tint.collect { tint ->
|
viewModel.tint.collect { tint ->
|
||||||
iconView.imageTintList = ColorStateList.valueOf(tint)
|
iconView.imageTintList = ColorStateList.valueOf(tint)
|
||||||
|
|||||||
@@ -17,20 +17,24 @@
|
|||||||
package com.android.systemui.statusbar.pipeline.wifi.ui.viewmodel
|
package com.android.systemui.statusbar.pipeline.wifi.ui.viewmodel
|
||||||
|
|
||||||
import android.graphics.Color
|
import android.graphics.Color
|
||||||
|
import androidx.annotation.DrawableRes
|
||||||
|
import com.android.systemui.statusbar.connectivity.WifiIcons.WIFI_FULL_ICONS
|
||||||
|
import com.android.systemui.statusbar.connectivity.WifiIcons.WIFI_NO_INTERNET_ICONS
|
||||||
|
import com.android.systemui.statusbar.connectivity.WifiIcons.WIFI_NO_NETWORK
|
||||||
import com.android.systemui.statusbar.pipeline.StatusBarPipelineFlags
|
import com.android.systemui.statusbar.pipeline.StatusBarPipelineFlags
|
||||||
import com.android.systemui.statusbar.pipeline.shared.ConnectivityPipelineLogger
|
import com.android.systemui.statusbar.pipeline.shared.ConnectivityPipelineLogger
|
||||||
import com.android.systemui.statusbar.pipeline.shared.ConnectivityPipelineLogger.Companion.logOutputChange
|
import com.android.systemui.statusbar.pipeline.shared.ConnectivityPipelineLogger.Companion.logOutputChange
|
||||||
|
import com.android.systemui.statusbar.pipeline.wifi.data.model.WifiNetworkModel
|
||||||
import com.android.systemui.statusbar.pipeline.wifi.domain.interactor.WifiInteractor
|
import com.android.systemui.statusbar.pipeline.wifi.domain.interactor.WifiInteractor
|
||||||
import com.android.systemui.statusbar.pipeline.wifi.shared.WifiConstants
|
import com.android.systemui.statusbar.pipeline.wifi.shared.WifiConstants
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
import kotlinx.coroutines.flow.Flow
|
import kotlinx.coroutines.flow.Flow
|
||||||
import kotlinx.coroutines.flow.emptyFlow
|
import kotlinx.coroutines.flow.emptyFlow
|
||||||
import kotlinx.coroutines.flow.flowOf
|
import kotlinx.coroutines.flow.flowOf
|
||||||
|
import kotlinx.coroutines.flow.map
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Models the UI state for the status bar wifi icon.
|
* Models the UI state for the status bar wifi icon.
|
||||||
*
|
|
||||||
* TODO(b/238425913): Hook this up to the real status bar wifi view using a view binder.
|
|
||||||
*/
|
*/
|
||||||
class WifiViewModel @Inject constructor(
|
class WifiViewModel @Inject constructor(
|
||||||
statusBarPipelineFlags: StatusBarPipelineFlags,
|
statusBarPipelineFlags: StatusBarPipelineFlags,
|
||||||
@@ -38,6 +42,23 @@ class WifiViewModel @Inject constructor(
|
|||||||
private val logger: ConnectivityPipelineLogger,
|
private val logger: ConnectivityPipelineLogger,
|
||||||
private val interactor: WifiInteractor,
|
private val interactor: WifiInteractor,
|
||||||
) {
|
) {
|
||||||
|
/**
|
||||||
|
* The drawable resource ID to use for the wifi icon. Null if we shouldn't display any icon.
|
||||||
|
*/
|
||||||
|
@DrawableRes
|
||||||
|
val wifiIconResId: Flow<Int?> = interactor.wifiNetwork.map {
|
||||||
|
when (it) {
|
||||||
|
is WifiNetworkModel.CarrierMerged -> null
|
||||||
|
is WifiNetworkModel.Inactive -> WIFI_NO_NETWORK
|
||||||
|
is WifiNetworkModel.Active ->
|
||||||
|
when {
|
||||||
|
it.level == null -> null
|
||||||
|
it.isValidated -> WIFI_FULL_ICONS[it.level]
|
||||||
|
else -> WIFI_NO_INTERNET_ICONS[it.level]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
val isActivityInVisible: Flow<Boolean>
|
val isActivityInVisible: Flow<Boolean>
|
||||||
get() =
|
get() =
|
||||||
if (!constants.shouldShowActivityConfig) {
|
if (!constants.shouldShowActivityConfig) {
|
||||||
|
|||||||
@@ -0,0 +1,54 @@
|
|||||||
|
/*
|
||||||
|
* 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
|
||||||
|
|
||||||
|
import androidx.test.filters.SmallTest
|
||||||
|
import com.android.systemui.SysuiTestCase
|
||||||
|
import com.android.systemui.statusbar.pipeline.wifi.data.model.WifiNetworkModel.Active.Companion.MAX_VALID_LEVEL
|
||||||
|
import com.android.systemui.statusbar.pipeline.wifi.data.model.WifiNetworkModel.Active.Companion.MIN_VALID_LEVEL
|
||||||
|
import org.junit.Test
|
||||||
|
|
||||||
|
@SmallTest
|
||||||
|
class WifiNetworkModelTest : SysuiTestCase() {
|
||||||
|
@Test
|
||||||
|
fun active_levelsInValidRange_noException() {
|
||||||
|
(MIN_VALID_LEVEL..MAX_VALID_LEVEL).forEach { level ->
|
||||||
|
WifiNetworkModel.Active(NETWORK_ID, level = level)
|
||||||
|
// No assert, just need no crash
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@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)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test(expected = IllegalArgumentException::class)
|
||||||
|
fun active_levelTooHigh_exceptionThrown() {
|
||||||
|
WifiNetworkModel.Active(NETWORK_ID, level = MAX_VALID_LEVEL + 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private const val NETWORK_ID = 2
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -19,6 +19,7 @@ package com.android.systemui.statusbar.pipeline.wifi.data.repository
|
|||||||
import android.net.ConnectivityManager
|
import android.net.ConnectivityManager
|
||||||
import android.net.Network
|
import android.net.Network
|
||||||
import android.net.NetworkCapabilities
|
import android.net.NetworkCapabilities
|
||||||
|
import android.net.NetworkCapabilities.NET_CAPABILITY_VALIDATED
|
||||||
import android.net.NetworkCapabilities.TRANSPORT_CELLULAR
|
import android.net.NetworkCapabilities.TRANSPORT_CELLULAR
|
||||||
import android.net.NetworkCapabilities.TRANSPORT_WIFI
|
import android.net.NetworkCapabilities.TRANSPORT_WIFI
|
||||||
import android.net.vcn.VcnTransportInfo
|
import android.net.vcn.VcnTransportInfo
|
||||||
@@ -39,11 +40,14 @@ import com.android.systemui.util.mockito.mock
|
|||||||
import com.android.systemui.util.time.FakeSystemClock
|
import com.android.systemui.util.time.FakeSystemClock
|
||||||
import com.google.common.truth.Truth.assertThat
|
import com.google.common.truth.Truth.assertThat
|
||||||
import java.util.concurrent.Executor
|
import java.util.concurrent.Executor
|
||||||
|
import kotlinx.coroutines.CoroutineScope
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||||
|
import kotlinx.coroutines.cancel
|
||||||
import kotlinx.coroutines.flow.launchIn
|
import kotlinx.coroutines.flow.launchIn
|
||||||
import kotlinx.coroutines.flow.onEach
|
import kotlinx.coroutines.flow.onEach
|
||||||
import kotlinx.coroutines.runBlocking
|
import kotlinx.coroutines.runBlocking
|
||||||
|
import org.junit.After
|
||||||
import org.junit.Before
|
import org.junit.Before
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
import org.mockito.Mock
|
import org.mockito.Mock
|
||||||
@@ -61,20 +65,28 @@ class WifiRepositoryImplTest : SysuiTestCase() {
|
|||||||
@Mock private lateinit var connectivityManager: ConnectivityManager
|
@Mock private lateinit var connectivityManager: ConnectivityManager
|
||||||
@Mock private lateinit var wifiManager: WifiManager
|
@Mock private lateinit var wifiManager: WifiManager
|
||||||
private lateinit var executor: Executor
|
private lateinit var executor: Executor
|
||||||
|
private lateinit var scope: CoroutineScope
|
||||||
|
|
||||||
@Before
|
@Before
|
||||||
fun setUp() {
|
fun setUp() {
|
||||||
MockitoAnnotations.initMocks(this)
|
MockitoAnnotations.initMocks(this)
|
||||||
executor = FakeExecutor(FakeSystemClock())
|
executor = FakeExecutor(FakeSystemClock())
|
||||||
|
scope = CoroutineScope(IMMEDIATE)
|
||||||
|
|
||||||
underTest = WifiRepositoryImpl(
|
underTest = WifiRepositoryImpl(
|
||||||
connectivityManager,
|
connectivityManager,
|
||||||
wifiManager,
|
|
||||||
executor,
|
|
||||||
logger,
|
logger,
|
||||||
|
executor,
|
||||||
|
scope,
|
||||||
|
wifiManager,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@After
|
||||||
|
fun tearDown() {
|
||||||
|
scope.cancel()
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun wifiNetwork_initiallyGetsDefault() = runBlocking(IMMEDIATE) {
|
fun wifiNetwork_initiallyGetsDefault() = runBlocking(IMMEDIATE) {
|
||||||
var latest: WifiNetworkModel? = null
|
var latest: WifiNetworkModel? = null
|
||||||
@@ -114,6 +126,61 @@ class WifiRepositoryImplTest : SysuiTestCase() {
|
|||||||
job.cancel()
|
job.cancel()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun wifiNetwork_isCarrierMerged_flowHasCarrierMerged() = 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)
|
||||||
|
whenever(this.isCarrierMerged).thenReturn(true)
|
||||||
|
}
|
||||||
|
|
||||||
|
getNetworkCallback().onCapabilitiesChanged(NETWORK, createWifiNetworkCapabilities(wifiInfo))
|
||||||
|
|
||||||
|
assertThat(latest is WifiNetworkModel.CarrierMerged).isTrue()
|
||||||
|
|
||||||
|
job.cancel()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun wifiNetwork_notValidated_networkNotValidated() = runBlocking(IMMEDIATE) {
|
||||||
|
var latest: WifiNetworkModel? = null
|
||||||
|
val job = underTest
|
||||||
|
.wifiNetwork
|
||||||
|
.onEach { latest = it }
|
||||||
|
.launchIn(this)
|
||||||
|
|
||||||
|
getNetworkCallback().onCapabilitiesChanged(
|
||||||
|
NETWORK, createWifiNetworkCapabilities(PRIMARY_WIFI_INFO, isValidated = false)
|
||||||
|
)
|
||||||
|
|
||||||
|
assertThat((latest as WifiNetworkModel.Active).isValidated).isFalse()
|
||||||
|
|
||||||
|
job.cancel()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun wifiNetwork_validated_networkValidated() = runBlocking(IMMEDIATE) {
|
||||||
|
var latest: WifiNetworkModel? = null
|
||||||
|
val job = underTest
|
||||||
|
.wifiNetwork
|
||||||
|
.onEach { latest = it }
|
||||||
|
.launchIn(this)
|
||||||
|
|
||||||
|
getNetworkCallback().onCapabilitiesChanged(
|
||||||
|
NETWORK, createWifiNetworkCapabilities(PRIMARY_WIFI_INFO, isValidated = true)
|
||||||
|
)
|
||||||
|
|
||||||
|
assertThat((latest as WifiNetworkModel.Active).isValidated).isTrue()
|
||||||
|
|
||||||
|
job.cancel()
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun wifiNetwork_nonPrimaryWifiNetworkAdded_flowHasNoNetwork() = runBlocking(IMMEDIATE) {
|
fun wifiNetwork_nonPrimaryWifiNetworkAdded_flowHasNoNetwork() = runBlocking(IMMEDIATE) {
|
||||||
var latest: WifiNetworkModel? = null
|
var latest: WifiNetworkModel? = null
|
||||||
@@ -282,13 +349,14 @@ class WifiRepositoryImplTest : SysuiTestCase() {
|
|||||||
.launchIn(this)
|
.launchIn(this)
|
||||||
|
|
||||||
val wifiInfo = mock<WifiInfo>().apply {
|
val wifiInfo = mock<WifiInfo>().apply {
|
||||||
whenever(this.ssid).thenReturn(SSID)
|
whenever(this.ssid).thenReturn(SSID)
|
||||||
whenever(this.isPrimary).thenReturn(true)
|
whenever(this.isPrimary).thenReturn(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Start with the original network
|
// Start with the original network
|
||||||
getNetworkCallback()
|
getNetworkCallback().onCapabilitiesChanged(
|
||||||
.onCapabilitiesChanged(NETWORK, createWifiNetworkCapabilities(wifiInfo))
|
NETWORK, createWifiNetworkCapabilities(wifiInfo, isValidated = true)
|
||||||
|
)
|
||||||
|
|
||||||
// WHEN we keep the same network ID but change the SSID
|
// WHEN we keep the same network ID but change the SSID
|
||||||
val newSsid = "CD"
|
val newSsid = "CD"
|
||||||
@@ -297,14 +365,16 @@ class WifiRepositoryImplTest : SysuiTestCase() {
|
|||||||
whenever(this.isPrimary).thenReturn(true)
|
whenever(this.isPrimary).thenReturn(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
getNetworkCallback()
|
getNetworkCallback().onCapabilitiesChanged(
|
||||||
.onCapabilitiesChanged(NETWORK, createWifiNetworkCapabilities(newWifiInfo))
|
NETWORK, createWifiNetworkCapabilities(newWifiInfo, isValidated = false)
|
||||||
|
)
|
||||||
|
|
||||||
// THEN we've updated to the new SSID
|
// THEN we've updated to the new SSID
|
||||||
assertThat(latest is WifiNetworkModel.Active).isTrue()
|
assertThat(latest is WifiNetworkModel.Active).isTrue()
|
||||||
val latestActive = latest as WifiNetworkModel.Active
|
val latestActive = latest as WifiNetworkModel.Active
|
||||||
assertThat(latestActive.networkId).isEqualTo(NETWORK_ID)
|
assertThat(latestActive.networkId).isEqualTo(NETWORK_ID)
|
||||||
assertThat(latestActive.ssid).isEqualTo(newSsid)
|
assertThat(latestActive.ssid).isEqualTo(newSsid)
|
||||||
|
assertThat(latestActive.isValidated).isFalse()
|
||||||
|
|
||||||
job.cancel()
|
job.cancel()
|
||||||
}
|
}
|
||||||
@@ -406,10 +476,11 @@ class WifiRepositoryImplTest : SysuiTestCase() {
|
|||||||
@Test
|
@Test
|
||||||
fun wifiActivity_nullWifiManager_receivesDefault() = runBlocking(IMMEDIATE) {
|
fun wifiActivity_nullWifiManager_receivesDefault() = runBlocking(IMMEDIATE) {
|
||||||
underTest = WifiRepositoryImpl(
|
underTest = WifiRepositoryImpl(
|
||||||
connectivityManager,
|
connectivityManager,
|
||||||
wifiManager = null,
|
logger,
|
||||||
executor,
|
executor,
|
||||||
logger,
|
scope,
|
||||||
|
wifiManager = null,
|
||||||
)
|
)
|
||||||
|
|
||||||
var latest: WifiActivityModel? = null
|
var latest: WifiActivityModel? = null
|
||||||
@@ -501,11 +572,16 @@ class WifiRepositoryImplTest : SysuiTestCase() {
|
|||||||
return callbackCaptor.value!!
|
return callbackCaptor.value!!
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun createWifiNetworkCapabilities(wifiInfo: WifiInfo) =
|
private fun createWifiNetworkCapabilities(
|
||||||
mock<NetworkCapabilities>().apply {
|
wifiInfo: WifiInfo,
|
||||||
whenever(this.hasTransport(TRANSPORT_WIFI)).thenReturn(true)
|
isValidated: Boolean = true,
|
||||||
whenever(this.transportInfo).thenReturn(wifiInfo)
|
): NetworkCapabilities {
|
||||||
|
return mock<NetworkCapabilities>().also {
|
||||||
|
whenever(it.hasTransport(TRANSPORT_WIFI)).thenReturn(true)
|
||||||
|
whenever(it.transportInfo).thenReturn(wifiInfo)
|
||||||
|
whenever(it.hasCapability(NET_CAPABILITY_VALIDATED)).thenReturn(isValidated)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private companion object {
|
private companion object {
|
||||||
const val NETWORK_ID = 45
|
const val NETWORK_ID = 45
|
||||||
|
|||||||
@@ -125,6 +125,38 @@ class WifiInteractorTest : SysuiTestCase() {
|
|||||||
job.cancel()
|
job.cancel()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun hasActivityIn_inactiveNetwork_outputsFalse() = runBlocking(IMMEDIATE) {
|
||||||
|
repository.setWifiNetwork(WifiNetworkModel.Inactive)
|
||||||
|
repository.setWifiActivity(WifiActivityModel(hasActivityIn = true, hasActivityOut = true))
|
||||||
|
|
||||||
|
var latest: Boolean? = null
|
||||||
|
val job = underTest
|
||||||
|
.hasActivityIn
|
||||||
|
.onEach { latest = it }
|
||||||
|
.launchIn(this)
|
||||||
|
|
||||||
|
assertThat(latest).isFalse()
|
||||||
|
|
||||||
|
job.cancel()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun hasActivityIn_carrierMergedNetwork_outputsFalse() = runBlocking(IMMEDIATE) {
|
||||||
|
repository.setWifiNetwork(WifiNetworkModel.CarrierMerged)
|
||||||
|
repository.setWifiActivity(WifiActivityModel(hasActivityIn = true, hasActivityOut = true))
|
||||||
|
|
||||||
|
var latest: Boolean? = null
|
||||||
|
val job = underTest
|
||||||
|
.hasActivityIn
|
||||||
|
.onEach { latest = it }
|
||||||
|
.launchIn(this)
|
||||||
|
|
||||||
|
assertThat(latest).isFalse()
|
||||||
|
|
||||||
|
job.cancel()
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun hasActivityIn_multipleChanges_multipleOutputChanges() = runBlocking(IMMEDIATE) {
|
fun hasActivityIn_multipleChanges_multipleOutputChanges() = runBlocking(IMMEDIATE) {
|
||||||
repository.setWifiNetwork(VALID_WIFI_NETWORK_MODEL)
|
repository.setWifiNetwork(VALID_WIFI_NETWORK_MODEL)
|
||||||
@@ -159,6 +191,28 @@ class WifiInteractorTest : SysuiTestCase() {
|
|||||||
job.cancel()
|
job.cancel()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun wifiNetwork_matchesRepoWifiNetwork() = runBlocking(IMMEDIATE) {
|
||||||
|
val wifiNetwork = WifiNetworkModel.Active(
|
||||||
|
networkId = 45,
|
||||||
|
isValidated = true,
|
||||||
|
level = 3,
|
||||||
|
ssid = "AB",
|
||||||
|
passpointProviderFriendlyName = "friendly"
|
||||||
|
)
|
||||||
|
repository.setWifiNetwork(wifiNetwork)
|
||||||
|
|
||||||
|
var latest: WifiNetworkModel? = null
|
||||||
|
val job = underTest
|
||||||
|
.wifiNetwork
|
||||||
|
.onEach { latest = it }
|
||||||
|
.launchIn(this)
|
||||||
|
|
||||||
|
assertThat(latest).isEqualTo(wifiNetwork)
|
||||||
|
|
||||||
|
job.cancel()
|
||||||
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
val VALID_WIFI_NETWORK_MODEL = WifiNetworkModel.Active(networkId = 1, ssid = "AB")
|
val VALID_WIFI_NETWORK_MODEL = WifiNetworkModel.Active(networkId = 1, ssid = "AB")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,6 +18,9 @@ package com.android.systemui.statusbar.pipeline.wifi.ui.viewmodel
|
|||||||
|
|
||||||
import androidx.test.filters.SmallTest
|
import androidx.test.filters.SmallTest
|
||||||
import com.android.systemui.SysuiTestCase
|
import com.android.systemui.SysuiTestCase
|
||||||
|
import com.android.systemui.statusbar.connectivity.WifiIcons.WIFI_FULL_ICONS
|
||||||
|
import com.android.systemui.statusbar.connectivity.WifiIcons.WIFI_NO_INTERNET_ICONS
|
||||||
|
import com.android.systemui.statusbar.connectivity.WifiIcons.WIFI_NO_NETWORK
|
||||||
import com.android.systemui.statusbar.pipeline.StatusBarPipelineFlags
|
import com.android.systemui.statusbar.pipeline.StatusBarPipelineFlags
|
||||||
import com.android.systemui.statusbar.pipeline.shared.ConnectivityPipelineLogger
|
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.WifiActivityModel
|
||||||
@@ -62,14 +65,103 @@ class WifiViewModelTest : SysuiTestCase() {
|
|||||||
logger,
|
logger,
|
||||||
interactor
|
interactor
|
||||||
)
|
)
|
||||||
|
|
||||||
// Set up with a valid SSID
|
|
||||||
repository.setWifiNetwork(WifiNetworkModel.Active(networkId = 1, ssid = "AB"))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun activityInVisible_showActivityConfigFalse_receivesFalse() = runBlocking(IMMEDIATE) {
|
fun wifiIconResId_inactiveNetwork_outputsNoNetworkIcon() = runBlocking(IMMEDIATE) {
|
||||||
|
repository.setWifiNetwork(WifiNetworkModel.Inactive)
|
||||||
|
|
||||||
|
var latest: Int? = null
|
||||||
|
val job = underTest
|
||||||
|
.wifiIconResId
|
||||||
|
.onEach { latest = it }
|
||||||
|
.launchIn(this)
|
||||||
|
|
||||||
|
assertThat(latest).isEqualTo(WIFI_NO_NETWORK)
|
||||||
|
|
||||||
|
job.cancel()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun wifiIconResId_carrierMergedNetwork_outputsNull() = runBlocking(IMMEDIATE) {
|
||||||
|
repository.setWifiNetwork(WifiNetworkModel.CarrierMerged)
|
||||||
|
|
||||||
|
var latest: Int? = null
|
||||||
|
val job = underTest
|
||||||
|
.wifiIconResId
|
||||||
|
.onEach { latest = it }
|
||||||
|
.launchIn(this)
|
||||||
|
|
||||||
|
assertThat(latest).isNull()
|
||||||
|
|
||||||
|
job.cancel()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun wifiIconResId_isActiveNullLevel_outputsNull() = runBlocking(IMMEDIATE) {
|
||||||
|
repository.setWifiNetwork(WifiNetworkModel.Active(NETWORK_ID, level = null))
|
||||||
|
|
||||||
|
var latest: Int? = null
|
||||||
|
val job = underTest
|
||||||
|
.wifiIconResId
|
||||||
|
.onEach { latest = it }
|
||||||
|
.launchIn(this)
|
||||||
|
|
||||||
|
assertThat(latest).isNull()
|
||||||
|
|
||||||
|
job.cancel()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun wifiIconResId_isActiveAndValidated_level1_outputsFull1Icon() = runBlocking(IMMEDIATE) {
|
||||||
|
val level = 1
|
||||||
|
|
||||||
|
repository.setWifiNetwork(
|
||||||
|
WifiNetworkModel.Active(
|
||||||
|
NETWORK_ID,
|
||||||
|
isValidated = true,
|
||||||
|
level = level
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
var latest: Int? = null
|
||||||
|
val job = underTest
|
||||||
|
.wifiIconResId
|
||||||
|
.onEach { latest = it }
|
||||||
|
.launchIn(this)
|
||||||
|
|
||||||
|
assertThat(latest).isEqualTo(WIFI_FULL_ICONS[level])
|
||||||
|
|
||||||
|
job.cancel()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun wifiIconResId_isActiveAndNotValidated_level4_outputsEmpty4Icon() = runBlocking(IMMEDIATE) {
|
||||||
|
val level = 4
|
||||||
|
|
||||||
|
repository.setWifiNetwork(
|
||||||
|
WifiNetworkModel.Active(
|
||||||
|
NETWORK_ID,
|
||||||
|
isValidated = false,
|
||||||
|
level = level
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
var latest: Int? = null
|
||||||
|
val job = underTest
|
||||||
|
.wifiIconResId
|
||||||
|
.onEach { latest = it }
|
||||||
|
.launchIn(this)
|
||||||
|
|
||||||
|
assertThat(latest).isEqualTo(WIFI_NO_INTERNET_ICONS[level])
|
||||||
|
|
||||||
|
job.cancel()
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun activityInVisible_showActivityConfigFalse_outputsFalse() = runBlocking(IMMEDIATE) {
|
||||||
whenever(constants.shouldShowActivityConfig).thenReturn(false)
|
whenever(constants.shouldShowActivityConfig).thenReturn(false)
|
||||||
|
repository.setWifiNetwork(ACTIVE_VALID_WIFI_NETWORK)
|
||||||
|
|
||||||
var latest: Boolean? = null
|
var latest: Boolean? = null
|
||||||
val job = underTest
|
val job = underTest
|
||||||
@@ -86,6 +178,7 @@ class WifiViewModelTest : SysuiTestCase() {
|
|||||||
@Test
|
@Test
|
||||||
fun activityInVisible_showActivityConfigFalse_noUpdatesReceived() = runBlocking(IMMEDIATE) {
|
fun activityInVisible_showActivityConfigFalse_noUpdatesReceived() = runBlocking(IMMEDIATE) {
|
||||||
whenever(constants.shouldShowActivityConfig).thenReturn(false)
|
whenever(constants.shouldShowActivityConfig).thenReturn(false)
|
||||||
|
repository.setWifiNetwork(ACTIVE_VALID_WIFI_NETWORK)
|
||||||
|
|
||||||
var latest: Boolean? = null
|
var latest: Boolean? = null
|
||||||
val job = underTest
|
val job = underTest
|
||||||
@@ -104,8 +197,9 @@ class WifiViewModelTest : SysuiTestCase() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun activityInVisible_showActivityConfigTrue_receivesUpdate() = runBlocking(IMMEDIATE) {
|
fun activityInVisible_showActivityConfigTrue_outputsUpdate() = runBlocking(IMMEDIATE) {
|
||||||
whenever(constants.shouldShowActivityConfig).thenReturn(true)
|
whenever(constants.shouldShowActivityConfig).thenReturn(true)
|
||||||
|
repository.setWifiNetwork(ACTIVE_VALID_WIFI_NETWORK)
|
||||||
|
|
||||||
var latest: Boolean? = null
|
var latest: Boolean? = null
|
||||||
val job = underTest
|
val job = underTest
|
||||||
@@ -122,6 +216,11 @@ class WifiViewModelTest : SysuiTestCase() {
|
|||||||
|
|
||||||
job.cancel()
|
job.cancel()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private const val NETWORK_ID = 2
|
||||||
|
private val ACTIVE_VALID_WIFI_NETWORK = WifiNetworkModel.Active(NETWORK_ID, ssid = "AB")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private val IMMEDIATE = Dispatchers.Main.immediate
|
private val IMMEDIATE = Dispatchers.Main.immediate
|
||||||
|
|||||||
Reference in New Issue
Block a user