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  }