1 /*
2  * Copyright (C) 2023 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.systemui.statusbar.pipeline.wifi.data.repository.prod
18 
19 import android.net.wifi.ScanResult
20 import android.net.wifi.WifiManager
21 import android.net.wifi.WifiManager.UNKNOWN_SSID
22 import android.net.wifi.sharedconnectivity.app.NetworkProviderInfo
23 import android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID
24 import android.testing.TestableLooper
25 import androidx.test.filters.SmallTest
26 import com.android.systemui.SysuiTestCase
27 import com.android.systemui.coroutines.collectLastValue
28 import com.android.systemui.flags.FakeFeatureFlags
29 import com.android.systemui.flags.Flags
30 import com.android.systemui.log.LogBuffer
31 import com.android.systemui.log.table.TableLogBuffer
32 import com.android.systemui.statusbar.connectivity.WifiPickerTrackerFactory
33 import com.android.systemui.statusbar.pipeline.shared.data.model.DataActivityModel
34 import com.android.systemui.statusbar.pipeline.wifi.data.repository.prod.WifiRepositoryImpl.Companion.WIFI_NETWORK_DEFAULT
35 import com.android.systemui.statusbar.pipeline.wifi.shared.model.WifiNetworkModel
36 import com.android.systemui.statusbar.pipeline.wifi.shared.model.WifiScanEntry
37 import com.android.systemui.util.concurrency.FakeExecutor
38 import com.android.systemui.util.mockito.any
39 import com.android.systemui.util.mockito.argumentCaptor
40 import com.android.systemui.util.mockito.capture
41 import com.android.systemui.util.mockito.mock
42 import com.android.systemui.util.mockito.whenever
43 import com.android.systemui.util.time.FakeSystemClock
44 import com.android.wifitrackerlib.HotspotNetworkEntry
45 import com.android.wifitrackerlib.HotspotNetworkEntry.DeviceType
46 import com.android.wifitrackerlib.MergedCarrierEntry
47 import com.android.wifitrackerlib.WifiEntry
48 import com.android.wifitrackerlib.WifiEntry.WIFI_LEVEL_MAX
49 import com.android.wifitrackerlib.WifiEntry.WIFI_LEVEL_MIN
50 import com.android.wifitrackerlib.WifiEntry.WIFI_LEVEL_UNREACHABLE
51 import com.android.wifitrackerlib.WifiPickerTracker
52 import com.google.common.truth.Truth.assertThat
53 import kotlinx.coroutines.ExperimentalCoroutinesApi
54 import kotlinx.coroutines.test.StandardTestDispatcher
55 import kotlinx.coroutines.test.TestScope
56 import kotlinx.coroutines.test.runCurrent
57 import kotlinx.coroutines.test.runTest
58 import org.junit.Before
59 import org.junit.Test
60 import org.mockito.Mockito.verify
61 
62 /**
63  * Note: Most of these tests are duplicates of [WifiRepositoryImplTest] tests.
64  *
65  * Any new tests added here may also need to be added to [WifiRepositoryImplTest].
66  */
67 @Suppress("EXPERIMENTAL_IS_NOT_ENABLED")
68 @OptIn(ExperimentalCoroutinesApi::class)
69 @SmallTest
70 @TestableLooper.RunWithLooper(setAsMainLooper = true)
71 class WifiRepositoryImplTest : SysuiTestCase() {
72 
73     // Using lazy means that the class will only be constructed once it's fetched. Because the
74     // repository internally sets some values on construction, we need to set up some test
75     // parameters (like feature flags) *before* construction. Using lazy allows us to do that setup
76     // inside each test case without needing to manually recreate the repository.
<lambda>null77     private val underTest: WifiRepositoryImpl by lazy {
78         WifiRepositoryImpl(
79             featureFlags,
80             testScope.backgroundScope,
81             executor,
82             dispatcher,
83             wifiPickerTrackerFactory,
84             wifiManager,
85             logger,
86             tableLogger,
87         )
88     }
89 
90     private val executor = FakeExecutor(FakeSystemClock())
91     private val logger = LogBuffer("name", maxSize = 100, logcatEchoTracker = mock())
92     private val featureFlags = FakeFeatureFlags()
93     private val tableLogger = mock<TableLogBuffer>()
94     private val wifiManager =
<lambda>null95         mock<WifiManager>().apply { whenever(this.maxSignalLevel).thenReturn(10) }
96     private val wifiPickerTrackerFactory = mock<WifiPickerTrackerFactory>()
97     private val wifiPickerTracker = mock<WifiPickerTracker>()
98 
99     private val callbackCaptor = argumentCaptor<WifiPickerTracker.WifiPickerTrackerCallback>()
100 
101     private val dispatcher = StandardTestDispatcher()
102     private val testScope = TestScope(dispatcher)
103 
104     @Before
setUpnull105     fun setUp() {
106         featureFlags.set(Flags.INSTANT_TETHER, false)
107         featureFlags.set(Flags.WIFI_SECONDARY_NETWORKS, false)
108         whenever(wifiPickerTrackerFactory.create(any(), capture(callbackCaptor), any()))
109             .thenReturn(wifiPickerTracker)
110     }
111 
112     @Test
wifiPickerTrackerCreation_scansDisablednull113     fun wifiPickerTrackerCreation_scansDisabled() =
114         testScope.runTest {
115             collectLastValue(underTest.wifiNetwork)
116             testScope.runCurrent()
117 
118             verify(wifiPickerTracker).disableScanning()
119         }
120 
121     @Test
isWifiEnabled_enabled_truenull122     fun isWifiEnabled_enabled_true() =
123         testScope.runTest {
124             val latest by collectLastValue(underTest.isWifiEnabled)
125 
126             whenever(wifiPickerTracker.wifiState).thenReturn(WifiManager.WIFI_STATE_ENABLED)
127             getCallback().onWifiStateChanged()
128 
129             assertThat(latest).isTrue()
130         }
131 
132     @Test
isWifiEnabled_enabling_falsenull133     fun isWifiEnabled_enabling_false() =
134         testScope.runTest {
135             val latest by collectLastValue(underTest.isWifiEnabled)
136 
137             whenever(wifiPickerTracker.wifiState).thenReturn(WifiManager.WIFI_STATE_ENABLING)
138             getCallback().onWifiStateChanged()
139 
140             assertThat(latest).isFalse()
141         }
142 
143     @Test
isWifiEnabled_disabling_truenull144     fun isWifiEnabled_disabling_true() =
145         testScope.runTest {
146             val latest by collectLastValue(underTest.isWifiEnabled)
147 
148             whenever(wifiPickerTracker.wifiState).thenReturn(WifiManager.WIFI_STATE_DISABLING)
149             getCallback().onWifiStateChanged()
150 
151             assertThat(latest).isFalse()
152         }
153 
154     @Test
isWifiEnabled_disabled_falsenull155     fun isWifiEnabled_disabled_false() =
156         testScope.runTest {
157             val latest by collectLastValue(underTest.isWifiEnabled)
158 
159             whenever(wifiPickerTracker.wifiState).thenReturn(WifiManager.WIFI_STATE_DISABLED)
160             getCallback().onWifiStateChanged()
161 
162             assertThat(latest).isFalse()
163         }
164 
165     @Test
isWifiEnabled_respondsToUpdatesnull166     fun isWifiEnabled_respondsToUpdates() =
167         testScope.runTest {
168             val latest by collectLastValue(underTest.isWifiEnabled)
169             executor.runAllReady()
170 
171             whenever(wifiPickerTracker.wifiState).thenReturn(WifiManager.WIFI_STATE_ENABLED)
172             getCallback().onWifiStateChanged()
173 
174             assertThat(latest).isTrue()
175 
176             whenever(wifiPickerTracker.wifiState).thenReturn(WifiManager.WIFI_STATE_DISABLED)
177             getCallback().onWifiStateChanged()
178 
179             assertThat(latest).isFalse()
180         }
181 
182     @Test
isWifiDefault_initiallyGetsDefaultnull183     fun isWifiDefault_initiallyGetsDefault() =
184         testScope.runTest { assertThat(underTest.isWifiDefault.value).isFalse() }
185 
186     @Test
isWifiDefault_wifiNetwork_isTruenull187     fun isWifiDefault_wifiNetwork_isTrue() =
188         testScope.runTest {
189             val latest by collectLastValue(underTest.isWifiDefault)
190 
191             val wifiEntry =
192                 mock<WifiEntry>().apply { whenever(this.isDefaultNetwork).thenReturn(true) }
193             whenever(wifiPickerTracker.connectedWifiEntry).thenReturn(wifiEntry)
194             getCallback().onWifiEntriesChanged()
195 
196             assertThat(latest).isTrue()
197         }
198 
199     @Test
isWifiDefault_carrierMerged_isTruenull200     fun isWifiDefault_carrierMerged_isTrue() =
201         testScope.runTest {
202             val latest by collectLastValue(underTest.isWifiDefault)
203 
204             val mergedEntry =
205                 mock<MergedCarrierEntry>().apply {
206                     whenever(this.isDefaultNetwork).thenReturn(true)
207                 }
208             whenever(wifiPickerTracker.mergedCarrierEntry).thenReturn(mergedEntry)
209             getCallback().onWifiEntriesChanged()
210 
211             assertThat(latest).isTrue()
212         }
213 
214     @Test
isWifiDefault_wifiNetworkNotDefault_isFalsenull215     fun isWifiDefault_wifiNetworkNotDefault_isFalse() =
216         testScope.runTest {
217             val latest by collectLastValue(underTest.isWifiDefault)
218 
219             val wifiEntry =
220                 mock<WifiEntry>().apply { whenever(this.isDefaultNetwork).thenReturn(false) }
221             whenever(wifiPickerTracker.connectedWifiEntry).thenReturn(wifiEntry)
222             getCallback().onWifiEntriesChanged()
223 
224             assertThat(latest).isFalse()
225         }
226 
227     @Test
isWifiDefault_carrierMergedNotDefault_isFalsenull228     fun isWifiDefault_carrierMergedNotDefault_isFalse() =
229         testScope.runTest {
230             val latest by collectLastValue(underTest.isWifiDefault)
231 
232             val mergedEntry =
233                 mock<MergedCarrierEntry>().apply {
234                     whenever(this.isDefaultNetwork).thenReturn(false)
235                 }
236             whenever(wifiPickerTracker.mergedCarrierEntry).thenReturn(mergedEntry)
237             getCallback().onWifiEntriesChanged()
238 
239             assertThat(latest).isFalse()
240         }
241 
242     @Test
isWifiDefault_noWifiNetwork_isFalsenull243     fun isWifiDefault_noWifiNetwork_isFalse() =
244         testScope.runTest {
245             val latest by collectLastValue(underTest.isWifiDefault)
246 
247             // First, add a network
248             val wifiEntry =
249                 mock<WifiEntry>().apply { whenever(this.isDefaultNetwork).thenReturn(true) }
250             whenever(wifiPickerTracker.connectedWifiEntry).thenReturn(wifiEntry)
251             getCallback().onWifiEntriesChanged()
252 
253             assertThat(latest).isTrue()
254 
255             // WHEN the network is lost
256             whenever(wifiPickerTracker.connectedWifiEntry).thenReturn(null)
257             getCallback().onWifiEntriesChanged()
258 
259             // THEN we update to false
260             assertThat(latest).isFalse()
261         }
262 
263     @Test
wifiNetwork_initiallyGetsDefaultnull264     fun wifiNetwork_initiallyGetsDefault() =
265         testScope.runTest {
266             val latest by collectLastValue(underTest.wifiNetwork)
267 
268             assertThat(latest).isEqualTo(WIFI_NETWORK_DEFAULT)
269         }
270 
271     @Test
wifiNetwork_primaryWifiNetworkAdded_flowHasNetworknull272     fun wifiNetwork_primaryWifiNetworkAdded_flowHasNetwork() =
273         testScope.runTest {
274             val latest by collectLastValue(underTest.wifiNetwork)
275 
276             val wifiEntry =
277                 mock<WifiEntry>().apply {
278                     whenever(this.isPrimaryNetwork).thenReturn(true)
279                     whenever(this.level).thenReturn(3)
280                     whenever(this.title).thenReturn(TITLE)
281                 }
282             whenever(wifiPickerTracker.connectedWifiEntry).thenReturn(wifiEntry)
283             getCallback().onWifiEntriesChanged()
284 
285             assertThat(latest is WifiNetworkModel.Active).isTrue()
286             val latestActive = latest as WifiNetworkModel.Active
287             assertThat(latestActive.level).isEqualTo(3)
288             assertThat(latestActive.ssid).isEqualTo(TITLE)
289         }
290 
291     @Test
accessPointInfo_alwaysFalsenull292     fun accessPointInfo_alwaysFalse() =
293         testScope.runTest {
294             val latest by collectLastValue(underTest.wifiNetwork)
295 
296             val wifiEntry =
297                 mock<WifiEntry>().apply {
298                     whenever(this.isPrimaryNetwork).thenReturn(true)
299                     whenever(this.level).thenReturn(3)
300                     whenever(this.title).thenReturn(TITLE)
301                 }
302             whenever(wifiPickerTracker.connectedWifiEntry).thenReturn(wifiEntry)
303             getCallback().onWifiEntriesChanged()
304 
305             assertThat(latest is WifiNetworkModel.Active).isTrue()
306             val latestActive = latest as WifiNetworkModel.Active
307             assertThat(latestActive.isPasspointAccessPoint).isFalse()
308             assertThat(latestActive.isOnlineSignUpForPasspointAccessPoint).isFalse()
309             assertThat(latestActive.passpointProviderFriendlyName).isNull()
310         }
311 
312     @Test
wifiNetwork_unreachableLevel_inactiveNetworknull313     fun wifiNetwork_unreachableLevel_inactiveNetwork() =
314         testScope.runTest {
315             val latest by collectLastValue(underTest.wifiNetwork)
316 
317             val wifiEntry =
318                 mock<WifiEntry>().apply {
319                     whenever(this.isPrimaryNetwork).thenReturn(true)
320                     whenever(this.level).thenReturn(WIFI_LEVEL_UNREACHABLE)
321                 }
322             whenever(wifiPickerTracker.connectedWifiEntry).thenReturn(wifiEntry)
323             getCallback().onWifiEntriesChanged()
324 
325             assertThat(latest).isEqualTo(WifiNetworkModel.Inactive)
326         }
327 
328     @Test
wifiNetwork_levelTooHigh_inactiveNetworknull329     fun wifiNetwork_levelTooHigh_inactiveNetwork() =
330         testScope.runTest {
331             val latest by collectLastValue(underTest.wifiNetwork)
332 
333             val wifiEntry =
334                 mock<WifiEntry>().apply {
335                     whenever(this.isPrimaryNetwork).thenReturn(true)
336                     whenever(this.level).thenReturn(WIFI_LEVEL_MAX + 1)
337                 }
338             whenever(wifiPickerTracker.connectedWifiEntry).thenReturn(wifiEntry)
339             getCallback().onWifiEntriesChanged()
340 
341             assertThat(latest).isEqualTo(WifiNetworkModel.Inactive)
342         }
343 
344     @Test
wifiNetwork_levelTooLow_inactiveNetworknull345     fun wifiNetwork_levelTooLow_inactiveNetwork() =
346         testScope.runTest {
347             val latest by collectLastValue(underTest.wifiNetwork)
348 
349             val wifiEntry =
350                 mock<WifiEntry>().apply {
351                     whenever(this.isPrimaryNetwork).thenReturn(true)
352                     whenever(this.level).thenReturn(WIFI_LEVEL_MIN - 1)
353                 }
354             whenever(wifiPickerTracker.connectedWifiEntry).thenReturn(wifiEntry)
355             getCallback().onWifiEntriesChanged()
356 
357             assertThat(latest).isEqualTo(WifiNetworkModel.Inactive)
358         }
359 
360     @Test
wifiNetwork_levelIsMax_activeNetworkWithMaxLevelnull361     fun wifiNetwork_levelIsMax_activeNetworkWithMaxLevel() =
362         testScope.runTest {
363             val latest by collectLastValue(underTest.wifiNetwork)
364 
365             val wifiEntry =
366                 mock<WifiEntry>().apply {
367                     whenever(this.isPrimaryNetwork).thenReturn(true)
368                     whenever(this.level).thenReturn(WIFI_LEVEL_MAX)
369                 }
370             whenever(wifiPickerTracker.connectedWifiEntry).thenReturn(wifiEntry)
371             getCallback().onWifiEntriesChanged()
372 
373             assertThat(latest).isInstanceOf(WifiNetworkModel.Active::class.java)
374             assertThat((latest as WifiNetworkModel.Active).level).isEqualTo(WIFI_LEVEL_MAX)
375         }
376 
377     @Test
wifiNetwork_levelIsMin_activeNetworkWithMinLevelnull378     fun wifiNetwork_levelIsMin_activeNetworkWithMinLevel() =
379         testScope.runTest {
380             val latest by collectLastValue(underTest.wifiNetwork)
381 
382             val wifiEntry =
383                 mock<WifiEntry>().apply {
384                     whenever(this.isPrimaryNetwork).thenReturn(true)
385                     whenever(this.level).thenReturn(WIFI_LEVEL_MIN)
386                 }
387             whenever(wifiPickerTracker.connectedWifiEntry).thenReturn(wifiEntry)
388             getCallback().onWifiEntriesChanged()
389 
390             assertThat(latest).isInstanceOf(WifiNetworkModel.Active::class.java)
391             assertThat((latest as WifiNetworkModel.Active).level).isEqualTo(WIFI_LEVEL_MIN)
392         }
393 
394     @Test
wifiNetwork_notHotspot_nonenull395     fun wifiNetwork_notHotspot_none() =
396         testScope.runTest {
397             featureFlags.set(Flags.INSTANT_TETHER, true)
398             val latest by collectLastValue(underTest.wifiNetwork)
399 
400             val wifiEntry =
401                 mock<WifiEntry>().apply { whenever(this.isPrimaryNetwork).thenReturn(true) }
402             whenever(wifiPickerTracker.connectedWifiEntry).thenReturn(wifiEntry)
403             getCallback().onWifiEntriesChanged()
404 
405             assertThat((latest as WifiNetworkModel.Active).hotspotDeviceType)
406                 .isEqualTo(WifiNetworkModel.HotspotDeviceType.NONE)
407         }
408 
409     @Test
wifiNetwork_hotspot_unknownnull410     fun wifiNetwork_hotspot_unknown() =
411         testScope.runTest {
412             featureFlags.set(Flags.INSTANT_TETHER, true)
413             val latest by collectLastValue(underTest.wifiNetwork)
414 
415             val wifiEntry = createHotspotWithType(NetworkProviderInfo.DEVICE_TYPE_UNKNOWN)
416             whenever(wifiPickerTracker.connectedWifiEntry).thenReturn(wifiEntry)
417             getCallback().onWifiEntriesChanged()
418 
419             assertThat((latest as WifiNetworkModel.Active).hotspotDeviceType)
420                 .isEqualTo(WifiNetworkModel.HotspotDeviceType.UNKNOWN)
421         }
422 
423     @Test
wifiNetwork_hotspot_phonenull424     fun wifiNetwork_hotspot_phone() =
425         testScope.runTest {
426             featureFlags.set(Flags.INSTANT_TETHER, true)
427             val latest by collectLastValue(underTest.wifiNetwork)
428 
429             val wifiEntry = createHotspotWithType(NetworkProviderInfo.DEVICE_TYPE_PHONE)
430             whenever(wifiPickerTracker.connectedWifiEntry).thenReturn(wifiEntry)
431             getCallback().onWifiEntriesChanged()
432 
433             assertThat((latest as WifiNetworkModel.Active).hotspotDeviceType)
434                 .isEqualTo(WifiNetworkModel.HotspotDeviceType.PHONE)
435         }
436 
437     @Test
wifiNetwork_hotspot_tabletnull438     fun wifiNetwork_hotspot_tablet() =
439         testScope.runTest {
440             featureFlags.set(Flags.INSTANT_TETHER, true)
441             val latest by collectLastValue(underTest.wifiNetwork)
442 
443             val wifiEntry = createHotspotWithType(NetworkProviderInfo.DEVICE_TYPE_TABLET)
444             whenever(wifiPickerTracker.connectedWifiEntry).thenReturn(wifiEntry)
445             getCallback().onWifiEntriesChanged()
446 
447             assertThat((latest as WifiNetworkModel.Active).hotspotDeviceType)
448                 .isEqualTo(WifiNetworkModel.HotspotDeviceType.TABLET)
449         }
450 
451     @Test
wifiNetwork_hotspot_laptopnull452     fun wifiNetwork_hotspot_laptop() =
453         testScope.runTest {
454             featureFlags.set(Flags.INSTANT_TETHER, true)
455             val latest by collectLastValue(underTest.wifiNetwork)
456 
457             val wifiEntry = createHotspotWithType(NetworkProviderInfo.DEVICE_TYPE_LAPTOP)
458             whenever(wifiPickerTracker.connectedWifiEntry).thenReturn(wifiEntry)
459             getCallback().onWifiEntriesChanged()
460 
461             assertThat((latest as WifiNetworkModel.Active).hotspotDeviceType)
462                 .isEqualTo(WifiNetworkModel.HotspotDeviceType.LAPTOP)
463         }
464 
465     @Test
wifiNetwork_hotspot_watchnull466     fun wifiNetwork_hotspot_watch() =
467         testScope.runTest {
468             featureFlags.set(Flags.INSTANT_TETHER, true)
469             val latest by collectLastValue(underTest.wifiNetwork)
470 
471             val wifiEntry = createHotspotWithType(NetworkProviderInfo.DEVICE_TYPE_WATCH)
472             whenever(wifiPickerTracker.connectedWifiEntry).thenReturn(wifiEntry)
473             getCallback().onWifiEntriesChanged()
474 
475             assertThat((latest as WifiNetworkModel.Active).hotspotDeviceType)
476                 .isEqualTo(WifiNetworkModel.HotspotDeviceType.WATCH)
477         }
478 
479     @Test
wifiNetwork_hotspot_autonull480     fun wifiNetwork_hotspot_auto() =
481         testScope.runTest {
482             featureFlags.set(Flags.INSTANT_TETHER, true)
483             val latest by collectLastValue(underTest.wifiNetwork)
484 
485             val wifiEntry = createHotspotWithType(NetworkProviderInfo.DEVICE_TYPE_AUTO)
486             whenever(wifiPickerTracker.connectedWifiEntry).thenReturn(wifiEntry)
487             getCallback().onWifiEntriesChanged()
488 
489             assertThat((latest as WifiNetworkModel.Active).hotspotDeviceType)
490                 .isEqualTo(WifiNetworkModel.HotspotDeviceType.AUTO)
491         }
492 
493     @Test
wifiNetwork_hotspot_invalidnull494     fun wifiNetwork_hotspot_invalid() =
495         testScope.runTest {
496             featureFlags.set(Flags.INSTANT_TETHER, true)
497             val latest by collectLastValue(underTest.wifiNetwork)
498 
499             val wifiEntry = createHotspotWithType(1234)
500             whenever(wifiPickerTracker.connectedWifiEntry).thenReturn(wifiEntry)
501             getCallback().onWifiEntriesChanged()
502 
503             assertThat((latest as WifiNetworkModel.Active).hotspotDeviceType)
504                 .isEqualTo(WifiNetworkModel.HotspotDeviceType.INVALID)
505         }
506 
507     @Test
wifiNetwork_hotspot_flagOff_valueNotUsednull508     fun wifiNetwork_hotspot_flagOff_valueNotUsed() =
509         testScope.runTest {
510             // WHEN the flag is off
511             featureFlags.set(Flags.INSTANT_TETHER, false)
512 
513             val latest by collectLastValue(underTest.wifiNetwork)
514 
515             val wifiEntry = createHotspotWithType(NetworkProviderInfo.DEVICE_TYPE_WATCH)
516             whenever(wifiPickerTracker.connectedWifiEntry).thenReturn(wifiEntry)
517             getCallback().onWifiEntriesChanged()
518 
519             // THEN NONE is always used, even if the wifi entry does have a hotspot device type
520             assertThat((latest as WifiNetworkModel.Active).hotspotDeviceType)
521                 .isEqualTo(WifiNetworkModel.HotspotDeviceType.NONE)
522         }
523 
524     @Test
wifiNetwork_isCarrierMerged_flowHasCarrierMergednull525     fun wifiNetwork_isCarrierMerged_flowHasCarrierMerged() =
526         testScope.runTest {
527             val latest by collectLastValue(underTest.wifiNetwork)
528 
529             val mergedEntry =
530                 mock<MergedCarrierEntry>().apply {
531                     whenever(this.isPrimaryNetwork).thenReturn(true)
532                     whenever(this.level).thenReturn(3)
533                     whenever(this.subscriptionId).thenReturn(567)
534                     whenever(this.isDefaultNetwork).thenReturn(true)
535                 }
536             whenever(wifiPickerTracker.mergedCarrierEntry).thenReturn(mergedEntry)
537             getCallback().onWifiEntriesChanged()
538 
539             assertThat(latest is WifiNetworkModel.CarrierMerged).isTrue()
540             val latestMerged = latest as WifiNetworkModel.CarrierMerged
541             assertThat(latestMerged.level).isEqualTo(3)
542             assertThat(latestMerged.subscriptionId).isEqualTo(567)
543         }
544 
545     @Test
wifiNetwork_isCarrierMerged_getsMaxSignalLevelnull546     fun wifiNetwork_isCarrierMerged_getsMaxSignalLevel() =
547         testScope.runTest {
548             val latest by collectLastValue(underTest.wifiNetwork)
549 
550             val mergedEntry =
551                 mock<MergedCarrierEntry>().apply {
552                     whenever(this.isPrimaryNetwork).thenReturn(true)
553                     whenever(this.isDefaultNetwork).thenReturn(true)
554                 }
555             whenever(wifiPickerTracker.mergedCarrierEntry).thenReturn(mergedEntry)
556             whenever(wifiManager.maxSignalLevel).thenReturn(5)
557 
558             getCallback().onWifiEntriesChanged()
559 
560             assertThat(latest is WifiNetworkModel.CarrierMerged).isTrue()
561             val latestMerged = latest as WifiNetworkModel.CarrierMerged
562             // numberOfLevels = maxSignalLevel + 1
563             assertThat(latestMerged.numberOfLevels).isEqualTo(6)
564         }
565 
566     @Test
wifiNetwork_carrierMergedButInvalidSubId_flowHasInvalidnull567     fun wifiNetwork_carrierMergedButInvalidSubId_flowHasInvalid() =
568         testScope.runTest {
569             val latest by collectLastValue(underTest.wifiNetwork)
570 
571             val mergedEntry =
572                 mock<MergedCarrierEntry>().apply {
573                     whenever(this.isPrimaryNetwork).thenReturn(true)
574                     whenever(this.subscriptionId).thenReturn(INVALID_SUBSCRIPTION_ID)
575                     whenever(this.isDefaultNetwork).thenReturn(true)
576                 }
577             whenever(wifiPickerTracker.mergedCarrierEntry).thenReturn(mergedEntry)
578 
579             getCallback().onWifiEntriesChanged()
580 
581             assertThat(latest).isInstanceOf(WifiNetworkModel.Invalid::class.java)
582         }
583 
584     @Test
wifiNetwork_notValidated_networkNotValidatednull585     fun wifiNetwork_notValidated_networkNotValidated() =
586         testScope.runTest {
587             val latest by collectLastValue(underTest.wifiNetwork)
588 
589             val wifiEntry =
590                 mock<WifiEntry>().apply {
591                     whenever(this.isPrimaryNetwork).thenReturn(true)
592                     whenever(this.hasInternetAccess()).thenReturn(false)
593                 }
594             whenever(wifiPickerTracker.connectedWifiEntry).thenReturn(wifiEntry)
595             getCallback().onWifiEntriesChanged()
596 
597             assertThat((latest as WifiNetworkModel.Active).isValidated).isFalse()
598         }
599 
600     @Test
wifiNetwork_validated_networkValidatednull601     fun wifiNetwork_validated_networkValidated() =
602         testScope.runTest {
603             val latest by collectLastValue(underTest.wifiNetwork)
604 
605             val wifiEntry =
606                 mock<WifiEntry>().apply {
607                     whenever(this.isPrimaryNetwork).thenReturn(true)
608                     whenever(this.hasInternetAccess()).thenReturn(true)
609                 }
610             whenever(wifiPickerTracker.connectedWifiEntry).thenReturn(wifiEntry)
611             getCallback().onWifiEntriesChanged()
612 
613             assertThat((latest as WifiNetworkModel.Active).isValidated).isTrue()
614         }
615 
616     @Test
wifiNetwork_nonPrimaryWifiNetworkAdded_flowHasNoNetworknull617     fun wifiNetwork_nonPrimaryWifiNetworkAdded_flowHasNoNetwork() =
618         testScope.runTest {
619             val latest by collectLastValue(underTest.wifiNetwork)
620 
621             val wifiEntry =
622                 mock<WifiEntry>().apply { whenever(this.isPrimaryNetwork).thenReturn(false) }
623             whenever(wifiPickerTracker.connectedWifiEntry).thenReturn(wifiEntry)
624             getCallback().onWifiEntriesChanged()
625 
626             assertThat(latest).isEqualTo(WifiNetworkModel.Inactive)
627         }
628 
629     @Test
wifiNetwork_nonPrimaryCarrierMergedNetworkAdded_flowHasNoNetworknull630     fun wifiNetwork_nonPrimaryCarrierMergedNetworkAdded_flowHasNoNetwork() =
631         testScope.runTest {
632             val latest by collectLastValue(underTest.wifiNetwork)
633 
634             val mergedEntry =
635                 mock<MergedCarrierEntry>().apply {
636                     whenever(this.isPrimaryNetwork).thenReturn(false)
637                 }
638             whenever(wifiPickerTracker.mergedCarrierEntry).thenReturn(mergedEntry)
639             whenever(wifiPickerTracker.connectedWifiEntry).thenReturn(null)
640             getCallback().onWifiEntriesChanged()
641 
642             assertThat(latest).isEqualTo(WifiNetworkModel.Inactive)
643         }
644 
645     @Test
wifiNetwork_newPrimaryWifiNetwork_flowHasNewNetworknull646     fun wifiNetwork_newPrimaryWifiNetwork_flowHasNewNetwork() =
647         testScope.runTest {
648             val latest by collectLastValue(underTest.wifiNetwork)
649 
650             // Start with the original network
651             val wifiEntry =
652                 mock<WifiEntry>().apply {
653                     whenever(this.isPrimaryNetwork).thenReturn(true)
654                     whenever(this.level).thenReturn(3)
655                     whenever(this.title).thenReturn("AB")
656                 }
657             whenever(wifiPickerTracker.connectedWifiEntry).thenReturn(wifiEntry)
658             getCallback().onWifiEntriesChanged()
659 
660             assertThat(latest is WifiNetworkModel.Active).isTrue()
661             var latestActive = latest as WifiNetworkModel.Active
662             assertThat(latestActive.level).isEqualTo(3)
663             assertThat(latestActive.ssid).isEqualTo("AB")
664 
665             // WHEN we update to a new primary network
666             val newWifiEntry =
667                 mock<WifiEntry>().apply {
668                     whenever(this.isPrimaryNetwork).thenReturn(true)
669                     whenever(this.level).thenReturn(4)
670                     whenever(this.title).thenReturn("CD")
671                 }
672             whenever(wifiPickerTracker.connectedWifiEntry).thenReturn(newWifiEntry)
673             getCallback().onWifiEntriesChanged()
674 
675             // THEN we use the new network
676             assertThat(latest is WifiNetworkModel.Active).isTrue()
677             latestActive = latest as WifiNetworkModel.Active
678             assertThat(latestActive.level).isEqualTo(4)
679             assertThat(latestActive.ssid).isEqualTo("CD")
680         }
681 
682     @Test
wifiNetwork_noCurrentNetwork_networkLost_flowHasNoNetworknull683     fun wifiNetwork_noCurrentNetwork_networkLost_flowHasNoNetwork() =
684         testScope.runTest {
685             val latest by collectLastValue(underTest.wifiNetwork)
686 
687             // WHEN we receive a null network without any networks beforehand
688             whenever(wifiPickerTracker.connectedWifiEntry).thenReturn(null)
689             getCallback().onWifiEntriesChanged()
690 
691             // THEN there's no crash and we still have no network
692             assertThat(latest is WifiNetworkModel.Inactive).isTrue()
693         }
694 
695     @Test
wifiNetwork_currentActiveNetworkLost_flowHasNoNetworknull696     fun wifiNetwork_currentActiveNetworkLost_flowHasNoNetwork() =
697         testScope.runTest {
698             val latest by collectLastValue(underTest.wifiNetwork)
699 
700             val wifiEntry =
701                 mock<WifiEntry>().apply {
702                     whenever(this.isPrimaryNetwork).thenReturn(true)
703                     whenever(this.title).thenReturn(TITLE)
704                 }
705             whenever(wifiPickerTracker.connectedWifiEntry).thenReturn(wifiEntry)
706             getCallback().onWifiEntriesChanged()
707 
708             assertThat((latest as WifiNetworkModel.Active).ssid).isEqualTo(TITLE)
709 
710             // WHEN we lose our current network
711             whenever(wifiPickerTracker.connectedWifiEntry).thenReturn(null)
712             getCallback().onWifiEntriesChanged()
713 
714             // THEN we update to no network
715             assertThat(latest is WifiNetworkModel.Inactive).isTrue()
716         }
717 
718     /** Possible regression test for b/278618530. */
719     @Test
wifiNetwork_currentCarrierMergedNetworkLost_flowHasNoNetworknull720     fun wifiNetwork_currentCarrierMergedNetworkLost_flowHasNoNetwork() =
721         testScope.runTest {
722             val latest by collectLastValue(underTest.wifiNetwork)
723 
724             val mergedEntry =
725                 mock<MergedCarrierEntry>().apply {
726                     whenever(this.isPrimaryNetwork).thenReturn(true)
727                     whenever(this.level).thenReturn(3)
728                     whenever(this.isDefaultNetwork).thenReturn(true)
729                 }
730             whenever(wifiPickerTracker.connectedWifiEntry).thenReturn(null)
731             whenever(wifiPickerTracker.mergedCarrierEntry).thenReturn(mergedEntry)
732             getCallback().onWifiEntriesChanged()
733 
734             assertThat(latest is WifiNetworkModel.CarrierMerged).isTrue()
735             assertThat((latest as WifiNetworkModel.CarrierMerged).level).isEqualTo(3)
736 
737             // WHEN we lose our current network
738             whenever(wifiPickerTracker.connectedWifiEntry).thenReturn(null)
739             whenever(wifiPickerTracker.mergedCarrierEntry).thenReturn(null)
740             getCallback().onWifiEntriesChanged()
741 
742             // THEN we update to no network
743             assertThat(latest is WifiNetworkModel.Inactive).isTrue()
744         }
745 
746     /** Regression test for b/244173280. */
747     @Test
wifiNetwork_multipleSubscribers_newSubscribersGetCurrentValuenull748     fun wifiNetwork_multipleSubscribers_newSubscribersGetCurrentValue() =
749         testScope.runTest {
750             val latest1 by collectLastValue(underTest.wifiNetwork)
751 
752             val wifiEntry =
753                 mock<WifiEntry>().apply {
754                     whenever(this.isPrimaryNetwork).thenReturn(true)
755                     whenever(this.level).thenReturn(1)
756                     whenever(this.title).thenReturn(TITLE)
757                 }
758             whenever(wifiPickerTracker.connectedWifiEntry).thenReturn(wifiEntry)
759             getCallback().onWifiEntriesChanged()
760 
761             assertThat(latest1 is WifiNetworkModel.Active).isTrue()
762             val latest1Active = latest1 as WifiNetworkModel.Active
763             assertThat(latest1Active.level).isEqualTo(1)
764             assertThat(latest1Active.ssid).isEqualTo(TITLE)
765 
766             // WHEN we add a second subscriber after having already emitted a value
767             val latest2 by collectLastValue(underTest.wifiNetwork)
768 
769             // THEN the second subscribe receives the already-emitted value
770             assertThat(latest2 is WifiNetworkModel.Active).isTrue()
771             val latest2Active = latest2 as WifiNetworkModel.Active
772             assertThat(latest2Active.level).isEqualTo(1)
773             assertThat(latest2Active.ssid).isEqualTo(TITLE)
774         }
775 
776     @Test
wifiNetwork_carrierMerged_default_usesCarrierMergedInfonull777     fun wifiNetwork_carrierMerged_default_usesCarrierMergedInfo() =
778         testScope.runTest {
779             val latest by collectLastValue(underTest.wifiNetwork)
780 
781             val mergedEntry =
782                 mock<MergedCarrierEntry>().apply {
783                     whenever(this.isPrimaryNetwork).thenReturn(true)
784                     whenever(this.level).thenReturn(3)
785                     whenever(this.isDefaultNetwork).thenReturn(true)
786                 }
787             val wifiEntry =
788                 mock<WifiEntry>().apply {
789                     whenever(this.isPrimaryNetwork).thenReturn(true)
790                     whenever(this.level).thenReturn(1)
791                     whenever(this.title).thenReturn(TITLE)
792                 }
793             whenever(wifiPickerTracker.mergedCarrierEntry).thenReturn(mergedEntry)
794             whenever(wifiPickerTracker.connectedWifiEntry).thenReturn(wifiEntry)
795 
796             getCallback().onWifiEntriesChanged()
797 
798             assertThat(latest is WifiNetworkModel.CarrierMerged).isTrue()
799         }
800 
801     @Test
wifiNetwork_carrierMerged_notDefault_usesConnectedInfonull802     fun wifiNetwork_carrierMerged_notDefault_usesConnectedInfo() =
803         testScope.runTest {
804             val latest by collectLastValue(underTest.wifiNetwork)
805 
806             val mergedEntry =
807                 mock<MergedCarrierEntry>().apply {
808                     whenever(this.isPrimaryNetwork).thenReturn(true)
809                     whenever(this.level).thenReturn(3)
810                     whenever(this.isDefaultNetwork).thenReturn(false)
811                 }
812             val wifiEntry =
813                 mock<WifiEntry>().apply {
814                     whenever(this.isPrimaryNetwork).thenReturn(true)
815                     whenever(this.level).thenReturn(1)
816                     whenever(this.title).thenReturn(TITLE)
817                 }
818             whenever(wifiPickerTracker.mergedCarrierEntry).thenReturn(mergedEntry)
819             whenever(wifiPickerTracker.connectedWifiEntry).thenReturn(wifiEntry)
820 
821             getCallback().onWifiEntriesChanged()
822 
823             assertThat(latest is WifiNetworkModel.Active).isTrue()
824         }
825 
826     @Test
secondaryNetworks_activeEntriesEmpty_isEmptynull827     fun secondaryNetworks_activeEntriesEmpty_isEmpty() =
828         testScope.runTest {
829             featureFlags.set(Flags.WIFI_SECONDARY_NETWORKS, true)
830             val latest by collectLastValue(underTest.secondaryNetworks)
831 
832             whenever(wifiPickerTracker.activeWifiEntries).thenReturn(listOf())
833 
834             getCallback().onWifiEntriesChanged()
835 
836             assertThat(latest).isEmpty()
837         }
838 
839     @Test
secondaryNetworks_oneActiveEntry_hasOnenull840     fun secondaryNetworks_oneActiveEntry_hasOne() =
841         testScope.runTest {
842             featureFlags.set(Flags.WIFI_SECONDARY_NETWORKS, true)
843             val latest by collectLastValue(underTest.secondaryNetworks)
844 
845             val wifiEntry = mock<WifiEntry>()
846             whenever(wifiPickerTracker.activeWifiEntries).thenReturn(listOf(wifiEntry))
847 
848             getCallback().onWifiEntriesChanged()
849 
850             assertThat(latest).hasSize(1)
851         }
852 
853     @Test
secondaryNetworks_multipleActiveEntries_hasMultiplenull854     fun secondaryNetworks_multipleActiveEntries_hasMultiple() =
855         testScope.runTest {
856             featureFlags.set(Flags.WIFI_SECONDARY_NETWORKS, true)
857             val latest by collectLastValue(underTest.secondaryNetworks)
858 
859             val wifiEntry1 = mock<WifiEntry>()
860             val wifiEntry2 = mock<WifiEntry>()
861             whenever(wifiPickerTracker.activeWifiEntries).thenReturn(listOf(wifiEntry1, wifiEntry2))
862 
863             getCallback().onWifiEntriesChanged()
864 
865             assertThat(latest).hasSize(2)
866         }
867 
868     @Test
secondaryNetworks_mapsToInactivenull869     fun secondaryNetworks_mapsToInactive() =
870         testScope.runTest {
871             featureFlags.set(Flags.WIFI_SECONDARY_NETWORKS, true)
872             val latest by collectLastValue(underTest.secondaryNetworks)
873 
874             val inactiveEntry =
875                 mock<WifiEntry>().apply { whenever(this.level).thenReturn(WIFI_LEVEL_UNREACHABLE) }
876             whenever(wifiPickerTracker.activeWifiEntries).thenReturn(listOf(inactiveEntry))
877 
878             getCallback().onWifiEntriesChanged()
879 
880             assertThat(latest).hasSize(1)
881             assertThat(latest!![0]).isInstanceOf(WifiNetworkModel.Inactive::class.java)
882         }
883 
884     @Test
secondaryNetworks_mapsToActivenull885     fun secondaryNetworks_mapsToActive() =
886         testScope.runTest {
887             featureFlags.set(Flags.WIFI_SECONDARY_NETWORKS, true)
888             val latest by collectLastValue(underTest.secondaryNetworks)
889 
890             val activeEntry = mock<WifiEntry>().apply { whenever(this.level).thenReturn(2) }
891             whenever(wifiPickerTracker.activeWifiEntries).thenReturn(listOf(activeEntry))
892 
893             getCallback().onWifiEntriesChanged()
894 
895             assertThat(latest).hasSize(1)
896             assertThat(latest!![0]).isInstanceOf(WifiNetworkModel.Active::class.java)
897             assertThat((latest!![0] as WifiNetworkModel.Active).level).isEqualTo(2)
898         }
899 
900     @Test
secondaryNetworks_mapsToCarrierMergednull901     fun secondaryNetworks_mapsToCarrierMerged() =
902         testScope.runTest {
903             featureFlags.set(Flags.WIFI_SECONDARY_NETWORKS, true)
904             val latest by collectLastValue(underTest.secondaryNetworks)
905 
906             val carrierMergedEntry =
907                 mock<MergedCarrierEntry>().apply { whenever(this.level).thenReturn(3) }
908             whenever(wifiPickerTracker.activeWifiEntries).thenReturn(listOf(carrierMergedEntry))
909 
910             getCallback().onWifiEntriesChanged()
911 
912             assertThat(latest).hasSize(1)
913             assertThat(latest!![0]).isInstanceOf(WifiNetworkModel.CarrierMerged::class.java)
914             assertThat((latest!![0] as WifiNetworkModel.CarrierMerged).level).isEqualTo(3)
915         }
916 
917     @Test
secondaryNetworks_mapsMultipleInOrdernull918     fun secondaryNetworks_mapsMultipleInOrder() =
919         testScope.runTest {
920             featureFlags.set(Flags.WIFI_SECONDARY_NETWORKS, true)
921             val latest by collectLastValue(underTest.secondaryNetworks)
922 
923             val activeEntry = mock<WifiEntry>().apply { whenever(this.level).thenReturn(2) }
924             val carrierMergedEntry =
925                 mock<MergedCarrierEntry>().apply { whenever(this.level).thenReturn(3) }
926             whenever(wifiPickerTracker.activeWifiEntries)
927                 .thenReturn(listOf(activeEntry, carrierMergedEntry))
928 
929             getCallback().onWifiEntriesChanged()
930 
931             assertThat(latest!![0]).isInstanceOf(WifiNetworkModel.Active::class.java)
932             assertThat((latest!![0] as WifiNetworkModel.Active).level).isEqualTo(2)
933             assertThat(latest!![1]).isInstanceOf(WifiNetworkModel.CarrierMerged::class.java)
934             assertThat((latest!![1] as WifiNetworkModel.CarrierMerged).level).isEqualTo(3)
935         }
936 
937     @Test
secondaryNetworks_filtersOutConnectedEntrynull938     fun secondaryNetworks_filtersOutConnectedEntry() =
939         testScope.runTest {
940             featureFlags.set(Flags.WIFI_SECONDARY_NETWORKS, true)
941             val latest by collectLastValue(underTest.secondaryNetworks)
942 
943             val connectedEntry = mock<WifiEntry>().apply { whenever(this.level).thenReturn(1) }
944             val secondaryEntry1 = mock<WifiEntry>().apply { whenever(this.level).thenReturn(2) }
945             val secondaryEntry2 = mock<WifiEntry>().apply { whenever(this.level).thenReturn(3) }
946             // WHEN the active list has both a primary and secondary networks
947             whenever(wifiPickerTracker.activeWifiEntries)
948                 .thenReturn(listOf(connectedEntry, secondaryEntry1, secondaryEntry2))
949             whenever(wifiPickerTracker.connectedWifiEntry).thenReturn(connectedEntry)
950 
951             getCallback().onWifiEntriesChanged()
952 
953             // THEN only the secondary networks are included
954             assertThat(latest).hasSize(2)
955             assertThat((latest!![0] as WifiNetworkModel.Active).level).isEqualTo(2)
956             assertThat((latest!![1] as WifiNetworkModel.Active).level).isEqualTo(3)
957         }
958 
959     @Test
secondaryNetworks_noConnectedEntry_hasAllActiveEntriesnull960     fun secondaryNetworks_noConnectedEntry_hasAllActiveEntries() =
961         testScope.runTest {
962             featureFlags.set(Flags.WIFI_SECONDARY_NETWORKS, true)
963             val latest by collectLastValue(underTest.secondaryNetworks)
964 
965             val secondaryEntry1 = mock<WifiEntry>().apply { whenever(this.level).thenReturn(2) }
966             val secondaryEntry2 = mock<WifiEntry>().apply { whenever(this.level).thenReturn(3) }
967             whenever(wifiPickerTracker.activeWifiEntries)
968                 .thenReturn(listOf(secondaryEntry1, secondaryEntry2))
969             whenever(wifiPickerTracker.connectedWifiEntry).thenReturn(null)
970 
971             getCallback().onWifiEntriesChanged()
972 
973             assertThat(latest).hasSize(2)
974             assertThat((latest!![0] as WifiNetworkModel.Active).level).isEqualTo(2)
975             assertThat((latest!![1] as WifiNetworkModel.Active).level).isEqualTo(3)
976         }
977 
978     @Test
secondaryNetworks_filtersOutPrimaryNetworknull979     fun secondaryNetworks_filtersOutPrimaryNetwork() =
980         testScope.runTest {
981             featureFlags.set(Flags.WIFI_SECONDARY_NETWORKS, true)
982             val latest by collectLastValue(underTest.secondaryNetworks)
983 
984             val primaryEntry =
985                 mock<WifiEntry>().apply {
986                     whenever(this.isPrimaryNetwork).thenReturn(true)
987                     whenever(this.level).thenReturn(1)
988                 }
989             val secondaryEntry1 = mock<WifiEntry>().apply { whenever(this.level).thenReturn(2) }
990             val secondaryEntry2 = mock<WifiEntry>().apply { whenever(this.level).thenReturn(3) }
991             // WHEN the active list has both a primary and secondary networks
992             whenever(wifiPickerTracker.activeWifiEntries)
993                 .thenReturn(listOf(secondaryEntry1, primaryEntry, secondaryEntry2))
994 
995             getCallback().onWifiEntriesChanged()
996 
997             // THEN only the secondary networks are included
998             assertThat(latest).hasSize(2)
999             assertThat((latest!![0] as WifiNetworkModel.Active).level).isEqualTo(2)
1000             assertThat((latest!![1] as WifiNetworkModel.Active).level).isEqualTo(3)
1001         }
1002 
1003     @Test
secondaryNetworks_flagOff_noNetworksnull1004     fun secondaryNetworks_flagOff_noNetworks() =
1005         testScope.runTest {
1006             featureFlags.set(Flags.WIFI_SECONDARY_NETWORKS, false)
1007             val latest by collectLastValue(underTest.secondaryNetworks)
1008 
1009             val wifiEntry = mock<WifiEntry>()
1010             whenever(wifiPickerTracker.activeWifiEntries).thenReturn(listOf(wifiEntry))
1011 
1012             getCallback().onWifiEntriesChanged()
1013 
1014             assertThat(latest).isEmpty()
1015         }
1016 
1017     @Test
isWifiConnectedWithValidSsid_inactiveNetwork_falsenull1018     fun isWifiConnectedWithValidSsid_inactiveNetwork_false() =
1019         testScope.runTest {
1020             collectLastValue(underTest.wifiNetwork)
1021 
1022             whenever(wifiPickerTracker.connectedWifiEntry).thenReturn(null)
1023             getCallback().onWifiEntriesChanged()
1024 
1025             assertThat(underTest.isWifiConnectedWithValidSsid()).isFalse()
1026         }
1027 
1028     @Test
isWifiConnectedWithValidSsid_nonPrimaryNetwork_falsenull1029     fun isWifiConnectedWithValidSsid_nonPrimaryNetwork_false() =
1030         testScope.runTest {
1031             collectLastValue(underTest.wifiNetwork)
1032 
1033             val wifiEntry =
1034                 mock<WifiEntry>().apply { whenever(this.isPrimaryNetwork).thenReturn(false) }
1035             whenever(wifiPickerTracker.connectedWifiEntry).thenReturn(wifiEntry)
1036             getCallback().onWifiEntriesChanged()
1037             testScope.runCurrent()
1038 
1039             assertThat(underTest.isWifiConnectedWithValidSsid()).isFalse()
1040         }
1041 
1042     @Test
isWifiConnectedWithValidSsid_carrierMergedNetwork_falsenull1043     fun isWifiConnectedWithValidSsid_carrierMergedNetwork_false() =
1044         testScope.runTest {
1045             collectLastValue(underTest.wifiNetwork)
1046 
1047             val wifiEntry =
1048                 mock<MergedCarrierEntry>().apply {
1049                     whenever(this.isPrimaryNetwork).thenReturn(true)
1050                 }
1051             whenever(wifiPickerTracker.connectedWifiEntry).thenReturn(wifiEntry)
1052             getCallback().onWifiEntriesChanged()
1053             testScope.runCurrent()
1054 
1055             assertThat(underTest.isWifiConnectedWithValidSsid()).isFalse()
1056         }
1057 
1058     @Test
isWifiConnectedWithValidSsid_invalidNetwork_falsenull1059     fun isWifiConnectedWithValidSsid_invalidNetwork_false() =
1060         testScope.runTest {
1061             collectLastValue(underTest.wifiNetwork)
1062 
1063             val wifiEntry =
1064                 mock<MergedCarrierEntry>().apply {
1065                     whenever(this.isPrimaryNetwork).thenReturn(true)
1066                     whenever(this.subscriptionId).thenReturn(INVALID_SUBSCRIPTION_ID)
1067                 }
1068             whenever(wifiPickerTracker.connectedWifiEntry).thenReturn(wifiEntry)
1069             getCallback().onWifiEntriesChanged()
1070             testScope.runCurrent()
1071 
1072             assertThat(underTest.isWifiConnectedWithValidSsid()).isFalse()
1073         }
1074 
1075     @Test
isWifiConnectedWithValidSsid_activeNetwork_nullTitle_falsenull1076     fun isWifiConnectedWithValidSsid_activeNetwork_nullTitle_false() =
1077         testScope.runTest {
1078             collectLastValue(underTest.wifiNetwork)
1079 
1080             val wifiEntry =
1081                 mock<WifiEntry>().apply {
1082                     whenever(this.isPrimaryNetwork).thenReturn(true)
1083                     whenever(this.title).thenReturn(null)
1084                 }
1085             whenever(wifiPickerTracker.connectedWifiEntry).thenReturn(wifiEntry)
1086             getCallback().onWifiEntriesChanged()
1087             testScope.runCurrent()
1088 
1089             assertThat(underTest.isWifiConnectedWithValidSsid()).isFalse()
1090         }
1091 
1092     @Test
isWifiConnectedWithValidSsid_activeNetwork_unknownTitle_falsenull1093     fun isWifiConnectedWithValidSsid_activeNetwork_unknownTitle_false() =
1094         testScope.runTest {
1095             collectLastValue(underTest.wifiNetwork)
1096 
1097             val wifiEntry =
1098                 mock<WifiEntry>().apply {
1099                     whenever(this.isPrimaryNetwork).thenReturn(true)
1100                     whenever(this.title).thenReturn(UNKNOWN_SSID)
1101                 }
1102             whenever(wifiPickerTracker.connectedWifiEntry).thenReturn(wifiEntry)
1103             getCallback().onWifiEntriesChanged()
1104             testScope.runCurrent()
1105 
1106             assertThat(underTest.isWifiConnectedWithValidSsid()).isFalse()
1107         }
1108 
1109     @Test
isWifiConnectedWithValidSsid_activeNetwork_validTitle_truenull1110     fun isWifiConnectedWithValidSsid_activeNetwork_validTitle_true() =
1111         testScope.runTest {
1112             collectLastValue(underTest.wifiNetwork)
1113 
1114             val wifiEntry =
1115                 mock<WifiEntry>().apply {
1116                     whenever(this.isPrimaryNetwork).thenReturn(true)
1117                     whenever(this.title).thenReturn("fakeSsid")
1118                 }
1119             whenever(wifiPickerTracker.connectedWifiEntry).thenReturn(wifiEntry)
1120             getCallback().onWifiEntriesChanged()
1121             testScope.runCurrent()
1122 
1123             assertThat(underTest.isWifiConnectedWithValidSsid()).isTrue()
1124         }
1125 
1126     @Test
isWifiConnectedWithValidSsid_activeToInactive_trueToFalsenull1127     fun isWifiConnectedWithValidSsid_activeToInactive_trueToFalse() =
1128         testScope.runTest {
1129             collectLastValue(underTest.wifiNetwork)
1130 
1131             // Start with active
1132             val wifiEntry =
1133                 mock<WifiEntry>().apply {
1134                     whenever(this.isPrimaryNetwork).thenReturn(true)
1135                     whenever(this.title).thenReturn("fakeSsid")
1136                 }
1137             whenever(wifiPickerTracker.connectedWifiEntry).thenReturn(wifiEntry)
1138             getCallback().onWifiEntriesChanged()
1139             testScope.runCurrent()
1140 
1141             assertThat(underTest.isWifiConnectedWithValidSsid()).isTrue()
1142 
1143             // WHEN the network is lost
1144             whenever(wifiPickerTracker.connectedWifiEntry).thenReturn(null)
1145             getCallback().onWifiEntriesChanged()
1146             testScope.runCurrent()
1147 
1148             // THEN the isWifiConnected updates
1149             assertThat(underTest.isWifiConnectedWithValidSsid()).isFalse()
1150         }
1151 
1152     @Test
wifiActivity_callbackGivesNone_activityFlowHasNonenull1153     fun wifiActivity_callbackGivesNone_activityFlowHasNone() =
1154         testScope.runTest {
1155             val latest by collectLastValue(underTest.wifiActivity)
1156 
1157             getTrafficStateCallback()
1158                 .onStateChanged(WifiManager.TrafficStateCallback.DATA_ACTIVITY_NONE)
1159 
1160             assertThat(latest)
1161                 .isEqualTo(DataActivityModel(hasActivityIn = false, hasActivityOut = false))
1162         }
1163 
1164     @Test
wifiActivity_callbackGivesIn_activityFlowHasInnull1165     fun wifiActivity_callbackGivesIn_activityFlowHasIn() =
1166         testScope.runTest {
1167             val latest by collectLastValue(underTest.wifiActivity)
1168 
1169             getTrafficStateCallback()
1170                 .onStateChanged(WifiManager.TrafficStateCallback.DATA_ACTIVITY_IN)
1171 
1172             assertThat(latest)
1173                 .isEqualTo(DataActivityModel(hasActivityIn = true, hasActivityOut = false))
1174         }
1175 
1176     @Test
wifiActivity_callbackGivesOut_activityFlowHasOutnull1177     fun wifiActivity_callbackGivesOut_activityFlowHasOut() =
1178         testScope.runTest {
1179             val latest by collectLastValue(underTest.wifiActivity)
1180 
1181             getTrafficStateCallback()
1182                 .onStateChanged(WifiManager.TrafficStateCallback.DATA_ACTIVITY_OUT)
1183 
1184             assertThat(latest)
1185                 .isEqualTo(DataActivityModel(hasActivityIn = false, hasActivityOut = true))
1186         }
1187 
1188     @Test
wifiActivity_callbackGivesInout_activityFlowHasInAndOutnull1189     fun wifiActivity_callbackGivesInout_activityFlowHasInAndOut() =
1190         testScope.runTest {
1191             val latest by collectLastValue(underTest.wifiActivity)
1192 
1193             getTrafficStateCallback()
1194                 .onStateChanged(WifiManager.TrafficStateCallback.DATA_ACTIVITY_INOUT)
1195 
1196             assertThat(latest)
1197                 .isEqualTo(DataActivityModel(hasActivityIn = true, hasActivityOut = true))
1198         }
1199 
1200     @Test
wifiScanResults_containsSsidListnull1201     fun wifiScanResults_containsSsidList() =
1202         testScope.runTest {
1203             val latest by collectLastValue(underTest.wifiScanResults)
1204 
1205             val scanResults =
1206                 listOf(
1207                     ScanResult().also { it.SSID = "ssid 1" },
1208                     ScanResult().also { it.SSID = "ssid 2" },
1209                     ScanResult().also { it.SSID = "ssid 3" },
1210                     ScanResult().also { it.SSID = "ssid 4" },
1211                     ScanResult().also { it.SSID = "ssid 5" },
1212                 )
1213             whenever(wifiManager.scanResults).thenReturn(scanResults)
1214             getScanResultsCallback().onScanResultsAvailable()
1215 
1216             val expected =
1217                 listOf(
1218                     WifiScanEntry(ssid = "ssid 1"),
1219                     WifiScanEntry(ssid = "ssid 2"),
1220                     WifiScanEntry(ssid = "ssid 3"),
1221                     WifiScanEntry(ssid = "ssid 4"),
1222                     WifiScanEntry(ssid = "ssid 5"),
1223                 )
1224 
1225             assertThat(latest).isEqualTo(expected)
1226         }
1227 
1228     @Test
wifiScanResults_updatesnull1229     fun wifiScanResults_updates() =
1230         testScope.runTest {
1231             val latest by collectLastValue(underTest.wifiScanResults)
1232 
1233             var scanResults =
1234                 listOf(
1235                     ScanResult().also { it.SSID = "ssid 1" },
1236                     ScanResult().also { it.SSID = "ssid 2" },
1237                     ScanResult().also { it.SSID = "ssid 3" },
1238                     ScanResult().also { it.SSID = "ssid 4" },
1239                     ScanResult().also { it.SSID = "ssid 5" },
1240                 )
1241             whenever(wifiManager.scanResults).thenReturn(scanResults)
1242             getScanResultsCallback().onScanResultsAvailable()
1243 
1244             // New scan representing no results
1245             scanResults = listOf()
1246             whenever(wifiManager.scanResults).thenReturn(scanResults)
1247             getScanResultsCallback().onScanResultsAvailable()
1248 
1249             assertThat(latest).isEmpty()
1250         }
1251 
getCallbacknull1252     private fun getCallback(): WifiPickerTracker.WifiPickerTrackerCallback {
1253         testScope.runCurrent()
1254         return callbackCaptor.value
1255     }
1256 
getTrafficStateCallbacknull1257     private fun getTrafficStateCallback(): WifiManager.TrafficStateCallback {
1258         testScope.runCurrent()
1259         val callbackCaptor = argumentCaptor<WifiManager.TrafficStateCallback>()
1260         verify(wifiManager).registerTrafficStateCallback(any(), callbackCaptor.capture())
1261         return callbackCaptor.value!!
1262     }
1263 
createHotspotWithTypenull1264     private fun createHotspotWithType(@DeviceType type: Int): HotspotNetworkEntry {
1265         return mock<HotspotNetworkEntry>().apply {
1266             whenever(this.isPrimaryNetwork).thenReturn(true)
1267             whenever(this.deviceType).thenReturn(type)
1268         }
1269     }
1270 
getScanResultsCallbacknull1271     private fun getScanResultsCallback(): WifiManager.ScanResultsCallback {
1272         testScope.runCurrent()
1273         val callbackCaptor = argumentCaptor<WifiManager.ScanResultsCallback>()
1274         verify(wifiManager).registerScanResultsCallback(any(), callbackCaptor.capture())
1275         return callbackCaptor.value!!
1276     }
1277 
1278     private companion object {
1279         const val TITLE = "AB"
1280     }
1281 }
1282