Merge changes Ib74835e7,Ic077c0b0,I4fb5b8b5 into udc-qpr-dev
* changes: [Status Bar] Implement WifiRepository interface using WifiTrackerLib. [Status Bar] Move WifiPickerTrackerFactory to top-level class. [Status Bar] Move WifiRepositoryImplTest to newer test APIs.
This commit is contained in:
committed by
Android (Google) Code Review
commit
0231ea8790
@@ -354,6 +354,10 @@ object Flags {
|
||||
// TODO(b/280426085): Tracking Bug
|
||||
@JvmField val NEW_BLUETOOTH_REPOSITORY = releasedFlag(612, "new_bluetooth_repository")
|
||||
|
||||
// TODO(b/292533677): Tracking Bug
|
||||
val WIFI_TRACKER_LIB_FOR_WIFI_ICON =
|
||||
unreleasedFlag(613, "wifi_tracker_lib_for_wifi_icon")
|
||||
|
||||
// 700 - dialer/calls
|
||||
// TODO(b/254512734): Tracking Bug
|
||||
val ONGOING_CALL_STATUS_BAR_CHIP = releasedFlag(700, "ongoing_call_status_bar_chip")
|
||||
|
||||
@@ -16,13 +16,7 @@
|
||||
|
||||
package com.android.systemui.statusbar.connectivity;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.net.ConnectivityManager;
|
||||
import android.net.wifi.WifiManager;
|
||||
import android.os.Handler;
|
||||
import android.os.SimpleClock;
|
||||
import android.os.SystemClock;
|
||||
import android.os.UserHandle;
|
||||
import android.os.UserManager;
|
||||
import android.provider.Settings;
|
||||
@@ -35,25 +29,18 @@ import androidx.lifecycle.Lifecycle;
|
||||
import androidx.lifecycle.LifecycleOwner;
|
||||
import androidx.lifecycle.LifecycleRegistry;
|
||||
|
||||
import com.android.systemui.dagger.SysUISingleton;
|
||||
import com.android.systemui.dagger.qualifiers.Background;
|
||||
import com.android.systemui.dagger.qualifiers.Main;
|
||||
import com.android.systemui.settings.UserTracker;
|
||||
import com.android.wifitrackerlib.MergedCarrierEntry;
|
||||
import com.android.wifitrackerlib.WifiEntry;
|
||||
import com.android.wifitrackerlib.WifiPickerTracker;
|
||||
|
||||
import java.io.PrintWriter;
|
||||
import java.time.Clock;
|
||||
import java.time.ZoneOffset;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.Executor;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
/** */
|
||||
public class AccessPointControllerImpl implements AccessPointController,
|
||||
WifiPickerTracker.WifiPickerTrackerCallback,
|
||||
@@ -272,77 +259,4 @@ public class AccessPointControllerImpl implements AccessPointController,
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Factory for creating {@link WifiPickerTracker}.
|
||||
*
|
||||
* Uses the same time intervals as the Settings page for Wifi.
|
||||
*/
|
||||
@SysUISingleton
|
||||
public static class WifiPickerTrackerFactory {
|
||||
|
||||
// Max age of tracked WifiEntries
|
||||
private static final long MAX_SCAN_AGE_MILLIS = 15_000;
|
||||
// Interval between initiating WifiPickerTracker scans
|
||||
private static final long SCAN_INTERVAL_MILLIS = 10_000;
|
||||
|
||||
private final Context mContext;
|
||||
private final @Nullable WifiManager mWifiManager;
|
||||
private final ConnectivityManager mConnectivityManager;
|
||||
private final Handler mMainHandler;
|
||||
private final Handler mWorkerHandler;
|
||||
private final Clock mClock = new SimpleClock(ZoneOffset.UTC) {
|
||||
@Override
|
||||
public long millis() {
|
||||
return SystemClock.elapsedRealtime();
|
||||
}
|
||||
};
|
||||
|
||||
@Inject
|
||||
public WifiPickerTrackerFactory(
|
||||
Context context,
|
||||
@Nullable WifiManager wifiManager,
|
||||
ConnectivityManager connectivityManager,
|
||||
@Main Handler mainHandler,
|
||||
@Background Handler workerHandler
|
||||
) {
|
||||
mContext = context;
|
||||
mWifiManager = wifiManager;
|
||||
mConnectivityManager = connectivityManager;
|
||||
mMainHandler = mainHandler;
|
||||
mWorkerHandler = workerHandler;
|
||||
}
|
||||
|
||||
private boolean isSupported() {
|
||||
return mWifiManager != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a {@link WifiPickerTracker}
|
||||
*
|
||||
* @param lifecycle
|
||||
* @param listener
|
||||
* @return a new {@link WifiPickerTracker} or {@code null} if {@link WifiManager} is null.
|
||||
*/
|
||||
public @Nullable WifiPickerTracker create(
|
||||
Lifecycle lifecycle,
|
||||
WifiPickerTracker.WifiPickerTrackerCallback listener
|
||||
) {
|
||||
if (mWifiManager == null) {
|
||||
return null;
|
||||
}
|
||||
return new WifiPickerTracker(
|
||||
lifecycle,
|
||||
mContext,
|
||||
mWifiManager,
|
||||
mConnectivityManager,
|
||||
mMainHandler,
|
||||
mWorkerHandler,
|
||||
mClock,
|
||||
MAX_SCAN_AGE_MILLIS,
|
||||
SCAN_INTERVAL_MILLIS,
|
||||
listener
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,92 @@
|
||||
/*
|
||||
* Copyright (C) 2023 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.connectivity
|
||||
|
||||
import android.content.Context
|
||||
import android.net.ConnectivityManager
|
||||
import android.net.wifi.WifiManager
|
||||
import android.os.Handler
|
||||
import android.os.SimpleClock
|
||||
import androidx.lifecycle.Lifecycle
|
||||
import com.android.systemui.dagger.SysUISingleton
|
||||
import com.android.systemui.dagger.qualifiers.Background
|
||||
import com.android.systemui.dagger.qualifiers.Main
|
||||
import com.android.systemui.util.time.SystemClock
|
||||
import com.android.wifitrackerlib.WifiPickerTracker
|
||||
import com.android.wifitrackerlib.WifiPickerTracker.WifiPickerTrackerCallback
|
||||
import java.time.Clock
|
||||
import java.time.ZoneOffset
|
||||
import javax.inject.Inject
|
||||
|
||||
/**
|
||||
* Factory for creating [WifiPickerTracker] for SysUI.
|
||||
*
|
||||
* Uses the same time intervals as the Settings page for Wifi.
|
||||
*/
|
||||
@SysUISingleton
|
||||
class WifiPickerTrackerFactory
|
||||
@Inject
|
||||
constructor(
|
||||
private val context: Context,
|
||||
private val wifiManager: WifiManager?,
|
||||
private val connectivityManager: ConnectivityManager,
|
||||
private val systemClock: SystemClock,
|
||||
@Main private val mainHandler: Handler,
|
||||
@Background private val workerHandler: Handler,
|
||||
) {
|
||||
private val clock: Clock =
|
||||
object : SimpleClock(ZoneOffset.UTC) {
|
||||
override fun millis(): Long {
|
||||
return systemClock.elapsedRealtime()
|
||||
}
|
||||
}
|
||||
val isSupported: Boolean
|
||||
get() = wifiManager != null
|
||||
|
||||
/**
|
||||
* Creates a [WifiPickerTracker] instance.
|
||||
*
|
||||
* @return a new [WifiPickerTracker] or null if [WifiManager] is null.
|
||||
*/
|
||||
fun create(
|
||||
lifecycle: Lifecycle,
|
||||
listener: WifiPickerTrackerCallback,
|
||||
): WifiPickerTracker? {
|
||||
return if (wifiManager == null) {
|
||||
null
|
||||
} else
|
||||
WifiPickerTracker(
|
||||
lifecycle,
|
||||
context,
|
||||
wifiManager,
|
||||
connectivityManager,
|
||||
mainHandler,
|
||||
workerHandler,
|
||||
clock,
|
||||
MAX_SCAN_AGE_MILLIS,
|
||||
SCAN_INTERVAL_MILLIS,
|
||||
listener,
|
||||
)
|
||||
}
|
||||
|
||||
companion object {
|
||||
/** Max age of tracked WifiEntries. */
|
||||
private const val MAX_SCAN_AGE_MILLIS: Long = 15000
|
||||
/** Interval between initiating WifiPickerTracker scans. */
|
||||
private const val SCAN_INTERVAL_MILLIS: Long = 10000
|
||||
}
|
||||
}
|
||||
@@ -19,6 +19,8 @@ package com.android.systemui.statusbar.pipeline.dagger
|
||||
import android.net.wifi.WifiManager
|
||||
import com.android.systemui.CoreStartable
|
||||
import com.android.systemui.dagger.SysUISingleton
|
||||
import com.android.systemui.flags.FeatureFlags
|
||||
import com.android.systemui.flags.Flags
|
||||
import com.android.systemui.log.LogBuffer
|
||||
import com.android.systemui.log.LogBufferFactory
|
||||
import com.android.systemui.log.table.TableLogBuffer
|
||||
@@ -48,9 +50,12 @@ import com.android.systemui.statusbar.pipeline.shared.ui.viewmodel.CollapsedStat
|
||||
import com.android.systemui.statusbar.pipeline.shared.ui.viewmodel.CollapsedStatusBarViewModelImpl
|
||||
import com.android.systemui.statusbar.pipeline.wifi.data.repository.RealWifiRepository
|
||||
import com.android.systemui.statusbar.pipeline.wifi.data.repository.WifiRepository
|
||||
import com.android.systemui.statusbar.pipeline.wifi.data.repository.WifiRepositoryDagger
|
||||
import com.android.systemui.statusbar.pipeline.wifi.data.repository.WifiRepositorySwitcher
|
||||
import com.android.systemui.statusbar.pipeline.wifi.data.repository.WifiRepositoryViaTrackerLibDagger
|
||||
import com.android.systemui.statusbar.pipeline.wifi.data.repository.prod.DisabledWifiRepository
|
||||
import com.android.systemui.statusbar.pipeline.wifi.data.repository.prod.WifiRepositoryImpl
|
||||
import com.android.systemui.statusbar.pipeline.wifi.data.repository.prod.WifiRepositoryViaTrackerLib
|
||||
import com.android.systemui.statusbar.pipeline.wifi.domain.interactor.WifiInteractor
|
||||
import com.android.systemui.statusbar.pipeline.wifi.domain.interactor.WifiInteractorImpl
|
||||
import dagger.Binds
|
||||
@@ -114,14 +119,19 @@ abstract class StatusBarPipelineModule {
|
||||
impl: CollapsedStatusBarViewBinderImpl
|
||||
): CollapsedStatusBarViewBinder
|
||||
|
||||
@Binds
|
||||
@IntoMap
|
||||
@ClassKey(WifiRepositoryDagger::class)
|
||||
abstract fun bindWifiRepositoryDagger(impl: WifiRepositoryDagger): CoreStartable
|
||||
|
||||
companion object {
|
||||
@Provides
|
||||
@SysUISingleton
|
||||
fun provideRealWifiRepository(
|
||||
fun provideWifiRepositoryDagger(
|
||||
wifiManager: WifiManager?,
|
||||
disabledWifiRepository: DisabledWifiRepository,
|
||||
wifiRepositoryImplFactory: WifiRepositoryImpl.Factory,
|
||||
): RealWifiRepository {
|
||||
): WifiRepositoryDagger {
|
||||
// If we have a null [WifiManager], then the wifi repository should be permanently
|
||||
// disabled.
|
||||
return if (wifiManager == null) {
|
||||
@@ -131,6 +141,36 @@ abstract class StatusBarPipelineModule {
|
||||
}
|
||||
}
|
||||
|
||||
@Provides
|
||||
@SysUISingleton
|
||||
fun provideWifiRepositoryViaTrackerLibDagger(
|
||||
wifiManager: WifiManager?,
|
||||
disabledWifiRepository: DisabledWifiRepository,
|
||||
wifiRepositoryFromTrackerLibFactory: WifiRepositoryViaTrackerLib.Factory,
|
||||
): WifiRepositoryViaTrackerLibDagger {
|
||||
// If we have a null [WifiManager], then the wifi repository should be permanently
|
||||
// disabled.
|
||||
return if (wifiManager == null) {
|
||||
disabledWifiRepository
|
||||
} else {
|
||||
wifiRepositoryFromTrackerLibFactory.create(wifiManager)
|
||||
}
|
||||
}
|
||||
|
||||
@Provides
|
||||
@SysUISingleton
|
||||
fun provideRealWifiRepository(
|
||||
wifiRepository: WifiRepositoryDagger,
|
||||
wifiRepositoryFromTrackerLib: WifiRepositoryViaTrackerLibDagger,
|
||||
flags: FeatureFlags,
|
||||
): RealWifiRepository {
|
||||
return if (flags.isEnabled(Flags.WIFI_TRACKER_LIB_FOR_WIFI_ICON)) {
|
||||
wifiRepositoryFromTrackerLib
|
||||
} else {
|
||||
wifiRepository
|
||||
}
|
||||
}
|
||||
|
||||
@Provides
|
||||
@SysUISingleton
|
||||
@Named(FIRST_MOBILE_SUB_SHOWING_NETWORK_TYPE_ICON)
|
||||
@@ -149,6 +189,14 @@ abstract class StatusBarPipelineModule {
|
||||
return factory.create("WifiInputLog", 50)
|
||||
}
|
||||
|
||||
@Provides
|
||||
@SysUISingleton
|
||||
@WifiTrackerLibInputLog
|
||||
fun provideWifiTrackerLibInputLogBuffer(factory: LogBufferFactory): LogBuffer {
|
||||
// WifiTrackerLib is pretty noisy, so give it more room than WifiInputLog.
|
||||
return factory.create("WifiTrackerLibInputLog", 200)
|
||||
}
|
||||
|
||||
@Provides
|
||||
@SysUISingleton
|
||||
@WifiTableLog
|
||||
@@ -156,6 +204,13 @@ abstract class StatusBarPipelineModule {
|
||||
return factory.create("WifiTableLog", 100)
|
||||
}
|
||||
|
||||
@Provides
|
||||
@SysUISingleton
|
||||
@WifiTrackerLibTableLog
|
||||
fun provideWifiTrackerLibTableLogBuffer(factory: TableLogBufferFactory): TableLogBuffer {
|
||||
return factory.create("WifiTrackerLibTableLog", 100)
|
||||
}
|
||||
|
||||
@Provides
|
||||
@SysUISingleton
|
||||
@AirplaneTableLog
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* Copyright (C) 2023 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.dagger
|
||||
|
||||
import javax.inject.Qualifier
|
||||
|
||||
/** Wifi logs for inputs into [WifiRepositoryViaTrackerLib]. */
|
||||
@Qualifier
|
||||
@MustBeDocumented
|
||||
@kotlin.annotation.Retention(AnnotationRetention.RUNTIME)
|
||||
annotation class WifiTrackerLibInputLog
|
||||
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* Copyright (C) 2023 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.dagger
|
||||
|
||||
import javax.inject.Qualifier
|
||||
|
||||
/** Wifi logs from [WifiRepositoryViaTrackerLib] in table format. */
|
||||
@Qualifier
|
||||
@MustBeDocumented
|
||||
@Retention(AnnotationRetention.RUNTIME)
|
||||
annotation class WifiTrackerLibTableLog
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package com.android.systemui.statusbar.pipeline.wifi.data.repository
|
||||
|
||||
import com.android.systemui.CoreStartable
|
||||
import com.android.systemui.statusbar.pipeline.shared.data.model.DataActivityModel
|
||||
import com.android.systemui.statusbar.pipeline.wifi.shared.model.WifiNetworkModel
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
@@ -42,6 +43,13 @@ interface WifiRepository {
|
||||
val currentNetwork = wifiNetwork.value
|
||||
return currentNetwork is WifiNetworkModel.Active && currentNetwork.hasValidSsid()
|
||||
}
|
||||
|
||||
companion object {
|
||||
/** Column name to use for [isWifiEnabled] for table logging. */
|
||||
const val COL_NAME_IS_ENABLED = "isEnabled"
|
||||
/** Column name to use for [isWifiDefault] for table logging. */
|
||||
const val COL_NAME_IS_DEFAULT = "isDefault"
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -53,3 +61,8 @@ interface WifiRepository {
|
||||
* repository.
|
||||
*/
|
||||
interface RealWifiRepository : WifiRepository
|
||||
|
||||
/** Used only by Dagger to bind [WifiRepositoryImpl]. */
|
||||
interface WifiRepositoryDagger : RealWifiRepository, CoreStartable
|
||||
/** Used only by Dagger to bind [WifiRepositoryViaTrackerLib]. */
|
||||
interface WifiRepositoryViaTrackerLibDagger : RealWifiRepository
|
||||
|
||||
@@ -18,7 +18,8 @@ package com.android.systemui.statusbar.pipeline.wifi.data.repository.prod
|
||||
|
||||
import com.android.systemui.dagger.SysUISingleton
|
||||
import com.android.systemui.statusbar.pipeline.shared.data.model.DataActivityModel
|
||||
import com.android.systemui.statusbar.pipeline.wifi.data.repository.RealWifiRepository
|
||||
import com.android.systemui.statusbar.pipeline.wifi.data.repository.WifiRepositoryDagger
|
||||
import com.android.systemui.statusbar.pipeline.wifi.data.repository.WifiRepositoryViaTrackerLibDagger
|
||||
import com.android.systemui.statusbar.pipeline.wifi.shared.model.WifiNetworkModel
|
||||
import javax.inject.Inject
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
@@ -32,7 +33,10 @@ import kotlinx.coroutines.flow.asStateFlow
|
||||
* wifi information.
|
||||
*/
|
||||
@SysUISingleton
|
||||
class DisabledWifiRepository @Inject constructor() : RealWifiRepository {
|
||||
class DisabledWifiRepository @Inject constructor() :
|
||||
WifiRepositoryDagger, WifiRepositoryViaTrackerLibDagger {
|
||||
override fun start() {}
|
||||
|
||||
override val isWifiEnabled: StateFlow<Boolean> = MutableStateFlow(false).asStateFlow()
|
||||
|
||||
override val isWifiDefault: StateFlow<Boolean> = MutableStateFlow(false).asStateFlow()
|
||||
|
||||
@@ -43,8 +43,10 @@ import com.android.systemui.statusbar.pipeline.shared.data.model.DataActivityMod
|
||||
import com.android.systemui.statusbar.pipeline.shared.data.model.toWifiDataActivityModel
|
||||
import com.android.systemui.statusbar.pipeline.shared.data.repository.ConnectivityRepository
|
||||
import com.android.systemui.statusbar.pipeline.shared.data.repository.ConnectivityRepositoryImpl.Companion.getMainOrUnderlyingWifiInfo
|
||||
import com.android.systemui.statusbar.pipeline.wifi.data.repository.RealWifiRepository
|
||||
import com.android.systemui.statusbar.pipeline.wifi.data.repository.WifiRepository
|
||||
import com.android.systemui.statusbar.pipeline.wifi.data.repository.WifiRepository.Companion.COL_NAME_IS_DEFAULT
|
||||
import com.android.systemui.statusbar.pipeline.wifi.data.repository.WifiRepository.Companion.COL_NAME_IS_ENABLED
|
||||
import com.android.systemui.statusbar.pipeline.wifi.data.repository.WifiRepositoryDagger
|
||||
import com.android.systemui.statusbar.pipeline.wifi.shared.WifiInputLogger
|
||||
import com.android.systemui.statusbar.pipeline.wifi.shared.model.WifiNetworkModel
|
||||
import java.util.concurrent.Executor
|
||||
@@ -64,6 +66,7 @@ import kotlinx.coroutines.flow.merge
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
import kotlinx.coroutines.flow.onStart
|
||||
import kotlinx.coroutines.flow.stateIn
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
|
||||
/** Real implementation of [WifiRepository]. */
|
||||
@@ -81,9 +84,21 @@ constructor(
|
||||
@WifiTableLog wifiTableLogBuffer: TableLogBuffer,
|
||||
@Main mainExecutor: Executor,
|
||||
@Background private val bgDispatcher: CoroutineDispatcher,
|
||||
@Application scope: CoroutineScope,
|
||||
@Application private val scope: CoroutineScope,
|
||||
private val wifiManager: WifiManager,
|
||||
) : RealWifiRepository {
|
||||
) : WifiRepositoryDagger {
|
||||
|
||||
override fun start() {
|
||||
// There are two possible [WifiRepository] implementations: This class (old) and
|
||||
// [WifiRepositoryFromTrackerLib] (new). While we migrate to the new class, we want this old
|
||||
// class to still be running in the background so that we can collect logs and compare
|
||||
// discrepancies. This #start method collects on the flows to ensure that the logs are
|
||||
// collected.
|
||||
scope.launch { isWifiEnabled.collect {} }
|
||||
scope.launch { isWifiDefault.collect {} }
|
||||
scope.launch { wifiNetwork.collect {} }
|
||||
scope.launch { wifiActivity.collect {} }
|
||||
}
|
||||
|
||||
private val wifiStateChangeEvents: Flow<Unit> =
|
||||
broadcastDispatcher
|
||||
@@ -104,7 +119,7 @@ constructor(
|
||||
.logDiffsForTable(
|
||||
wifiTableLogBuffer,
|
||||
columnPrefix = "",
|
||||
columnName = "isEnabled",
|
||||
columnName = COL_NAME_IS_ENABLED,
|
||||
initialValue = false,
|
||||
)
|
||||
.stateIn(
|
||||
@@ -125,7 +140,7 @@ constructor(
|
||||
.logDiffsForTable(
|
||||
wifiTableLogBuffer,
|
||||
columnPrefix = "",
|
||||
columnName = "isDefault",
|
||||
columnName = COL_NAME_IS_DEFAULT,
|
||||
initialValue = false,
|
||||
)
|
||||
.stateIn(scope, started = SharingStarted.WhileSubscribed(), initialValue = false)
|
||||
@@ -234,6 +249,8 @@ constructor(
|
||||
// NetworkCallback inside [wifiNetwork] for our wifi network information.
|
||||
val WIFI_NETWORK_DEFAULT = WifiNetworkModel.Inactive
|
||||
|
||||
const val WIFI_STATE_DEFAULT = WifiManager.WIFI_STATE_DISABLED
|
||||
|
||||
private fun createWifiNetworkModel(
|
||||
wifiInfo: WifiInfo,
|
||||
network: Network,
|
||||
|
||||
@@ -0,0 +1,295 @@
|
||||
/*
|
||||
* Copyright (C) 2023 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.systemui.statusbar.pipeline.wifi.data.repository.prod
|
||||
|
||||
import android.net.wifi.WifiManager
|
||||
import androidx.lifecycle.Lifecycle
|
||||
import androidx.lifecycle.LifecycleOwner
|
||||
import androidx.lifecycle.LifecycleRegistry
|
||||
import com.android.systemui.dagger.SysUISingleton
|
||||
import com.android.systemui.dagger.qualifiers.Application
|
||||
import com.android.systemui.dagger.qualifiers.Main
|
||||
import com.android.systemui.log.LogBuffer
|
||||
import com.android.systemui.log.core.LogLevel
|
||||
import com.android.systemui.log.table.TableLogBuffer
|
||||
import com.android.systemui.log.table.logDiffsForTable
|
||||
import com.android.systemui.statusbar.connectivity.WifiPickerTrackerFactory
|
||||
import com.android.systemui.statusbar.pipeline.dagger.WifiTrackerLibInputLog
|
||||
import com.android.systemui.statusbar.pipeline.dagger.WifiTrackerLibTableLog
|
||||
import com.android.systemui.statusbar.pipeline.shared.data.model.DataActivityModel
|
||||
import com.android.systemui.statusbar.pipeline.wifi.data.repository.WifiRepository.Companion.COL_NAME_IS_DEFAULT
|
||||
import com.android.systemui.statusbar.pipeline.wifi.data.repository.WifiRepository.Companion.COL_NAME_IS_ENABLED
|
||||
import com.android.systemui.statusbar.pipeline.wifi.data.repository.WifiRepositoryViaTrackerLibDagger
|
||||
import com.android.systemui.statusbar.pipeline.wifi.data.repository.prod.WifiRepositoryImpl.Companion.WIFI_NETWORK_DEFAULT
|
||||
import com.android.systemui.statusbar.pipeline.wifi.data.repository.prod.WifiRepositoryImpl.Companion.WIFI_STATE_DEFAULT
|
||||
import com.android.systemui.statusbar.pipeline.wifi.shared.model.WifiNetworkModel
|
||||
import com.android.wifitrackerlib.MergedCarrierEntry
|
||||
import com.android.wifitrackerlib.WifiEntry
|
||||
import com.android.wifitrackerlib.WifiPickerTracker
|
||||
import java.util.concurrent.Executor
|
||||
import javax.inject.Inject
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.channels.awaitClose
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.SharingStarted
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
import kotlinx.coroutines.flow.callbackFlow
|
||||
import kotlinx.coroutines.flow.distinctUntilChanged
|
||||
import kotlinx.coroutines.flow.map
|
||||
import kotlinx.coroutines.flow.stateIn
|
||||
|
||||
/**
|
||||
* An implementation of [WifiRepository] that uses [com.android.wifitrackerlib] as the source of
|
||||
* truth for wifi information.
|
||||
*
|
||||
* Serves as a possible replacement for [WifiRepositoryImpl]. See b/292534484.
|
||||
*/
|
||||
@SysUISingleton
|
||||
class WifiRepositoryViaTrackerLib
|
||||
@Inject
|
||||
constructor(
|
||||
@Application private val scope: CoroutineScope,
|
||||
@Main private val mainExecutor: Executor,
|
||||
private val wifiPickerTrackerFactory: WifiPickerTrackerFactory,
|
||||
private val wifiManager: WifiManager,
|
||||
@WifiTrackerLibInputLog private val inputLogger: LogBuffer,
|
||||
@WifiTrackerLibTableLog private val wifiTrackerLibTableLogBuffer: TableLogBuffer,
|
||||
) : WifiRepositoryViaTrackerLibDagger, LifecycleOwner {
|
||||
|
||||
override val lifecycle =
|
||||
LifecycleRegistry(this).also {
|
||||
mainExecutor.execute { it.currentState = Lifecycle.State.CREATED }
|
||||
}
|
||||
|
||||
private var wifiPickerTracker: WifiPickerTracker? = null
|
||||
|
||||
private val wifiPickerTrackerInfo: StateFlow<WifiPickerTrackerInfo> = run {
|
||||
var current =
|
||||
WifiPickerTrackerInfo(
|
||||
state = WIFI_STATE_DEFAULT,
|
||||
isDefault = false,
|
||||
network = WIFI_NETWORK_DEFAULT,
|
||||
)
|
||||
callbackFlow {
|
||||
val callback =
|
||||
object : WifiPickerTracker.WifiPickerTrackerCallback {
|
||||
override fun onWifiEntriesChanged() {
|
||||
val connectedEntry = wifiPickerTracker?.connectedWifiEntry
|
||||
logOnWifiEntriesChanged(connectedEntry)
|
||||
|
||||
// [WifiPickerTracker.connectedWifiEntry] will return the same instance
|
||||
// but with updated internals. For example, when its validation status
|
||||
// changes from false to true, the same instance is re-used but with the
|
||||
// validated field updated.
|
||||
//
|
||||
// Because it's the same instance, the flow won't re-emit the value
|
||||
// (even though the internals have changed). So, we need to transform it
|
||||
// into our internal model immediately. [toWifiNetworkModel] always
|
||||
// returns a new instance, so the flow is guaranteed to emit.
|
||||
send(
|
||||
newNetwork = connectedEntry?.toWifiNetworkModel()
|
||||
?: WIFI_NETWORK_DEFAULT,
|
||||
newIsDefault = connectedEntry?.isDefaultNetwork ?: false,
|
||||
)
|
||||
}
|
||||
|
||||
override fun onWifiStateChanged() {
|
||||
val state = wifiPickerTracker?.wifiState
|
||||
logOnWifiStateChanged(state)
|
||||
send(newState = state ?: WIFI_STATE_DEFAULT)
|
||||
}
|
||||
|
||||
override fun onNumSavedNetworksChanged() {}
|
||||
|
||||
override fun onNumSavedSubscriptionsChanged() {}
|
||||
|
||||
private fun send(
|
||||
newState: Int = current.state,
|
||||
newIsDefault: Boolean = current.isDefault,
|
||||
newNetwork: WifiNetworkModel = current.network,
|
||||
) {
|
||||
val new = WifiPickerTrackerInfo(newState, newIsDefault, newNetwork)
|
||||
current = new
|
||||
trySend(new)
|
||||
}
|
||||
}
|
||||
|
||||
// TODO(b/292591403): [WifiPickerTrackerFactory] currently scans to see all
|
||||
// available wifi networks every 10s. Because SysUI only needs to display the
|
||||
// **connected** network, we don't need scans to be running. We should disable these
|
||||
// scans (ideal) or at least run them very infrequently.
|
||||
wifiPickerTracker = wifiPickerTrackerFactory.create(lifecycle, callback)
|
||||
// The lifecycle must be STARTED in order for the callback to receive events.
|
||||
mainExecutor.execute { lifecycle.currentState = Lifecycle.State.STARTED }
|
||||
awaitClose {
|
||||
mainExecutor.execute { lifecycle.currentState = Lifecycle.State.CREATED }
|
||||
}
|
||||
}
|
||||
// TODO(b/292534484): Update to Eagerly once scans are disabled. (Here and other flows)
|
||||
.stateIn(scope, SharingStarted.WhileSubscribed(), current)
|
||||
}
|
||||
|
||||
override val isWifiEnabled: StateFlow<Boolean> =
|
||||
wifiPickerTrackerInfo
|
||||
.map { it.state == WifiManager.WIFI_STATE_ENABLED }
|
||||
.distinctUntilChanged()
|
||||
.logDiffsForTable(
|
||||
wifiTrackerLibTableLogBuffer,
|
||||
columnPrefix = "",
|
||||
columnName = COL_NAME_IS_ENABLED,
|
||||
initialValue = false,
|
||||
)
|
||||
.stateIn(scope, SharingStarted.WhileSubscribed(), false)
|
||||
|
||||
override val wifiNetwork: StateFlow<WifiNetworkModel> =
|
||||
wifiPickerTrackerInfo
|
||||
.map { it.network }
|
||||
.distinctUntilChanged()
|
||||
.logDiffsForTable(
|
||||
wifiTrackerLibTableLogBuffer,
|
||||
columnPrefix = "",
|
||||
initialValue = WIFI_NETWORK_DEFAULT,
|
||||
)
|
||||
.stateIn(scope, SharingStarted.WhileSubscribed(), WIFI_NETWORK_DEFAULT)
|
||||
|
||||
/** Converts WifiTrackerLib's [WifiEntry] into our internal model. */
|
||||
private fun WifiEntry.toWifiNetworkModel(): WifiNetworkModel {
|
||||
if (!this.isPrimaryNetwork) {
|
||||
return WIFI_NETWORK_DEFAULT
|
||||
}
|
||||
return if (this is MergedCarrierEntry) {
|
||||
WifiNetworkModel.CarrierMerged(
|
||||
networkId = NETWORK_ID,
|
||||
// TODO(b/292534484): Fetch the real subscription ID from [MergedCarrierEntry].
|
||||
subscriptionId = TEMP_SUB_ID,
|
||||
level = this.level,
|
||||
// WifiManager APIs to calculate the signal level start from 0, so
|
||||
// maxSignalLevel + 1 represents the total level buckets count.
|
||||
numberOfLevels = wifiManager.maxSignalLevel + 1,
|
||||
)
|
||||
} else {
|
||||
WifiNetworkModel.Active(
|
||||
networkId = NETWORK_ID,
|
||||
isValidated = this.hasInternetAccess(),
|
||||
level = this.level,
|
||||
ssid = this.ssid,
|
||||
// TODO(b/292534484): Fetch the real values from [WifiEntry] (#getTitle might be
|
||||
// appropriate).
|
||||
isPasspointAccessPoint = false,
|
||||
isOnlineSignUpForPasspointAccessPoint = false,
|
||||
passpointProviderFriendlyName = null,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
override val isWifiDefault: StateFlow<Boolean> =
|
||||
wifiPickerTrackerInfo
|
||||
.map { it.isDefault }
|
||||
.distinctUntilChanged()
|
||||
.logDiffsForTable(
|
||||
wifiTrackerLibTableLogBuffer,
|
||||
columnPrefix = "",
|
||||
columnName = COL_NAME_IS_DEFAULT,
|
||||
initialValue = false,
|
||||
)
|
||||
.stateIn(scope, SharingStarted.WhileSubscribed(), false)
|
||||
|
||||
// TODO(b/292534484): Re-use WifiRepositoryImpl code to implement wifi activity since
|
||||
// WifiTrackerLib doesn't expose activity details.
|
||||
override val wifiActivity: StateFlow<DataActivityModel> =
|
||||
MutableStateFlow(DataActivityModel(false, false))
|
||||
|
||||
private fun logOnWifiEntriesChanged(connectedEntry: WifiEntry?) {
|
||||
inputLogger.log(
|
||||
TAG,
|
||||
LogLevel.DEBUG,
|
||||
{ str1 = connectedEntry.toString() },
|
||||
{ "onWifiEntriesChanged. ConnectedEntry=$str1" },
|
||||
)
|
||||
}
|
||||
|
||||
private fun logOnWifiStateChanged(state: Int?) {
|
||||
inputLogger.log(
|
||||
TAG,
|
||||
LogLevel.DEBUG,
|
||||
{ int1 = state ?: -1 },
|
||||
{ "onWifiStateChanged. State=${if (int1 == -1) null else int1}" },
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Data class storing all the information fetched from [WifiPickerTracker].
|
||||
*
|
||||
* Used so that we only register a single callback on [WifiPickerTracker].
|
||||
*/
|
||||
data class WifiPickerTrackerInfo(
|
||||
/** The current wifi state. See [WifiManager.getWifiState]. */
|
||||
val state: Int,
|
||||
/** True if wifi is currently the default connection and false otherwise. */
|
||||
val isDefault: Boolean,
|
||||
/** The currently primary wifi network. */
|
||||
val network: WifiNetworkModel,
|
||||
)
|
||||
|
||||
@SysUISingleton
|
||||
class Factory
|
||||
@Inject
|
||||
constructor(
|
||||
@Application private val scope: CoroutineScope,
|
||||
@Main private val mainExecutor: Executor,
|
||||
private val wifiPickerTrackerFactory: WifiPickerTrackerFactory,
|
||||
@WifiTrackerLibInputLog private val inputLogger: LogBuffer,
|
||||
@WifiTrackerLibTableLog private val wifiTrackerLibTableLogBuffer: TableLogBuffer,
|
||||
) {
|
||||
fun create(wifiManager: WifiManager): WifiRepositoryViaTrackerLib {
|
||||
return WifiRepositoryViaTrackerLib(
|
||||
scope,
|
||||
mainExecutor,
|
||||
wifiPickerTrackerFactory,
|
||||
wifiManager,
|
||||
inputLogger,
|
||||
wifiTrackerLibTableLogBuffer,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val TAG = "WifiTrackerLibInputLog"
|
||||
|
||||
/**
|
||||
* [WifiNetworkModel.Active.networkId] is only used at the repository layer. It's used by
|
||||
* [WifiRepositoryImpl], which tracks the ID in order to correctly apply the framework
|
||||
* callbacks within the repository.
|
||||
*
|
||||
* Since this class does not need to manually apply framework callbacks and since the
|
||||
* network ID is not used beyond the repository, it's safe to use an invalid ID in this
|
||||
* repository.
|
||||
*
|
||||
* The [WifiNetworkModel.Active.networkId] field should be deleted once we've fully migrated
|
||||
* to [WifiRepositoryViaTrackerLib].
|
||||
*/
|
||||
private const val NETWORK_ID = -1
|
||||
|
||||
/**
|
||||
* A temporary subscription ID until WifiTrackerLib exposes a method to fetch the
|
||||
* subscription ID.
|
||||
*
|
||||
* Use -2 because [SubscriptionManager.INVALID_SUBSCRIPTION_ID] is -1.
|
||||
*/
|
||||
private const val TEMP_SUB_ID = -2
|
||||
}
|
||||
}
|
||||
@@ -29,6 +29,7 @@ import com.android.systemui.statusbar.connectivity.AccessPointController;
|
||||
import com.android.systemui.statusbar.connectivity.AccessPointControllerImpl;
|
||||
import com.android.systemui.statusbar.connectivity.NetworkController;
|
||||
import com.android.systemui.statusbar.connectivity.NetworkControllerImpl;
|
||||
import com.android.systemui.statusbar.connectivity.WifiPickerTrackerFactory;
|
||||
import com.android.systemui.statusbar.phone.ConfigurationControllerImpl;
|
||||
import com.android.systemui.statusbar.policy.BluetoothController;
|
||||
import com.android.systemui.statusbar.policy.BluetoothControllerImpl;
|
||||
@@ -165,7 +166,7 @@ public interface StatusBarPolicyModule {
|
||||
UserManager userManager,
|
||||
UserTracker userTracker,
|
||||
@Main Executor mainExecutor,
|
||||
AccessPointControllerImpl.WifiPickerTrackerFactory wifiPickerTrackerFactory
|
||||
WifiPickerTrackerFactory wifiPickerTrackerFactory
|
||||
) {
|
||||
AccessPointControllerImpl controller = new AccessPointControllerImpl(
|
||||
userManager,
|
||||
|
||||
@@ -23,6 +23,7 @@ import android.testing.TestableLooper.RunWithLooper
|
||||
import androidx.lifecycle.Lifecycle
|
||||
import com.android.systemui.SysuiTestCase
|
||||
import com.android.systemui.settings.UserTracker
|
||||
import com.android.systemui.util.mockito.any
|
||||
import com.android.systemui.util.mockito.capture
|
||||
import com.android.wifitrackerlib.WifiEntry
|
||||
import com.android.wifitrackerlib.WifiPickerTracker
|
||||
@@ -31,7 +32,6 @@ import org.junit.Before
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import org.mockito.ArgumentCaptor
|
||||
import org.mockito.ArgumentMatchers.any
|
||||
import org.mockito.ArgumentMatchers.anyList
|
||||
import org.mockito.Captor
|
||||
import org.mockito.Mock
|
||||
@@ -52,7 +52,7 @@ class AccessPointControllerImplTest : SysuiTestCase() {
|
||||
private lateinit var userTracker: UserTracker
|
||||
@Mock
|
||||
private lateinit var wifiPickerTrackerFactory:
|
||||
AccessPointControllerImpl.WifiPickerTrackerFactory
|
||||
WifiPickerTrackerFactory
|
||||
@Mock
|
||||
private lateinit var wifiPickerTracker: WifiPickerTracker
|
||||
@Mock
|
||||
|
||||
@@ -36,6 +36,7 @@ import androidx.test.ext.junit.runners.AndroidJUnit4
|
||||
import androidx.test.filters.SmallTest
|
||||
import com.android.systemui.RoboPilotTest
|
||||
import com.android.systemui.SysuiTestCase
|
||||
import com.android.systemui.coroutines.collectLastValue
|
||||
import com.android.systemui.log.table.TableLogBuffer
|
||||
import com.android.systemui.statusbar.pipeline.shared.data.model.ConnectivitySlots
|
||||
import com.android.systemui.statusbar.pipeline.shared.data.model.DataActivityModel
|
||||
@@ -48,23 +49,25 @@ 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.mockito.whenever
|
||||
import com.android.systemui.util.time.FakeSystemClock
|
||||
import com.google.common.truth.Truth.assertThat
|
||||
import java.util.concurrent.Executor
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
import kotlinx.coroutines.flow.launchIn
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
import kotlinx.coroutines.test.StandardTestDispatcher
|
||||
import kotlinx.coroutines.test.TestScope
|
||||
import kotlinx.coroutines.test.UnconfinedTestDispatcher
|
||||
import kotlinx.coroutines.test.runCurrent
|
||||
import kotlinx.coroutines.test.runTest
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import org.mockito.Mock
|
||||
import org.mockito.Mockito.verify
|
||||
import org.mockito.Mockito.`when` as whenever
|
||||
import org.mockito.MockitoAnnotations
|
||||
|
||||
/**
|
||||
* Note: Any new tests added here may also need to be added to [WifiRepositoryViaTrackerLibTest].
|
||||
*/
|
||||
@Suppress("EXPERIMENTAL_IS_NOT_ENABLED")
|
||||
@OptIn(ExperimentalCoroutinesApi::class)
|
||||
@SmallTest
|
||||
@@ -81,7 +84,7 @@ class WifiRepositoryImplTest : SysuiTestCase() {
|
||||
private lateinit var executor: Executor
|
||||
private lateinit var connectivityRepository: ConnectivityRepository
|
||||
|
||||
private val dispatcher = UnconfinedTestDispatcher()
|
||||
private val dispatcher = StandardTestDispatcher()
|
||||
private val testScope = TestScope(dispatcher)
|
||||
|
||||
@Before
|
||||
@@ -109,6 +112,7 @@ class WifiRepositoryImplTest : SysuiTestCase() {
|
||||
whenever(wifiManager.isWifiEnabled).thenReturn(true)
|
||||
|
||||
underTest = createRepo()
|
||||
testScope.runCurrent()
|
||||
|
||||
assertThat(underTest.isWifiEnabled.value).isTrue()
|
||||
}
|
||||
@@ -116,53 +120,43 @@ class WifiRepositoryImplTest : SysuiTestCase() {
|
||||
@Test
|
||||
fun isWifiEnabled_networkCapabilitiesChanged_valueUpdated() =
|
||||
testScope.runTest {
|
||||
// We need to call launch on the flows so that they start updating
|
||||
val networkJob = underTest.wifiNetwork.launchIn(this)
|
||||
val enabledJob = underTest.isWifiEnabled.launchIn(this)
|
||||
collectLastValue(underTest.wifiNetwork)
|
||||
val latest by collectLastValue(underTest.isWifiEnabled)
|
||||
|
||||
whenever(wifiManager.isWifiEnabled).thenReturn(true)
|
||||
getNetworkCallback()
|
||||
.onCapabilitiesChanged(NETWORK, createWifiNetworkCapabilities(PRIMARY_WIFI_INFO))
|
||||
|
||||
assertThat(underTest.isWifiEnabled.value).isTrue()
|
||||
assertThat(latest).isTrue()
|
||||
|
||||
whenever(wifiManager.isWifiEnabled).thenReturn(false)
|
||||
getNetworkCallback()
|
||||
.onCapabilitiesChanged(NETWORK, createWifiNetworkCapabilities(PRIMARY_WIFI_INFO))
|
||||
|
||||
assertThat(underTest.isWifiEnabled.value).isFalse()
|
||||
|
||||
networkJob.cancel()
|
||||
enabledJob.cancel()
|
||||
assertThat(latest).isFalse()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun isWifiEnabled_networkLost_valueUpdated() =
|
||||
testScope.runTest {
|
||||
// We need to call launch on the flows so that they start updating
|
||||
val networkJob = underTest.wifiNetwork.launchIn(this)
|
||||
val enabledJob = underTest.isWifiEnabled.launchIn(this)
|
||||
collectLastValue(underTest.wifiNetwork)
|
||||
val latest by collectLastValue(underTest.isWifiEnabled)
|
||||
|
||||
whenever(wifiManager.isWifiEnabled).thenReturn(true)
|
||||
getNetworkCallback().onLost(NETWORK)
|
||||
|
||||
assertThat(underTest.isWifiEnabled.value).isTrue()
|
||||
assertThat(latest).isTrue()
|
||||
|
||||
whenever(wifiManager.isWifiEnabled).thenReturn(false)
|
||||
getNetworkCallback().onLost(NETWORK)
|
||||
|
||||
assertThat(underTest.isWifiEnabled.value).isFalse()
|
||||
|
||||
networkJob.cancel()
|
||||
enabledJob.cancel()
|
||||
assertThat(latest).isFalse()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun isWifiEnabled_intentsReceived_valueUpdated() =
|
||||
testScope.runTest {
|
||||
underTest = createRepo()
|
||||
|
||||
val job = underTest.isWifiEnabled.launchIn(this)
|
||||
val latest by collectLastValue(underTest.isWifiEnabled)
|
||||
|
||||
whenever(wifiManager.isWifiEnabled).thenReturn(true)
|
||||
fakeBroadcastDispatcher.sendIntentToMatchingReceiversOnly(
|
||||
@@ -170,7 +164,7 @@ class WifiRepositoryImplTest : SysuiTestCase() {
|
||||
Intent(WifiManager.WIFI_STATE_CHANGED_ACTION),
|
||||
)
|
||||
|
||||
assertThat(underTest.isWifiEnabled.value).isTrue()
|
||||
assertThat(latest).isTrue()
|
||||
|
||||
whenever(wifiManager.isWifiEnabled).thenReturn(false)
|
||||
fakeBroadcastDispatcher.sendIntentToMatchingReceiversOnly(
|
||||
@@ -178,76 +172,61 @@ class WifiRepositoryImplTest : SysuiTestCase() {
|
||||
Intent(WifiManager.WIFI_STATE_CHANGED_ACTION),
|
||||
)
|
||||
|
||||
assertThat(underTest.isWifiEnabled.value).isFalse()
|
||||
|
||||
job.cancel()
|
||||
assertThat(latest).isFalse()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun isWifiEnabled_bothIntentAndNetworkUpdates_valueAlwaysUpdated() =
|
||||
testScope.runTest {
|
||||
underTest = createRepo()
|
||||
|
||||
val networkJob = underTest.wifiNetwork.launchIn(this)
|
||||
val enabledJob = underTest.isWifiEnabled.launchIn(this)
|
||||
collectLastValue(underTest.wifiNetwork)
|
||||
val latest by collectLastValue(underTest.isWifiEnabled)
|
||||
|
||||
whenever(wifiManager.isWifiEnabled).thenReturn(false)
|
||||
fakeBroadcastDispatcher.sendIntentToMatchingReceiversOnly(
|
||||
context,
|
||||
Intent(WifiManager.WIFI_STATE_CHANGED_ACTION),
|
||||
)
|
||||
assertThat(underTest.isWifiEnabled.value).isFalse()
|
||||
assertThat(latest).isFalse()
|
||||
|
||||
whenever(wifiManager.isWifiEnabled).thenReturn(true)
|
||||
getNetworkCallback().onLost(NETWORK)
|
||||
assertThat(underTest.isWifiEnabled.value).isTrue()
|
||||
assertThat(latest).isTrue()
|
||||
|
||||
whenever(wifiManager.isWifiEnabled).thenReturn(false)
|
||||
getNetworkCallback()
|
||||
.onCapabilitiesChanged(NETWORK, createWifiNetworkCapabilities(PRIMARY_WIFI_INFO))
|
||||
assertThat(underTest.isWifiEnabled.value).isFalse()
|
||||
assertThat(latest).isFalse()
|
||||
|
||||
whenever(wifiManager.isWifiEnabled).thenReturn(true)
|
||||
fakeBroadcastDispatcher.sendIntentToMatchingReceiversOnly(
|
||||
context,
|
||||
Intent(WifiManager.WIFI_STATE_CHANGED_ACTION),
|
||||
)
|
||||
assertThat(underTest.isWifiEnabled.value).isTrue()
|
||||
|
||||
networkJob.cancel()
|
||||
enabledJob.cancel()
|
||||
assertThat(latest).isTrue()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun isWifiDefault_initiallyGetsDefault() =
|
||||
testScope.runTest {
|
||||
val job = underTest.isWifiDefault.launchIn(this)
|
||||
|
||||
assertThat(underTest.isWifiDefault.value).isFalse()
|
||||
|
||||
job.cancel()
|
||||
}
|
||||
testScope.runTest { assertThat(underTest.isWifiDefault.value).isFalse() }
|
||||
|
||||
@Test
|
||||
fun isWifiDefault_wifiNetwork_isTrue() =
|
||||
testScope.runTest {
|
||||
val job = underTest.isWifiDefault.launchIn(this)
|
||||
val latest by collectLastValue(underTest.isWifiDefault)
|
||||
|
||||
val wifiInfo = mock<WifiInfo>().apply { whenever(this.ssid).thenReturn(SSID) }
|
||||
|
||||
getDefaultNetworkCallback()
|
||||
.onCapabilitiesChanged(NETWORK, createWifiNetworkCapabilities(wifiInfo))
|
||||
|
||||
assertThat(underTest.isWifiDefault.value).isTrue()
|
||||
|
||||
job.cancel()
|
||||
assertThat(latest).isTrue()
|
||||
}
|
||||
|
||||
/** Regression test for b/266628069. */
|
||||
@Test
|
||||
fun isWifiDefault_transportInfoIsNotWifi_andNoWifiTransport_false() =
|
||||
testScope.runTest {
|
||||
val job = underTest.isWifiDefault.launchIn(this)
|
||||
val latest by collectLastValue(underTest.isWifiDefault)
|
||||
|
||||
val transportInfo =
|
||||
VpnTransportInfo(
|
||||
@@ -264,16 +243,14 @@ class WifiRepositoryImplTest : SysuiTestCase() {
|
||||
|
||||
getDefaultNetworkCallback().onCapabilitiesChanged(NETWORK, networkCapabilities)
|
||||
|
||||
assertThat(underTest.isWifiDefault.value).isFalse()
|
||||
|
||||
job.cancel()
|
||||
assertThat(latest).isFalse()
|
||||
}
|
||||
|
||||
/** Regression test for b/266628069. */
|
||||
@Test
|
||||
fun isWifiDefault_transportInfoIsNotWifi_butHasWifiTransport_true() =
|
||||
testScope.runTest {
|
||||
val job = underTest.isWifiDefault.launchIn(this)
|
||||
val latest by collectLastValue(underTest.isWifiDefault)
|
||||
|
||||
val transportInfo =
|
||||
VpnTransportInfo(
|
||||
@@ -290,15 +267,13 @@ class WifiRepositoryImplTest : SysuiTestCase() {
|
||||
|
||||
getDefaultNetworkCallback().onCapabilitiesChanged(NETWORK, networkCapabilities)
|
||||
|
||||
assertThat(underTest.isWifiDefault.value).isTrue()
|
||||
|
||||
job.cancel()
|
||||
assertThat(latest).isTrue()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun isWifiDefault_carrierMergedViaCellular_isTrue() =
|
||||
testScope.runTest {
|
||||
val job = underTest.isWifiDefault.launchIn(this)
|
||||
val latest by collectLastValue(underTest.isWifiDefault)
|
||||
|
||||
val carrierMergedInfo =
|
||||
mock<WifiInfo>().apply { whenever(this.isCarrierMerged).thenReturn(true) }
|
||||
@@ -312,15 +287,13 @@ class WifiRepositoryImplTest : SysuiTestCase() {
|
||||
|
||||
getDefaultNetworkCallback().onCapabilitiesChanged(NETWORK, capabilities)
|
||||
|
||||
assertThat(underTest.isWifiDefault.value).isTrue()
|
||||
|
||||
job.cancel()
|
||||
assertThat(latest).isTrue()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun isWifiDefault_carrierMergedViaCellular_withVcnTransport_isTrue() =
|
||||
testScope.runTest {
|
||||
val job = underTest.isWifiDefault.launchIn(this)
|
||||
val latest by collectLastValue(underTest.isWifiDefault)
|
||||
|
||||
val capabilities =
|
||||
mock<NetworkCapabilities>().apply {
|
||||
@@ -331,15 +304,13 @@ class WifiRepositoryImplTest : SysuiTestCase() {
|
||||
|
||||
getDefaultNetworkCallback().onCapabilitiesChanged(NETWORK, capabilities)
|
||||
|
||||
assertThat(underTest.isWifiDefault.value).isTrue()
|
||||
|
||||
job.cancel()
|
||||
assertThat(latest).isTrue()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun isWifiDefault_carrierMergedViaWifi_isTrue() =
|
||||
testScope.runTest {
|
||||
val job = underTest.isWifiDefault.launchIn(this)
|
||||
val latest by collectLastValue(underTest.isWifiDefault)
|
||||
|
||||
val carrierMergedInfo =
|
||||
mock<WifiInfo>().apply { whenever(this.isCarrierMerged).thenReturn(true) }
|
||||
@@ -353,15 +324,13 @@ class WifiRepositoryImplTest : SysuiTestCase() {
|
||||
|
||||
getDefaultNetworkCallback().onCapabilitiesChanged(NETWORK, capabilities)
|
||||
|
||||
assertThat(underTest.isWifiDefault.value).isTrue()
|
||||
|
||||
job.cancel()
|
||||
assertThat(latest).isTrue()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun isWifiDefault_carrierMergedViaWifi_withVcnTransport_isTrue() =
|
||||
testScope.runTest {
|
||||
val job = underTest.isWifiDefault.launchIn(this)
|
||||
val latest by collectLastValue(underTest.isWifiDefault)
|
||||
|
||||
val capabilities =
|
||||
mock<NetworkCapabilities>().apply {
|
||||
@@ -372,15 +341,13 @@ class WifiRepositoryImplTest : SysuiTestCase() {
|
||||
|
||||
getDefaultNetworkCallback().onCapabilitiesChanged(NETWORK, capabilities)
|
||||
|
||||
assertThat(underTest.isWifiDefault.value).isTrue()
|
||||
|
||||
job.cancel()
|
||||
assertThat(latest).isTrue()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun isWifiDefault_cellularAndWifiTransports_usesCellular_isTrue() =
|
||||
testScope.runTest {
|
||||
val job = underTest.isWifiDefault.launchIn(this)
|
||||
val latest by collectLastValue(underTest.isWifiDefault)
|
||||
|
||||
val capabilities =
|
||||
mock<NetworkCapabilities>().apply {
|
||||
@@ -391,15 +358,13 @@ class WifiRepositoryImplTest : SysuiTestCase() {
|
||||
|
||||
getDefaultNetworkCallback().onCapabilitiesChanged(NETWORK, capabilities)
|
||||
|
||||
assertThat(underTest.isWifiDefault.value).isTrue()
|
||||
|
||||
job.cancel()
|
||||
assertThat(latest).isTrue()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun isWifiDefault_cellularNotVcnNetwork_isFalse() =
|
||||
testScope.runTest {
|
||||
val job = underTest.isWifiDefault.launchIn(this)
|
||||
val latest by collectLastValue(underTest.isWifiDefault)
|
||||
|
||||
val capabilities =
|
||||
mock<NetworkCapabilities>().apply {
|
||||
@@ -409,15 +374,13 @@ class WifiRepositoryImplTest : SysuiTestCase() {
|
||||
|
||||
getDefaultNetworkCallback().onCapabilitiesChanged(NETWORK, capabilities)
|
||||
|
||||
assertThat(underTest.isWifiDefault.value).isFalse()
|
||||
|
||||
job.cancel()
|
||||
assertThat(latest).isFalse()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun isWifiDefault_isCarrierMergedViaUnderlyingWifi_isTrue() =
|
||||
testScope.runTest {
|
||||
val job = underTest.isWifiDefault.launchIn(this)
|
||||
val latest by collectLastValue(underTest.isWifiDefault)
|
||||
|
||||
val underlyingNetwork = mock<Network>()
|
||||
val carrierMergedInfo =
|
||||
@@ -444,15 +407,13 @@ class WifiRepositoryImplTest : SysuiTestCase() {
|
||||
getDefaultNetworkCallback().onCapabilitiesChanged(NETWORK, mainCapabilities)
|
||||
|
||||
// THEN the wifi network is carrier merged, so wifi is default
|
||||
assertThat(underTest.isWifiDefault.value).isTrue()
|
||||
|
||||
job.cancel()
|
||||
assertThat(latest).isTrue()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun isWifiDefault_isCarrierMergedViaUnderlyingCellular_isTrue() =
|
||||
testScope.runTest {
|
||||
val job = underTest.isWifiDefault.launchIn(this)
|
||||
val latest by collectLastValue(underTest.isWifiDefault)
|
||||
|
||||
val underlyingCarrierMergedNetwork = mock<Network>()
|
||||
val carrierMergedInfo =
|
||||
@@ -478,46 +439,38 @@ class WifiRepositoryImplTest : SysuiTestCase() {
|
||||
getDefaultNetworkCallback().onCapabilitiesChanged(NETWORK, mainCapabilities)
|
||||
|
||||
// THEN the wifi network is carrier merged, so wifi is default
|
||||
assertThat(underTest.isWifiDefault.value).isTrue()
|
||||
|
||||
job.cancel()
|
||||
assertThat(latest).isTrue()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun isWifiDefault_wifiNetworkLost_isFalse() =
|
||||
testScope.runTest {
|
||||
val job = underTest.isWifiDefault.launchIn(this)
|
||||
val latest by collectLastValue(underTest.isWifiDefault)
|
||||
|
||||
// First, add a network
|
||||
getDefaultNetworkCallback()
|
||||
.onCapabilitiesChanged(NETWORK, createWifiNetworkCapabilities(PRIMARY_WIFI_INFO))
|
||||
assertThat(underTest.isWifiDefault.value).isTrue()
|
||||
assertThat(latest).isTrue()
|
||||
|
||||
// WHEN the network is lost
|
||||
getDefaultNetworkCallback().onLost(NETWORK)
|
||||
|
||||
// THEN we update to false
|
||||
assertThat(underTest.isWifiDefault.value).isFalse()
|
||||
|
||||
job.cancel()
|
||||
assertThat(latest).isFalse()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun wifiNetwork_initiallyGetsDefault() =
|
||||
testScope.runTest {
|
||||
var latest: WifiNetworkModel? = null
|
||||
val job = underTest.wifiNetwork.onEach { latest = it }.launchIn(this)
|
||||
val latest by collectLastValue(underTest.wifiNetwork)
|
||||
|
||||
assertThat(latest).isEqualTo(WIFI_NETWORK_DEFAULT)
|
||||
|
||||
job.cancel()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun wifiNetwork_primaryWifiNetworkAdded_flowHasNetwork() =
|
||||
testScope.runTest {
|
||||
var latest: WifiNetworkModel? = null
|
||||
val job = underTest.wifiNetwork.onEach { latest = it }.launchIn(this)
|
||||
val latest by collectLastValue(underTest.wifiNetwork)
|
||||
|
||||
val wifiInfo =
|
||||
mock<WifiInfo>().apply {
|
||||
@@ -533,15 +486,12 @@ class WifiRepositoryImplTest : SysuiTestCase() {
|
||||
val latestActive = latest as WifiNetworkModel.Active
|
||||
assertThat(latestActive.networkId).isEqualTo(NETWORK_ID)
|
||||
assertThat(latestActive.ssid).isEqualTo(SSID)
|
||||
|
||||
job.cancel()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun wifiNetwork_isCarrierMerged_flowHasCarrierMerged() =
|
||||
testScope.runTest {
|
||||
var latest: WifiNetworkModel? = null
|
||||
val job = underTest.wifiNetwork.onEach { latest = it }.launchIn(this)
|
||||
val latest by collectLastValue(underTest.wifiNetwork)
|
||||
|
||||
val wifiInfo =
|
||||
mock<WifiInfo>().apply {
|
||||
@@ -553,15 +503,12 @@ class WifiRepositoryImplTest : SysuiTestCase() {
|
||||
.onCapabilitiesChanged(NETWORK, createWifiNetworkCapabilities(wifiInfo))
|
||||
|
||||
assertThat(latest is WifiNetworkModel.CarrierMerged).isTrue()
|
||||
|
||||
job.cancel()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun wifiNetwork_isCarrierMergedViaUnderlyingWifi_flowHasCarrierMerged() =
|
||||
testScope.runTest {
|
||||
var latest: WifiNetworkModel? = null
|
||||
val job = underTest.wifiNetwork.onEach { latest = it }.launchIn(this)
|
||||
val latest by collectLastValue(underTest.wifiNetwork)
|
||||
|
||||
val underlyingNetwork = mock<Network>()
|
||||
val carrierMergedInfo =
|
||||
@@ -590,15 +537,12 @@ class WifiRepositoryImplTest : SysuiTestCase() {
|
||||
|
||||
// THEN the wifi network is carrier merged
|
||||
assertThat(latest is WifiNetworkModel.CarrierMerged).isTrue()
|
||||
|
||||
job.cancel()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun wifiNetwork_isCarrierMergedViaUnderlyingCellular_flowHasCarrierMerged() =
|
||||
testScope.runTest {
|
||||
var latest: WifiNetworkModel? = null
|
||||
val job = underTest.wifiNetwork.onEach { latest = it }.launchIn(this)
|
||||
val latest by collectLastValue(underTest.wifiNetwork)
|
||||
|
||||
val underlyingCarrierMergedNetwork = mock<Network>()
|
||||
val carrierMergedInfo =
|
||||
@@ -628,15 +572,12 @@ class WifiRepositoryImplTest : SysuiTestCase() {
|
||||
|
||||
// THEN the wifi network is carrier merged
|
||||
assertThat(latest is WifiNetworkModel.CarrierMerged).isTrue()
|
||||
|
||||
job.cancel()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun wifiNetwork_carrierMergedButInvalidSubId_flowHasInvalid() =
|
||||
testScope.runTest {
|
||||
var latest: WifiNetworkModel? = null
|
||||
val job = underTest.wifiNetwork.onEach { latest = it }.launchIn(this)
|
||||
val latest by collectLastValue(underTest.wifiNetwork)
|
||||
|
||||
val wifiInfo =
|
||||
mock<WifiInfo>().apply {
|
||||
@@ -652,15 +593,12 @@ class WifiRepositoryImplTest : SysuiTestCase() {
|
||||
)
|
||||
|
||||
assertThat(latest).isInstanceOf(WifiNetworkModel.Invalid::class.java)
|
||||
|
||||
job.cancel()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun wifiNetwork_isCarrierMerged_getsCorrectValues() =
|
||||
testScope.runTest {
|
||||
var latest: WifiNetworkModel? = null
|
||||
val job = underTest.wifiNetwork.onEach { latest = it }.launchIn(this)
|
||||
val latest by collectLastValue(underTest.wifiNetwork)
|
||||
|
||||
val rssi = -57
|
||||
val wifiInfo =
|
||||
@@ -687,15 +625,12 @@ class WifiRepositoryImplTest : SysuiTestCase() {
|
||||
assertThat(latestCarrierMerged.level).isEqualTo(2)
|
||||
// numberOfLevels = maxSignalLevel + 1
|
||||
assertThat(latestCarrierMerged.numberOfLevels).isEqualTo(6)
|
||||
|
||||
job.cancel()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun wifiNetwork_notValidated_networkNotValidated() =
|
||||
testScope.runTest {
|
||||
var latest: WifiNetworkModel? = null
|
||||
val job = underTest.wifiNetwork.onEach { latest = it }.launchIn(this)
|
||||
val latest by collectLastValue(underTest.wifiNetwork)
|
||||
|
||||
getNetworkCallback()
|
||||
.onCapabilitiesChanged(
|
||||
@@ -704,15 +639,12 @@ class WifiRepositoryImplTest : SysuiTestCase() {
|
||||
)
|
||||
|
||||
assertThat((latest as WifiNetworkModel.Active).isValidated).isFalse()
|
||||
|
||||
job.cancel()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun wifiNetwork_validated_networkValidated() =
|
||||
testScope.runTest {
|
||||
var latest: WifiNetworkModel? = null
|
||||
val job = underTest.wifiNetwork.onEach { latest = it }.launchIn(this)
|
||||
val latest by collectLastValue(underTest.wifiNetwork)
|
||||
|
||||
getNetworkCallback()
|
||||
.onCapabilitiesChanged(
|
||||
@@ -721,15 +653,12 @@ class WifiRepositoryImplTest : SysuiTestCase() {
|
||||
)
|
||||
|
||||
assertThat((latest as WifiNetworkModel.Active).isValidated).isTrue()
|
||||
|
||||
job.cancel()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun wifiNetwork_nonPrimaryWifiNetworkAdded_flowHasNoNetwork() =
|
||||
testScope.runTest {
|
||||
var latest: WifiNetworkModel? = null
|
||||
val job = underTest.wifiNetwork.onEach { latest = it }.launchIn(this)
|
||||
val latest by collectLastValue(underTest.wifiNetwork)
|
||||
|
||||
val wifiInfo =
|
||||
mock<WifiInfo>().apply {
|
||||
@@ -741,16 +670,13 @@ class WifiRepositoryImplTest : SysuiTestCase() {
|
||||
.onCapabilitiesChanged(NETWORK, createWifiNetworkCapabilities(wifiInfo))
|
||||
|
||||
assertThat(latest is WifiNetworkModel.Inactive).isTrue()
|
||||
|
||||
job.cancel()
|
||||
}
|
||||
|
||||
/** Regression test for b/266628069. */
|
||||
@Test
|
||||
fun wifiNetwork_transportInfoIsNotWifi_flowHasNoNetwork() =
|
||||
testScope.runTest {
|
||||
var latest: WifiNetworkModel? = null
|
||||
val job = underTest.wifiNetwork.onEach { latest = it }.launchIn(this)
|
||||
val latest by collectLastValue(underTest.wifiNetwork)
|
||||
|
||||
val transportInfo =
|
||||
VpnTransportInfo(
|
||||
@@ -761,15 +687,12 @@ class WifiRepositoryImplTest : SysuiTestCase() {
|
||||
.onCapabilitiesChanged(NETWORK, createWifiNetworkCapabilities(transportInfo))
|
||||
|
||||
assertThat(latest is WifiNetworkModel.Inactive).isTrue()
|
||||
|
||||
job.cancel()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun wifiNetwork_cellularVcnNetworkAdded_flowHasNetwork() =
|
||||
testScope.runTest {
|
||||
var latest: WifiNetworkModel? = null
|
||||
val job = underTest.wifiNetwork.onEach { latest = it }.launchIn(this)
|
||||
val latest by collectLastValue(underTest.wifiNetwork)
|
||||
|
||||
val capabilities =
|
||||
mock<NetworkCapabilities>().apply {
|
||||
@@ -783,15 +706,12 @@ class WifiRepositoryImplTest : SysuiTestCase() {
|
||||
val latestActive = latest as WifiNetworkModel.Active
|
||||
assertThat(latestActive.networkId).isEqualTo(NETWORK_ID)
|
||||
assertThat(latestActive.ssid).isEqualTo(SSID)
|
||||
|
||||
job.cancel()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun wifiNetwork_nonPrimaryCellularVcnNetworkAdded_flowHasNoNetwork() =
|
||||
testScope.runTest {
|
||||
var latest: WifiNetworkModel? = null
|
||||
val job = underTest.wifiNetwork.onEach { latest = it }.launchIn(this)
|
||||
val latest by collectLastValue(underTest.wifiNetwork)
|
||||
|
||||
val wifiInfo =
|
||||
mock<WifiInfo>().apply {
|
||||
@@ -807,15 +727,12 @@ class WifiRepositoryImplTest : SysuiTestCase() {
|
||||
getNetworkCallback().onCapabilitiesChanged(NETWORK, capabilities)
|
||||
|
||||
assertThat(latest is WifiNetworkModel.Inactive).isTrue()
|
||||
|
||||
job.cancel()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun wifiNetwork_cellularNotVcnNetworkAdded_flowHasNoNetwork() =
|
||||
testScope.runTest {
|
||||
var latest: WifiNetworkModel? = null
|
||||
val job = underTest.wifiNetwork.onEach { latest = it }.launchIn(this)
|
||||
val latest by collectLastValue(underTest.wifiNetwork)
|
||||
|
||||
val capabilities =
|
||||
mock<NetworkCapabilities>().apply {
|
||||
@@ -826,15 +743,12 @@ class WifiRepositoryImplTest : SysuiTestCase() {
|
||||
getNetworkCallback().onCapabilitiesChanged(NETWORK, capabilities)
|
||||
|
||||
assertThat(latest is WifiNetworkModel.Inactive).isTrue()
|
||||
|
||||
job.cancel()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun wifiNetwork_cellularAndWifiTransports_usesCellular() =
|
||||
testScope.runTest {
|
||||
var latest: WifiNetworkModel? = null
|
||||
val job = underTest.wifiNetwork.onEach { latest = it }.launchIn(this)
|
||||
val latest by collectLastValue(underTest.wifiNetwork)
|
||||
|
||||
val capabilities =
|
||||
mock<NetworkCapabilities>().apply {
|
||||
@@ -849,15 +763,12 @@ class WifiRepositoryImplTest : SysuiTestCase() {
|
||||
val latestActive = latest as WifiNetworkModel.Active
|
||||
assertThat(latestActive.networkId).isEqualTo(NETWORK_ID)
|
||||
assertThat(latestActive.ssid).isEqualTo(SSID)
|
||||
|
||||
job.cancel()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun wifiNetwork_newPrimaryWifiNetwork_flowHasNewNetwork() =
|
||||
testScope.runTest {
|
||||
var latest: WifiNetworkModel? = null
|
||||
val job = underTest.wifiNetwork.onEach { latest = it }.launchIn(this)
|
||||
val latest by collectLastValue(underTest.wifiNetwork)
|
||||
|
||||
// Start with the original network
|
||||
getNetworkCallback()
|
||||
@@ -882,15 +793,12 @@ class WifiRepositoryImplTest : SysuiTestCase() {
|
||||
val latestActive = latest as WifiNetworkModel.Active
|
||||
assertThat(latestActive.networkId).isEqualTo(newNetworkId)
|
||||
assertThat(latestActive.ssid).isEqualTo(newSsid)
|
||||
|
||||
job.cancel()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun wifiNetwork_newNonPrimaryWifiNetwork_flowHasOldNetwork() =
|
||||
testScope.runTest {
|
||||
var latest: WifiNetworkModel? = null
|
||||
val job = underTest.wifiNetwork.onEach { latest = it }.launchIn(this)
|
||||
val latest by collectLastValue(underTest.wifiNetwork)
|
||||
|
||||
// Start with the original network
|
||||
getNetworkCallback()
|
||||
@@ -915,15 +823,12 @@ class WifiRepositoryImplTest : SysuiTestCase() {
|
||||
val latestActive = latest as WifiNetworkModel.Active
|
||||
assertThat(latestActive.networkId).isEqualTo(NETWORK_ID)
|
||||
assertThat(latestActive.ssid).isEqualTo(SSID)
|
||||
|
||||
job.cancel()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun wifiNetwork_newNetworkCapabilities_flowHasNewData() =
|
||||
testScope.runTest {
|
||||
var latest: WifiNetworkModel? = null
|
||||
val job = underTest.wifiNetwork.onEach { latest = it }.launchIn(this)
|
||||
val latest by collectLastValue(underTest.wifiNetwork)
|
||||
|
||||
val wifiInfo =
|
||||
mock<WifiInfo>().apply {
|
||||
@@ -958,30 +863,24 @@ class WifiRepositoryImplTest : SysuiTestCase() {
|
||||
assertThat(latestActive.networkId).isEqualTo(NETWORK_ID)
|
||||
assertThat(latestActive.ssid).isEqualTo(newSsid)
|
||||
assertThat(latestActive.isValidated).isFalse()
|
||||
|
||||
job.cancel()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun wifiNetwork_noCurrentNetwork_networkLost_flowHasNoNetwork() =
|
||||
testScope.runTest {
|
||||
var latest: WifiNetworkModel? = null
|
||||
val job = underTest.wifiNetwork.onEach { latest = it }.launchIn(this)
|
||||
val latest by collectLastValue(underTest.wifiNetwork)
|
||||
|
||||
// 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_currentActiveNetworkLost_flowHasNoNetwork() =
|
||||
testScope.runTest {
|
||||
var latest: WifiNetworkModel? = null
|
||||
val job = underTest.wifiNetwork.onEach { latest = it }.launchIn(this)
|
||||
val latest by collectLastValue(underTest.wifiNetwork)
|
||||
|
||||
getNetworkCallback()
|
||||
.onCapabilitiesChanged(NETWORK, createWifiNetworkCapabilities(PRIMARY_WIFI_INFO))
|
||||
@@ -992,16 +891,13 @@ class WifiRepositoryImplTest : SysuiTestCase() {
|
||||
|
||||
// THEN we update to no network
|
||||
assertThat(latest is WifiNetworkModel.Inactive).isTrue()
|
||||
|
||||
job.cancel()
|
||||
}
|
||||
|
||||
/** Possible regression test for b/278618530. */
|
||||
@Test
|
||||
fun wifiNetwork_currentCarrierMergedNetworkLost_flowHasNoNetwork() =
|
||||
testScope.runTest {
|
||||
var latest: WifiNetworkModel? = null
|
||||
val job = underTest.wifiNetwork.onEach { latest = it }.launchIn(this)
|
||||
val latest by collectLastValue(underTest.wifiNetwork)
|
||||
|
||||
val wifiInfo =
|
||||
mock<WifiInfo>().apply {
|
||||
@@ -1019,15 +915,12 @@ class WifiRepositoryImplTest : SysuiTestCase() {
|
||||
|
||||
// THEN we update to no network
|
||||
assertThat(latest is WifiNetworkModel.Inactive).isTrue()
|
||||
|
||||
job.cancel()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun wifiNetwork_unknownNetworkLost_flowHasPreviousNetwork() =
|
||||
testScope.runTest {
|
||||
var latest: WifiNetworkModel? = null
|
||||
val job = underTest.wifiNetwork.onEach { latest = it }.launchIn(this)
|
||||
val latest by collectLastValue(underTest.wifiNetwork)
|
||||
|
||||
getNetworkCallback()
|
||||
.onCapabilitiesChanged(NETWORK, createWifiNetworkCapabilities(PRIMARY_WIFI_INFO))
|
||||
@@ -1042,15 +935,12 @@ class WifiRepositoryImplTest : SysuiTestCase() {
|
||||
val latestActive = latest as WifiNetworkModel.Active
|
||||
assertThat(latestActive.networkId).isEqualTo(NETWORK_ID)
|
||||
assertThat(latestActive.ssid).isEqualTo(SSID)
|
||||
|
||||
job.cancel()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun wifiNetwork_notCurrentNetworkLost_flowHasCurrentNetwork() =
|
||||
testScope.runTest {
|
||||
var latest: WifiNetworkModel? = null
|
||||
val job = underTest.wifiNetwork.onEach { latest = it }.launchIn(this)
|
||||
val latest by collectLastValue(underTest.wifiNetwork)
|
||||
|
||||
getNetworkCallback()
|
||||
.onCapabilitiesChanged(NETWORK, createWifiNetworkCapabilities(PRIMARY_WIFI_INFO))
|
||||
@@ -1067,16 +957,13 @@ class WifiRepositoryImplTest : SysuiTestCase() {
|
||||
|
||||
// THEN we still have the new network
|
||||
assertThat((latest as WifiNetworkModel.Active).networkId).isEqualTo(newNetworkId)
|
||||
|
||||
job.cancel()
|
||||
}
|
||||
|
||||
/** Regression test for b/244173280. */
|
||||
@Test
|
||||
fun wifiNetwork_multipleSubscribers_newSubscribersGetCurrentValue() =
|
||||
testScope.runTest {
|
||||
var latest1: WifiNetworkModel? = null
|
||||
val job1 = underTest.wifiNetwork.onEach { latest1 = it }.launchIn(this)
|
||||
val latest1 by collectLastValue(underTest.wifiNetwork)
|
||||
|
||||
getNetworkCallback()
|
||||
.onCapabilitiesChanged(NETWORK, createWifiNetworkCapabilities(PRIMARY_WIFI_INFO))
|
||||
@@ -1087,23 +974,19 @@ class WifiRepositoryImplTest : SysuiTestCase() {
|
||||
assertThat(latest1Active.ssid).isEqualTo(SSID)
|
||||
|
||||
// WHEN we add a second subscriber after having already emitted a value
|
||||
var latest2: WifiNetworkModel? = null
|
||||
val job2 = underTest.wifiNetwork.onEach { latest2 = it }.launchIn(this)
|
||||
val latest2 by collectLastValue(underTest.wifiNetwork)
|
||||
|
||||
// THEN the second subscribe receives the already-emitted value
|
||||
assertThat(latest2 is WifiNetworkModel.Active).isTrue()
|
||||
val latest2Active = latest2 as WifiNetworkModel.Active
|
||||
assertThat(latest2Active.networkId).isEqualTo(NETWORK_ID)
|
||||
assertThat(latest2Active.ssid).isEqualTo(SSID)
|
||||
|
||||
job1.cancel()
|
||||
job2.cancel()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun isWifiConnectedWithValidSsid_inactiveNetwork_false() =
|
||||
testScope.runTest {
|
||||
val job = underTest.wifiNetwork.launchIn(this)
|
||||
collectLastValue(underTest.wifiNetwork)
|
||||
|
||||
val wifiInfo =
|
||||
mock<WifiInfo>().apply {
|
||||
@@ -1116,14 +999,12 @@ class WifiRepositoryImplTest : SysuiTestCase() {
|
||||
.onCapabilitiesChanged(NETWORK, createWifiNetworkCapabilities(wifiInfo))
|
||||
|
||||
assertThat(underTest.isWifiConnectedWithValidSsid()).isFalse()
|
||||
|
||||
job.cancel()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun isWifiConnectedWithValidSsid_carrierMergedNetwork_false() =
|
||||
testScope.runTest {
|
||||
val job = underTest.wifiNetwork.launchIn(this)
|
||||
collectLastValue(underTest.wifiNetwork)
|
||||
|
||||
val wifiInfo =
|
||||
mock<WifiInfo>().apply {
|
||||
@@ -1133,16 +1014,15 @@ class WifiRepositoryImplTest : SysuiTestCase() {
|
||||
|
||||
getNetworkCallback()
|
||||
.onCapabilitiesChanged(NETWORK, createWifiNetworkCapabilities(wifiInfo))
|
||||
testScope.runCurrent()
|
||||
|
||||
assertThat(underTest.isWifiConnectedWithValidSsid()).isFalse()
|
||||
|
||||
job.cancel()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun isWifiConnectedWithValidSsid_invalidNetwork_false() =
|
||||
testScope.runTest {
|
||||
val job = underTest.wifiNetwork.launchIn(this)
|
||||
collectLastValue(underTest.wifiNetwork)
|
||||
|
||||
val wifiInfo =
|
||||
mock<WifiInfo>().apply {
|
||||
@@ -1156,16 +1036,15 @@ class WifiRepositoryImplTest : SysuiTestCase() {
|
||||
NETWORK,
|
||||
createWifiNetworkCapabilities(wifiInfo),
|
||||
)
|
||||
testScope.runCurrent()
|
||||
|
||||
assertThat(underTest.isWifiConnectedWithValidSsid()).isFalse()
|
||||
|
||||
job.cancel()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun isWifiConnectedWithValidSsid_activeNetwork_nullSsid_false() =
|
||||
testScope.runTest {
|
||||
val job = underTest.wifiNetwork.launchIn(this)
|
||||
collectLastValue(underTest.wifiNetwork)
|
||||
|
||||
val wifiInfo =
|
||||
mock<WifiInfo>().apply {
|
||||
@@ -1175,16 +1054,15 @@ class WifiRepositoryImplTest : SysuiTestCase() {
|
||||
|
||||
getNetworkCallback()
|
||||
.onCapabilitiesChanged(NETWORK, createWifiNetworkCapabilities(wifiInfo))
|
||||
testScope.runCurrent()
|
||||
|
||||
assertThat(underTest.isWifiConnectedWithValidSsid()).isFalse()
|
||||
|
||||
job.cancel()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun isWifiConnectedWithValidSsid_activeNetwork_unknownSsid_false() =
|
||||
testScope.runTest {
|
||||
val job = underTest.wifiNetwork.launchIn(this)
|
||||
collectLastValue(underTest.wifiNetwork)
|
||||
|
||||
val wifiInfo =
|
||||
mock<WifiInfo>().apply {
|
||||
@@ -1194,16 +1072,15 @@ class WifiRepositoryImplTest : SysuiTestCase() {
|
||||
|
||||
getNetworkCallback()
|
||||
.onCapabilitiesChanged(NETWORK, createWifiNetworkCapabilities(wifiInfo))
|
||||
testScope.runCurrent()
|
||||
|
||||
assertThat(underTest.isWifiConnectedWithValidSsid()).isFalse()
|
||||
|
||||
job.cancel()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun isWifiConnectedWithValidSsid_activeNetwork_validSsid_true() =
|
||||
testScope.runTest {
|
||||
val job = underTest.wifiNetwork.launchIn(this)
|
||||
collectLastValue(underTest.wifiNetwork)
|
||||
|
||||
val wifiInfo =
|
||||
mock<WifiInfo>().apply {
|
||||
@@ -1213,16 +1090,15 @@ class WifiRepositoryImplTest : SysuiTestCase() {
|
||||
|
||||
getNetworkCallback()
|
||||
.onCapabilitiesChanged(NETWORK, createWifiNetworkCapabilities(wifiInfo))
|
||||
testScope.runCurrent()
|
||||
|
||||
assertThat(underTest.isWifiConnectedWithValidSsid()).isTrue()
|
||||
|
||||
job.cancel()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun isWifiConnectedWithValidSsid_activeToInactive_trueToFalse() =
|
||||
testScope.runTest {
|
||||
val job = underTest.wifiNetwork.launchIn(this)
|
||||
collectLastValue(underTest.wifiNetwork)
|
||||
|
||||
// Start with active
|
||||
val wifiInfo =
|
||||
@@ -1232,71 +1108,60 @@ class WifiRepositoryImplTest : SysuiTestCase() {
|
||||
}
|
||||
getNetworkCallback()
|
||||
.onCapabilitiesChanged(NETWORK, createWifiNetworkCapabilities(wifiInfo))
|
||||
testScope.runCurrent()
|
||||
|
||||
assertThat(underTest.isWifiConnectedWithValidSsid()).isTrue()
|
||||
|
||||
// WHEN the network is lost
|
||||
getNetworkCallback().onLost(NETWORK)
|
||||
testScope.runCurrent()
|
||||
|
||||
// THEN the isWifiConnected updates
|
||||
assertThat(underTest.isWifiConnectedWithValidSsid()).isFalse()
|
||||
|
||||
job.cancel()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun wifiActivity_callbackGivesNone_activityFlowHasNone() =
|
||||
testScope.runTest {
|
||||
var latest: DataActivityModel? = null
|
||||
val job = underTest.wifiActivity.onEach { latest = it }.launchIn(this)
|
||||
val latest by collectLastValue(underTest.wifiActivity)
|
||||
|
||||
getTrafficStateCallback().onStateChanged(TrafficStateCallback.DATA_ACTIVITY_NONE)
|
||||
|
||||
assertThat(latest)
|
||||
.isEqualTo(DataActivityModel(hasActivityIn = false, hasActivityOut = false))
|
||||
|
||||
job.cancel()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun wifiActivity_callbackGivesIn_activityFlowHasIn() =
|
||||
testScope.runTest {
|
||||
var latest: DataActivityModel? = null
|
||||
val job = underTest.wifiActivity.onEach { latest = it }.launchIn(this)
|
||||
val latest by collectLastValue(underTest.wifiActivity)
|
||||
|
||||
getTrafficStateCallback().onStateChanged(TrafficStateCallback.DATA_ACTIVITY_IN)
|
||||
|
||||
assertThat(latest)
|
||||
.isEqualTo(DataActivityModel(hasActivityIn = true, hasActivityOut = false))
|
||||
|
||||
job.cancel()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun wifiActivity_callbackGivesOut_activityFlowHasOut() =
|
||||
testScope.runTest {
|
||||
var latest: DataActivityModel? = null
|
||||
val job = underTest.wifiActivity.onEach { latest = it }.launchIn(this)
|
||||
val latest by collectLastValue(underTest.wifiActivity)
|
||||
|
||||
getTrafficStateCallback().onStateChanged(TrafficStateCallback.DATA_ACTIVITY_OUT)
|
||||
|
||||
assertThat(latest)
|
||||
.isEqualTo(DataActivityModel(hasActivityIn = false, hasActivityOut = true))
|
||||
|
||||
job.cancel()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun wifiActivity_callbackGivesInout_activityFlowHasInAndOut() =
|
||||
testScope.runTest {
|
||||
var latest: DataActivityModel? = null
|
||||
val job = underTest.wifiActivity.onEach { latest = it }.launchIn(this)
|
||||
val latest by collectLastValue(underTest.wifiActivity)
|
||||
|
||||
getTrafficStateCallback().onStateChanged(TrafficStateCallback.DATA_ACTIVITY_INOUT)
|
||||
|
||||
assertThat(latest)
|
||||
.isEqualTo(DataActivityModel(hasActivityIn = true, hasActivityOut = true))
|
||||
|
||||
job.cancel()
|
||||
}
|
||||
|
||||
private fun createRepo(): WifiRepositoryImpl {
|
||||
@@ -1314,18 +1179,21 @@ class WifiRepositoryImplTest : SysuiTestCase() {
|
||||
}
|
||||
|
||||
private fun getTrafficStateCallback(): TrafficStateCallback {
|
||||
testScope.runCurrent()
|
||||
val callbackCaptor = argumentCaptor<TrafficStateCallback>()
|
||||
verify(wifiManager).registerTrafficStateCallback(any(), callbackCaptor.capture())
|
||||
return callbackCaptor.value!!
|
||||
}
|
||||
|
||||
private fun getNetworkCallback(): ConnectivityManager.NetworkCallback {
|
||||
testScope.runCurrent()
|
||||
val callbackCaptor = argumentCaptor<ConnectivityManager.NetworkCallback>()
|
||||
verify(connectivityManager).registerNetworkCallback(any(), callbackCaptor.capture())
|
||||
return callbackCaptor.value!!
|
||||
}
|
||||
|
||||
private fun getDefaultNetworkCallback(): ConnectivityManager.NetworkCallback {
|
||||
testScope.runCurrent()
|
||||
val callbackCaptor = argumentCaptor<ConnectivityManager.NetworkCallback>()
|
||||
verify(connectivityManager).registerDefaultNetworkCallback(callbackCaptor.capture())
|
||||
return callbackCaptor.value!!
|
||||
|
||||
@@ -0,0 +1,665 @@
|
||||
/*
|
||||
* Copyright (C) 2023 The Android Open Source Project
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package com.android.systemui.statusbar.pipeline.wifi.data.repository.prod
|
||||
|
||||
import android.net.wifi.WifiManager
|
||||
import android.net.wifi.WifiManager.UNKNOWN_SSID
|
||||
import android.testing.TestableLooper
|
||||
import androidx.test.filters.SmallTest
|
||||
import com.android.systemui.SysuiTestCase
|
||||
import com.android.systemui.coroutines.collectLastValue
|
||||
import com.android.systemui.log.LogBuffer
|
||||
import com.android.systemui.log.table.TableLogBuffer
|
||||
import com.android.systemui.statusbar.connectivity.WifiPickerTrackerFactory
|
||||
import com.android.systemui.statusbar.pipeline.wifi.data.repository.prod.WifiRepositoryImpl.Companion.WIFI_NETWORK_DEFAULT
|
||||
import com.android.systemui.statusbar.pipeline.wifi.shared.model.WifiNetworkModel
|
||||
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.capture
|
||||
import com.android.systemui.util.mockito.mock
|
||||
import com.android.systemui.util.mockito.whenever
|
||||
import com.android.systemui.util.time.FakeSystemClock
|
||||
import com.android.wifitrackerlib.MergedCarrierEntry
|
||||
import com.android.wifitrackerlib.WifiEntry
|
||||
import com.android.wifitrackerlib.WifiPickerTracker
|
||||
import com.google.common.truth.Truth.assertThat
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
import kotlinx.coroutines.test.StandardTestDispatcher
|
||||
import kotlinx.coroutines.test.TestScope
|
||||
import kotlinx.coroutines.test.runCurrent
|
||||
import kotlinx.coroutines.test.runTest
|
||||
import org.junit.Before
|
||||
import org.junit.Test
|
||||
|
||||
/**
|
||||
* Note: Most of these tests are duplicates of [WifiRepositoryImplTest] tests.
|
||||
*
|
||||
* Any new tests added here may also need to be added to [WifiRepositoryImplTest].
|
||||
*/
|
||||
@Suppress("EXPERIMENTAL_IS_NOT_ENABLED")
|
||||
@OptIn(ExperimentalCoroutinesApi::class)
|
||||
@SmallTest
|
||||
@TestableLooper.RunWithLooper(setAsMainLooper = true)
|
||||
class WifiRepositoryViaTrackerLibTest : SysuiTestCase() {
|
||||
|
||||
private lateinit var underTest: WifiRepositoryViaTrackerLib
|
||||
|
||||
private val executor = FakeExecutor(FakeSystemClock())
|
||||
private val logger = LogBuffer("name", maxSize = 100, logcatEchoTracker = mock())
|
||||
private val tableLogger = mock<TableLogBuffer>()
|
||||
private val wifiManager =
|
||||
mock<WifiManager>().apply { whenever(this.maxSignalLevel).thenReturn(10) }
|
||||
private val wifiPickerTrackerFactory = mock<WifiPickerTrackerFactory>()
|
||||
private val wifiPickerTracker = mock<WifiPickerTracker>()
|
||||
|
||||
private val callbackCaptor = argumentCaptor<WifiPickerTracker.WifiPickerTrackerCallback>()
|
||||
|
||||
private val dispatcher = StandardTestDispatcher()
|
||||
private val testScope = TestScope(dispatcher)
|
||||
|
||||
@Before
|
||||
fun setUp() {
|
||||
whenever(wifiPickerTrackerFactory.create(any(), capture(callbackCaptor)))
|
||||
.thenReturn(wifiPickerTracker)
|
||||
underTest = createRepo()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun isWifiEnabled_enabled_true() =
|
||||
testScope.runTest {
|
||||
val latest by collectLastValue(underTest.isWifiEnabled)
|
||||
|
||||
whenever(wifiPickerTracker.wifiState).thenReturn(WifiManager.WIFI_STATE_ENABLED)
|
||||
getCallback().onWifiStateChanged()
|
||||
|
||||
assertThat(latest).isTrue()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun isWifiEnabled_enabling_false() =
|
||||
testScope.runTest {
|
||||
val latest by collectLastValue(underTest.isWifiEnabled)
|
||||
|
||||
whenever(wifiPickerTracker.wifiState).thenReturn(WifiManager.WIFI_STATE_ENABLING)
|
||||
getCallback().onWifiStateChanged()
|
||||
|
||||
assertThat(latest).isFalse()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun isWifiEnabled_disabling_true() =
|
||||
testScope.runTest {
|
||||
val latest by collectLastValue(underTest.isWifiEnabled)
|
||||
|
||||
whenever(wifiPickerTracker.wifiState).thenReturn(WifiManager.WIFI_STATE_DISABLING)
|
||||
getCallback().onWifiStateChanged()
|
||||
|
||||
assertThat(latest).isFalse()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun isWifiEnabled_disabled_false() =
|
||||
testScope.runTest {
|
||||
val latest by collectLastValue(underTest.isWifiEnabled)
|
||||
|
||||
whenever(wifiPickerTracker.wifiState).thenReturn(WifiManager.WIFI_STATE_DISABLED)
|
||||
getCallback().onWifiStateChanged()
|
||||
|
||||
assertThat(latest).isFalse()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun isWifiEnabled_respondsToUpdates() =
|
||||
testScope.runTest {
|
||||
val latest by collectLastValue(underTest.isWifiEnabled)
|
||||
executor.runAllReady()
|
||||
|
||||
whenever(wifiPickerTracker.wifiState).thenReturn(WifiManager.WIFI_STATE_ENABLED)
|
||||
getCallback().onWifiStateChanged()
|
||||
|
||||
assertThat(latest).isTrue()
|
||||
|
||||
whenever(wifiPickerTracker.wifiState).thenReturn(WifiManager.WIFI_STATE_DISABLED)
|
||||
getCallback().onWifiStateChanged()
|
||||
|
||||
assertThat(latest).isFalse()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun isWifiDefault_initiallyGetsDefault() =
|
||||
testScope.runTest { assertThat(underTest.isWifiDefault.value).isFalse() }
|
||||
|
||||
@Test
|
||||
fun isWifiDefault_wifiNetwork_isTrue() =
|
||||
testScope.runTest {
|
||||
val latest by collectLastValue(underTest.isWifiDefault)
|
||||
|
||||
val wifiEntry =
|
||||
mock<WifiEntry>().apply { whenever(this.isDefaultNetwork).thenReturn(true) }
|
||||
whenever(wifiPickerTracker.connectedWifiEntry).thenReturn(wifiEntry)
|
||||
getCallback().onWifiEntriesChanged()
|
||||
|
||||
assertThat(latest).isTrue()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun isWifiDefault_carrierMerged_isTrue() =
|
||||
testScope.runTest {
|
||||
val latest by collectLastValue(underTest.isWifiDefault)
|
||||
|
||||
val wifiEntry =
|
||||
mock<MergedCarrierEntry>().apply {
|
||||
whenever(this.isDefaultNetwork).thenReturn(true)
|
||||
}
|
||||
whenever(wifiPickerTracker.connectedWifiEntry).thenReturn(wifiEntry)
|
||||
getCallback().onWifiEntriesChanged()
|
||||
|
||||
assertThat(latest).isTrue()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun isWifiDefault_wifiNetworkNotDefault_isFalse() =
|
||||
testScope.runTest {
|
||||
val latest by collectLastValue(underTest.isWifiDefault)
|
||||
|
||||
val wifiEntry =
|
||||
mock<WifiEntry>().apply { whenever(this.isDefaultNetwork).thenReturn(false) }
|
||||
whenever(wifiPickerTracker.connectedWifiEntry).thenReturn(wifiEntry)
|
||||
getCallback().onWifiEntriesChanged()
|
||||
|
||||
assertThat(latest).isFalse()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun isWifiDefault_carrierMergedNotDefault_isFalse() =
|
||||
testScope.runTest {
|
||||
val latest by collectLastValue(underTest.isWifiDefault)
|
||||
|
||||
val wifiEntry =
|
||||
mock<MergedCarrierEntry>().apply {
|
||||
whenever(this.isDefaultNetwork).thenReturn(false)
|
||||
}
|
||||
whenever(wifiPickerTracker.connectedWifiEntry).thenReturn(wifiEntry)
|
||||
getCallback().onWifiEntriesChanged()
|
||||
|
||||
assertThat(latest).isFalse()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun isWifiDefault_noWifiNetwork_isFalse() =
|
||||
testScope.runTest {
|
||||
val latest by collectLastValue(underTest.isWifiDefault)
|
||||
|
||||
// First, add a network
|
||||
val wifiEntry =
|
||||
mock<WifiEntry>().apply { whenever(this.isDefaultNetwork).thenReturn(true) }
|
||||
whenever(wifiPickerTracker.connectedWifiEntry).thenReturn(wifiEntry)
|
||||
getCallback().onWifiEntriesChanged()
|
||||
|
||||
assertThat(latest).isTrue()
|
||||
|
||||
// WHEN the network is lost
|
||||
whenever(wifiPickerTracker.connectedWifiEntry).thenReturn(null)
|
||||
getCallback().onWifiEntriesChanged()
|
||||
|
||||
// THEN we update to false
|
||||
assertThat(latest).isFalse()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun wifiNetwork_initiallyGetsDefault() =
|
||||
testScope.runTest {
|
||||
val latest by collectLastValue(underTest.wifiNetwork)
|
||||
|
||||
assertThat(latest).isEqualTo(WIFI_NETWORK_DEFAULT)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun wifiNetwork_primaryWifiNetworkAdded_flowHasNetwork() =
|
||||
testScope.runTest {
|
||||
val latest by collectLastValue(underTest.wifiNetwork)
|
||||
|
||||
val wifiEntry =
|
||||
mock<WifiEntry>().apply {
|
||||
whenever(this.isPrimaryNetwork).thenReturn(true)
|
||||
whenever(this.level).thenReturn(3)
|
||||
whenever(this.ssid).thenReturn(SSID)
|
||||
}
|
||||
whenever(wifiPickerTracker.connectedWifiEntry).thenReturn(wifiEntry)
|
||||
getCallback().onWifiEntriesChanged()
|
||||
|
||||
assertThat(latest is WifiNetworkModel.Active).isTrue()
|
||||
val latestActive = latest as WifiNetworkModel.Active
|
||||
assertThat(latestActive.level).isEqualTo(3)
|
||||
assertThat(latestActive.ssid).isEqualTo(SSID)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun wifiNetwork_isCarrierMerged_flowHasCarrierMerged() =
|
||||
testScope.runTest {
|
||||
val latest by collectLastValue(underTest.wifiNetwork)
|
||||
|
||||
val wifiEntry =
|
||||
mock<MergedCarrierEntry>().apply {
|
||||
whenever(this.isPrimaryNetwork).thenReturn(true)
|
||||
whenever(this.level).thenReturn(3)
|
||||
}
|
||||
whenever(wifiPickerTracker.connectedWifiEntry).thenReturn(wifiEntry)
|
||||
getCallback().onWifiEntriesChanged()
|
||||
|
||||
assertThat(latest is WifiNetworkModel.CarrierMerged).isTrue()
|
||||
val latestMerged = latest as WifiNetworkModel.CarrierMerged
|
||||
assertThat(latestMerged.level).isEqualTo(3)
|
||||
// numberOfLevels = maxSignalLevel + 1
|
||||
}
|
||||
|
||||
@Test
|
||||
fun wifiNetwork_isCarrierMerged_getsMaxSignalLevel() =
|
||||
testScope.runTest {
|
||||
val latest by collectLastValue(underTest.wifiNetwork)
|
||||
|
||||
val wifiEntry =
|
||||
mock<MergedCarrierEntry>().apply {
|
||||
whenever(this.isPrimaryNetwork).thenReturn(true)
|
||||
}
|
||||
whenever(wifiPickerTracker.connectedWifiEntry).thenReturn(wifiEntry)
|
||||
whenever(wifiManager.maxSignalLevel).thenReturn(5)
|
||||
|
||||
getCallback().onWifiEntriesChanged()
|
||||
|
||||
assertThat(latest is WifiNetworkModel.CarrierMerged).isTrue()
|
||||
val latestMerged = latest as WifiNetworkModel.CarrierMerged
|
||||
// numberOfLevels = maxSignalLevel + 1
|
||||
assertThat(latestMerged.numberOfLevels).isEqualTo(6)
|
||||
}
|
||||
|
||||
/* TODO(b/292534484): Re-enable this test once WifiTrackerLib gives us the subscription ID.
|
||||
@Test
|
||||
fun wifiNetwork_carrierMergedButInvalidSubId_flowHasInvalid() =
|
||||
testScope.runTest {
|
||||
val latest by collectLastValue(underTest.wifiNetwork)
|
||||
|
||||
val wifiInfo =
|
||||
mock<WifiInfo>().apply {
|
||||
whenever(this.isPrimary).thenReturn(true)
|
||||
whenever(this.isCarrierMerged).thenReturn(true)
|
||||
whenever(this.subscriptionId).thenReturn(INVALID_SUBSCRIPTION_ID)
|
||||
}
|
||||
|
||||
getNetworkCallback()
|
||||
.onCapabilitiesChanged(
|
||||
NETWORK,
|
||||
createWifiNetworkCapabilities(wifiInfo),
|
||||
)
|
||||
|
||||
assertThat(latest).isInstanceOf(WifiNetworkModel.Invalid::class.java)
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
@Test
|
||||
fun wifiNetwork_notValidated_networkNotValidated() =
|
||||
testScope.runTest {
|
||||
val latest by collectLastValue(underTest.wifiNetwork)
|
||||
|
||||
val wifiEntry =
|
||||
mock<WifiEntry>().apply {
|
||||
whenever(this.isPrimaryNetwork).thenReturn(true)
|
||||
whenever(this.hasInternetAccess()).thenReturn(false)
|
||||
}
|
||||
whenever(wifiPickerTracker.connectedWifiEntry).thenReturn(wifiEntry)
|
||||
getCallback().onWifiEntriesChanged()
|
||||
|
||||
assertThat((latest as WifiNetworkModel.Active).isValidated).isFalse()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun wifiNetwork_validated_networkValidated() =
|
||||
testScope.runTest {
|
||||
val latest by collectLastValue(underTest.wifiNetwork)
|
||||
|
||||
val wifiEntry =
|
||||
mock<WifiEntry>().apply {
|
||||
whenever(this.isPrimaryNetwork).thenReturn(true)
|
||||
whenever(this.hasInternetAccess()).thenReturn(true)
|
||||
}
|
||||
whenever(wifiPickerTracker.connectedWifiEntry).thenReturn(wifiEntry)
|
||||
getCallback().onWifiEntriesChanged()
|
||||
|
||||
assertThat((latest as WifiNetworkModel.Active).isValidated).isTrue()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun wifiNetwork_nonPrimaryWifiNetworkAdded_flowHasNoNetwork() =
|
||||
testScope.runTest {
|
||||
val latest by collectLastValue(underTest.wifiNetwork)
|
||||
|
||||
val wifiEntry =
|
||||
mock<WifiEntry>().apply { whenever(this.isPrimaryNetwork).thenReturn(false) }
|
||||
whenever(wifiPickerTracker.connectedWifiEntry).thenReturn(wifiEntry)
|
||||
getCallback().onWifiEntriesChanged()
|
||||
|
||||
assertThat(latest).isEqualTo(WifiNetworkModel.Inactive)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun wifiNetwork_nonPrimaryCarrierMergedNetworkAdded_flowHasNoNetwork() =
|
||||
testScope.runTest {
|
||||
val latest by collectLastValue(underTest.wifiNetwork)
|
||||
|
||||
val wifiEntry =
|
||||
mock<MergedCarrierEntry>().apply {
|
||||
whenever(this.isPrimaryNetwork).thenReturn(false)
|
||||
}
|
||||
whenever(wifiPickerTracker.connectedWifiEntry).thenReturn(wifiEntry)
|
||||
getCallback().onWifiEntriesChanged()
|
||||
|
||||
assertThat(latest).isEqualTo(WifiNetworkModel.Inactive)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun wifiNetwork_newPrimaryWifiNetwork_flowHasNewNetwork() =
|
||||
testScope.runTest {
|
||||
val latest by collectLastValue(underTest.wifiNetwork)
|
||||
|
||||
// Start with the original network
|
||||
val wifiEntry =
|
||||
mock<WifiEntry>().apply {
|
||||
whenever(this.isPrimaryNetwork).thenReturn(true)
|
||||
whenever(this.level).thenReturn(3)
|
||||
whenever(this.ssid).thenReturn("AB")
|
||||
}
|
||||
whenever(wifiPickerTracker.connectedWifiEntry).thenReturn(wifiEntry)
|
||||
getCallback().onWifiEntriesChanged()
|
||||
|
||||
assertThat(latest is WifiNetworkModel.Active).isTrue()
|
||||
var latestActive = latest as WifiNetworkModel.Active
|
||||
assertThat(latestActive.level).isEqualTo(3)
|
||||
assertThat(latestActive.ssid).isEqualTo("AB")
|
||||
|
||||
// WHEN we update to a new primary network
|
||||
val newWifiEntry =
|
||||
mock<WifiEntry>().apply {
|
||||
whenever(this.isPrimaryNetwork).thenReturn(true)
|
||||
whenever(this.level).thenReturn(4)
|
||||
whenever(this.ssid).thenReturn("CD")
|
||||
}
|
||||
whenever(wifiPickerTracker.connectedWifiEntry).thenReturn(newWifiEntry)
|
||||
getCallback().onWifiEntriesChanged()
|
||||
|
||||
// THEN we use the new network
|
||||
assertThat(latest is WifiNetworkModel.Active).isTrue()
|
||||
latestActive = latest as WifiNetworkModel.Active
|
||||
assertThat(latestActive.level).isEqualTo(4)
|
||||
assertThat(latestActive.ssid).isEqualTo("CD")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun wifiNetwork_noCurrentNetwork_networkLost_flowHasNoNetwork() =
|
||||
testScope.runTest {
|
||||
val latest by collectLastValue(underTest.wifiNetwork)
|
||||
|
||||
// WHEN we receive a null network without any networks beforehand
|
||||
whenever(wifiPickerTracker.connectedWifiEntry).thenReturn(null)
|
||||
getCallback().onWifiEntriesChanged()
|
||||
|
||||
// THEN there's no crash and we still have no network
|
||||
assertThat(latest is WifiNetworkModel.Inactive).isTrue()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun wifiNetwork_currentActiveNetworkLost_flowHasNoNetwork() =
|
||||
testScope.runTest {
|
||||
val latest by collectLastValue(underTest.wifiNetwork)
|
||||
|
||||
val wifiEntry =
|
||||
mock<WifiEntry>().apply {
|
||||
whenever(this.isPrimaryNetwork).thenReturn(true)
|
||||
whenever(this.ssid).thenReturn(SSID)
|
||||
}
|
||||
whenever(wifiPickerTracker.connectedWifiEntry).thenReturn(wifiEntry)
|
||||
getCallback().onWifiEntriesChanged()
|
||||
|
||||
assertThat((latest as WifiNetworkModel.Active).ssid).isEqualTo(SSID)
|
||||
|
||||
// WHEN we lose our current network
|
||||
whenever(wifiPickerTracker.connectedWifiEntry).thenReturn(null)
|
||||
getCallback().onWifiEntriesChanged()
|
||||
|
||||
// THEN we update to no network
|
||||
assertThat(latest is WifiNetworkModel.Inactive).isTrue()
|
||||
}
|
||||
|
||||
/** Possible regression test for b/278618530. */
|
||||
@Test
|
||||
fun wifiNetwork_currentCarrierMergedNetworkLost_flowHasNoNetwork() =
|
||||
testScope.runTest {
|
||||
val latest by collectLastValue(underTest.wifiNetwork)
|
||||
|
||||
val wifiEntry =
|
||||
mock<MergedCarrierEntry>().apply {
|
||||
whenever(this.isPrimaryNetwork).thenReturn(true)
|
||||
whenever(this.level).thenReturn(3)
|
||||
}
|
||||
whenever(wifiPickerTracker.connectedWifiEntry).thenReturn(wifiEntry)
|
||||
getCallback().onWifiEntriesChanged()
|
||||
|
||||
assertThat(latest is WifiNetworkModel.CarrierMerged).isTrue()
|
||||
assertThat((latest as WifiNetworkModel.CarrierMerged).level).isEqualTo(3)
|
||||
|
||||
// WHEN we lose our current network
|
||||
whenever(wifiPickerTracker.connectedWifiEntry).thenReturn(null)
|
||||
getCallback().onWifiEntriesChanged()
|
||||
|
||||
// THEN we update to no network
|
||||
assertThat(latest is WifiNetworkModel.Inactive).isTrue()
|
||||
}
|
||||
|
||||
/** Regression test for b/244173280. */
|
||||
@Test
|
||||
fun wifiNetwork_multipleSubscribers_newSubscribersGetCurrentValue() =
|
||||
testScope.runTest {
|
||||
val latest1 by collectLastValue(underTest.wifiNetwork)
|
||||
|
||||
val wifiEntry =
|
||||
mock<WifiEntry>().apply {
|
||||
whenever(this.isPrimaryNetwork).thenReturn(true)
|
||||
whenever(this.level).thenReturn(1)
|
||||
whenever(this.ssid).thenReturn(SSID)
|
||||
}
|
||||
whenever(wifiPickerTracker.connectedWifiEntry).thenReturn(wifiEntry)
|
||||
getCallback().onWifiEntriesChanged()
|
||||
|
||||
assertThat(latest1 is WifiNetworkModel.Active).isTrue()
|
||||
val latest1Active = latest1 as WifiNetworkModel.Active
|
||||
assertThat(latest1Active.level).isEqualTo(1)
|
||||
assertThat(latest1Active.ssid).isEqualTo(SSID)
|
||||
|
||||
// WHEN we add a second subscriber after having already emitted a value
|
||||
val latest2 by collectLastValue(underTest.wifiNetwork)
|
||||
|
||||
// THEN the second subscribe receives the already-emitted value
|
||||
assertThat(latest2 is WifiNetworkModel.Active).isTrue()
|
||||
val latest2Active = latest2 as WifiNetworkModel.Active
|
||||
assertThat(latest2Active.level).isEqualTo(1)
|
||||
assertThat(latest2Active.ssid).isEqualTo(SSID)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun isWifiConnectedWithValidSsid_inactiveNetwork_false() =
|
||||
testScope.runTest {
|
||||
collectLastValue(underTest.wifiNetwork)
|
||||
|
||||
whenever(wifiPickerTracker.connectedWifiEntry).thenReturn(null)
|
||||
getCallback().onWifiEntriesChanged()
|
||||
|
||||
assertThat(underTest.isWifiConnectedWithValidSsid()).isFalse()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun isWifiConnectedWithValidSsid_nonPrimaryNetwork_false() =
|
||||
testScope.runTest {
|
||||
collectLastValue(underTest.wifiNetwork)
|
||||
|
||||
val wifiEntry =
|
||||
mock<WifiEntry>().apply { whenever(this.isPrimaryNetwork).thenReturn(false) }
|
||||
whenever(wifiPickerTracker.connectedWifiEntry).thenReturn(wifiEntry)
|
||||
getCallback().onWifiEntriesChanged()
|
||||
testScope.runCurrent()
|
||||
|
||||
assertThat(underTest.isWifiConnectedWithValidSsid()).isFalse()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun isWifiConnectedWithValidSsid_carrierMergedNetwork_false() =
|
||||
testScope.runTest {
|
||||
collectLastValue(underTest.wifiNetwork)
|
||||
|
||||
val wifiEntry =
|
||||
mock<MergedCarrierEntry>().apply {
|
||||
whenever(this.isPrimaryNetwork).thenReturn(true)
|
||||
}
|
||||
whenever(wifiPickerTracker.connectedWifiEntry).thenReturn(wifiEntry)
|
||||
getCallback().onWifiEntriesChanged()
|
||||
testScope.runCurrent()
|
||||
|
||||
assertThat(underTest.isWifiConnectedWithValidSsid()).isFalse()
|
||||
}
|
||||
|
||||
/* TODO(b/292534484): Re-enable this test once WifiTrackerLib gives us the subscription ID.
|
||||
@Test
|
||||
fun isWifiConnectedWithValidSsid_invalidNetwork_false() =
|
||||
testScope.runTest {
|
||||
collectLastValue(underTest.wifiNetwork)
|
||||
|
||||
val wifiInfo =
|
||||
mock<WifiInfo>().apply {
|
||||
whenever(this.isPrimary).thenReturn(true)
|
||||
whenever(this.isCarrierMerged).thenReturn(true)
|
||||
whenever(this.subscriptionId).thenReturn(INVALID_SUBSCRIPTION_ID)
|
||||
}
|
||||
|
||||
getNetworkCallback()
|
||||
.onCapabilitiesChanged(
|
||||
NETWORK,
|
||||
createWifiNetworkCapabilities(wifiInfo),
|
||||
)
|
||||
testScope.runCurrent()
|
||||
|
||||
assertThat(underTest.isWifiConnectedWithValidSsid()).isFalse()
|
||||
}
|
||||
|
||||
*/
|
||||
|
||||
@Test
|
||||
fun isWifiConnectedWithValidSsid_activeNetwork_nullSsid_false() =
|
||||
testScope.runTest {
|
||||
collectLastValue(underTest.wifiNetwork)
|
||||
|
||||
val wifiEntry =
|
||||
mock<WifiEntry>().apply {
|
||||
whenever(this.isPrimaryNetwork).thenReturn(true)
|
||||
whenever(this.ssid).thenReturn(null)
|
||||
}
|
||||
whenever(wifiPickerTracker.connectedWifiEntry).thenReturn(wifiEntry)
|
||||
getCallback().onWifiEntriesChanged()
|
||||
testScope.runCurrent()
|
||||
|
||||
assertThat(underTest.isWifiConnectedWithValidSsid()).isFalse()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun isWifiConnectedWithValidSsid_activeNetwork_unknownSsid_false() =
|
||||
testScope.runTest {
|
||||
collectLastValue(underTest.wifiNetwork)
|
||||
|
||||
val wifiEntry =
|
||||
mock<WifiEntry>().apply {
|
||||
whenever(this.isPrimaryNetwork).thenReturn(true)
|
||||
whenever(this.ssid).thenReturn(UNKNOWN_SSID)
|
||||
}
|
||||
whenever(wifiPickerTracker.connectedWifiEntry).thenReturn(wifiEntry)
|
||||
getCallback().onWifiEntriesChanged()
|
||||
testScope.runCurrent()
|
||||
|
||||
assertThat(underTest.isWifiConnectedWithValidSsid()).isFalse()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun isWifiConnectedWithValidSsid_activeNetwork_validSsid_true() =
|
||||
testScope.runTest {
|
||||
collectLastValue(underTest.wifiNetwork)
|
||||
|
||||
val wifiEntry =
|
||||
mock<WifiEntry>().apply {
|
||||
whenever(this.isPrimaryNetwork).thenReturn(true)
|
||||
whenever(this.ssid).thenReturn("fakeSsid")
|
||||
}
|
||||
whenever(wifiPickerTracker.connectedWifiEntry).thenReturn(wifiEntry)
|
||||
getCallback().onWifiEntriesChanged()
|
||||
testScope.runCurrent()
|
||||
|
||||
assertThat(underTest.isWifiConnectedWithValidSsid()).isTrue()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun isWifiConnectedWithValidSsid_activeToInactive_trueToFalse() =
|
||||
testScope.runTest {
|
||||
collectLastValue(underTest.wifiNetwork)
|
||||
|
||||
// Start with active
|
||||
val wifiEntry =
|
||||
mock<WifiEntry>().apply {
|
||||
whenever(this.isPrimaryNetwork).thenReturn(true)
|
||||
whenever(this.ssid).thenReturn("fakeSsid")
|
||||
}
|
||||
whenever(wifiPickerTracker.connectedWifiEntry).thenReturn(wifiEntry)
|
||||
getCallback().onWifiEntriesChanged()
|
||||
testScope.runCurrent()
|
||||
|
||||
assertThat(underTest.isWifiConnectedWithValidSsid()).isTrue()
|
||||
|
||||
// WHEN the network is lost
|
||||
whenever(wifiPickerTracker.connectedWifiEntry).thenReturn(null)
|
||||
getCallback().onWifiEntriesChanged()
|
||||
testScope.runCurrent()
|
||||
|
||||
// THEN the isWifiConnected updates
|
||||
assertThat(underTest.isWifiConnectedWithValidSsid()).isFalse()
|
||||
}
|
||||
|
||||
private fun getCallback(): WifiPickerTracker.WifiPickerTrackerCallback {
|
||||
testScope.runCurrent()
|
||||
return callbackCaptor.value
|
||||
}
|
||||
|
||||
private fun createRepo(): WifiRepositoryViaTrackerLib {
|
||||
return WifiRepositoryViaTrackerLib(
|
||||
testScope.backgroundScope,
|
||||
executor,
|
||||
wifiPickerTrackerFactory,
|
||||
wifiManager,
|
||||
logger,
|
||||
tableLogger,
|
||||
)
|
||||
}
|
||||
|
||||
private companion object {
|
||||
const val SSID = "AB"
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user