1 /*
2  * Copyright (C) 2020 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.connectivity
18 
19 import android.os.UserManager
20 import android.test.suitebuilder.annotation.SmallTest
21 import android.testing.AndroidTestingRunner
22 import android.testing.TestableLooper.RunWithLooper
23 import androidx.lifecycle.Lifecycle
24 import com.android.systemui.SysuiTestCase
25 import com.android.systemui.settings.UserTracker
26 import com.android.systemui.util.mockito.any
27 import com.android.systemui.util.mockito.capture
28 import com.android.wifitrackerlib.WifiEntry
29 import com.android.wifitrackerlib.WifiPickerTracker
30 import com.google.common.truth.Truth.assertThat
31 import org.junit.Before
32 import org.junit.Test
33 import org.junit.runner.RunWith
34 import org.mockito.ArgumentCaptor
35 import org.mockito.ArgumentMatchers.anyList
36 import org.mockito.Captor
37 import org.mockito.Mock
38 import org.mockito.Mockito.`when`
39 import org.mockito.Mockito.never
40 import org.mockito.Mockito.verify
41 import org.mockito.MockitoAnnotations
42 import java.util.concurrent.Executor
43 
44 @SmallTest
45 @RunWith(AndroidTestingRunner::class)
46 @RunWithLooper(setAsMainLooper = true)
47 class AccessPointControllerImplTest : SysuiTestCase() {
48 
49     @Mock
50     private lateinit var userManager: UserManager
51     @Mock
52     private lateinit var userTracker: UserTracker
53     @Mock
54     private lateinit var wifiPickerTrackerFactory:
55             WifiPickerTrackerFactory
56     @Mock
57     private lateinit var wifiPickerTracker: WifiPickerTracker
58     @Mock
59     private lateinit var callback: AccessPointController.AccessPointCallback
60     @Mock
61     private lateinit var otherCallback: AccessPointController.AccessPointCallback
62     @Mock
63     private lateinit var wifiEntryConnected: WifiEntry
64     @Mock
65     private lateinit var wifiEntryOther: WifiEntry
66     @Captor
67     private lateinit var wifiEntryListCaptor: ArgumentCaptor<List<WifiEntry>>
68 
69     private val instantExecutor = Executor { it.run() }
70     private lateinit var controller: AccessPointControllerImpl
71 
72     @Before
73     fun setUp() {
74         MockitoAnnotations.initMocks(this)
75         `when`(wifiPickerTrackerFactory.create(any(), any())).thenReturn(wifiPickerTracker)
76 
77         `when`(wifiPickerTracker.connectedWifiEntry).thenReturn(wifiEntryConnected)
78         `when`(wifiPickerTracker.wifiEntries).thenReturn(ArrayList<WifiEntry>().apply {
79             add(wifiEntryOther)
80         })
81 
82         controller = AccessPointControllerImpl(
83                 userManager,
84                 userTracker,
85                 instantExecutor,
86                 wifiPickerTrackerFactory
87         )
88 
89         controller.init()
90     }
91 
92     @Test
93     fun testInitialLifecycleStateCreated() {
94         assertThat(controller.lifecycle.currentState).isEqualTo(Lifecycle.State.CREATED)
95     }
96 
97     @Test
98     fun testLifecycleStartedAfterFirstCallback() {
99         controller.addAccessPointCallback(callback)
100         assertThat(controller.lifecycle.currentState).isEqualTo(Lifecycle.State.STARTED)
101     }
102 
103     @Test
104     fun testLifecycleBackToCreatedAfterRemovingOnlyCallback() {
105         controller.addAccessPointCallback(callback)
106         controller.removeAccessPointCallback(callback)
107 
108         assertThat(controller.lifecycle.currentState).isEqualTo(Lifecycle.State.CREATED)
109     }
110 
111     @Test
112     fun testLifecycleStillStartedAfterRemovingSecondCallback() {
113         controller.addAccessPointCallback(callback)
114         controller.addAccessPointCallback(otherCallback)
115         controller.removeAccessPointCallback(callback)
116 
117         assertThat(controller.lifecycle.currentState).isEqualTo(Lifecycle.State.STARTED)
118     }
119 
120     @Test
121     fun testScanForAccessPointsTriggersCallbackWithEntriesInOrder() {
122         controller.addAccessPointCallback(callback)
123         controller.scanForAccessPoints()
124 
125         verify(callback).onAccessPointsChanged(capture(wifiEntryListCaptor))
126 
127         assertThat(wifiEntryListCaptor.value).containsExactly(wifiEntryConnected, wifiEntryOther)
128     }
129 
130     @Test
131     fun testOnWifiStateChangedTriggersCallbackWithEntriesInOrder() {
132         controller.addAccessPointCallback(callback)
133         controller.onWifiStateChanged()
134 
135         verify(callback).onAccessPointsChanged(capture(wifiEntryListCaptor))
136 
137         assertThat(wifiEntryListCaptor.value).containsExactly(wifiEntryConnected, wifiEntryOther)
138     }
139 
140     @Test
141     fun testOnWifiEntriesChangedTriggersCallbackWithEntriesInOrder() {
142         controller.addAccessPointCallback(callback)
143         controller.onWifiEntriesChanged()
144 
145         verify(callback).onAccessPointsChanged(capture(wifiEntryListCaptor))
146 
147         assertThat(wifiEntryListCaptor.value).containsExactly(wifiEntryConnected, wifiEntryOther)
148     }
149 
150     @Test
151     fun testOnNumSavedNetworksChangedDoesntTriggerCallback() {
152         controller.addAccessPointCallback(callback)
153         controller.onNumSavedNetworksChanged()
154 
155         verify(callback, never()).onAccessPointsChanged(anyList())
156     }
157 
158     @Test
159     fun testOnNumSavedSubscriptionsChangedDoesntTriggerCallback() {
160         controller.addAccessPointCallback(callback)
161         controller.onNumSavedSubscriptionsChanged()
162 
163         verify(callback, never()).onAccessPointsChanged(anyList())
164     }
165 
166     @Test
167     fun testReturnEmptyListWhenNoWifiPickerTracker() {
168         `when`(wifiPickerTrackerFactory.create(any(), any())).thenReturn(null)
169         val otherController = AccessPointControllerImpl(
170                 userManager,
171                 userTracker,
172                 instantExecutor,
173                 wifiPickerTrackerFactory
174         )
175         otherController.init()
176 
177         otherController.addAccessPointCallback(callback)
178         otherController.scanForAccessPoints()
179 
180         verify(callback).onAccessPointsChanged(capture(wifiEntryListCaptor))
181 
182         assertThat(wifiEntryListCaptor.value).isEmpty()
183     }
184 
185     @Test
186     fun connectToNullEntry() {
187         controller.addAccessPointCallback(callback)
188 
189         assertThat(controller.connect(null)).isFalse()
190 
191         verify(callback, never()).onSettingsActivityTriggered(any())
192     }
193 
194     @Test
195     fun connectToSavedWifiEntry() {
196         controller.addAccessPointCallback(callback)
197         `when`(wifiEntryOther.isSaved).thenReturn(true)
198 
199         assertThat(controller.connect(wifiEntryOther)).isFalse()
200 
201         verify(wifiEntryOther).connect(any())
202         verify(callback, never()).onSettingsActivityTriggered(any())
203     }
204 
205     @Test
206     fun connectToSecuredNotSavedWifiEntry() {
207         controller.addAccessPointCallback(callback)
208         `when`(wifiEntryOther.isSaved).thenReturn(false)
209         `when`(wifiEntryOther.security).thenReturn(WifiEntry.SECURITY_EAP)
210 
211         // True means we will launch WifiSettings
212         assertThat(controller.connect(wifiEntryOther)).isTrue()
213 
214         verify(wifiEntryOther, never()).connect(any())
215         verify(callback).onSettingsActivityTriggered(any())
216     }
217 
218     @Test
219     fun connectToNotSecuredNotSavedWifiEntry() {
220         controller.addAccessPointCallback(callback)
221         `when`(wifiEntryOther.isSaved).thenReturn(false)
222         `when`(wifiEntryOther.security).thenReturn(WifiEntry.SECURITY_NONE)
223 
224         assertThat(controller.connect(wifiEntryOther)).isFalse()
225 
226         verify(wifiEntryOther).connect(any())
227         verify(callback, never()).onSettingsActivityTriggered(any())
228     }
229 }