blob: 3d01f6bce565611b1ac5f5b547b5a3c44395c8b4 [file] [log] [blame]
Ajay Nadathur7d176bc2016-10-24 16:55:24 -07001/*
2 * Copyright (C) 2016 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 */
16package com.android.settingslib.wifi;
17
Sundeep Ghuman2b489902017-02-22 18:17:29 -080018import static com.google.common.truth.Truth.assertThat;
19
Sundeep Ghuman5519b7b2016-12-14 17:53:31 -080020import static org.junit.Assert.assertEquals;
Stephen Chen21f68682017-04-04 13:23:31 -070021import static org.junit.Assert.assertFalse;
Ajay Nadathur7d176bc2016-10-24 16:55:24 -070022import static org.junit.Assert.assertTrue;
Sundeep Ghuman71f4a822017-04-18 19:51:46 -070023import static org.junit.Assert.fail;
Peter Qiuf5628382017-03-28 13:24:34 -070024import static org.mockito.Mockito.any;
Sundeep Ghuman5519b7b2016-12-14 17:53:31 -080025import static org.mockito.Mockito.anyInt;
Sundeep Ghuman71f4a822017-04-18 19:51:46 -070026import static org.mockito.Mockito.atMost;
Sundeep Ghuman5519b7b2016-12-14 17:53:31 -080027import static org.mockito.Mockito.doAnswer;
28import static org.mockito.Mockito.doNothing;
Peter Qiuf5628382017-03-28 13:24:34 -070029import static org.mockito.Mockito.doThrow;
Sundeep Ghumance6bab82017-04-19 16:21:46 -070030import static org.mockito.Mockito.mock;
Sundeep Ghumand4a79ac2017-06-07 18:11:39 -070031import static org.mockito.Mockito.never;
Sundeep Ghumance6bab82017-04-19 16:21:46 -070032import static org.mockito.Mockito.times;
Sundeep Ghuman5519b7b2016-12-14 17:53:31 -080033import static org.mockito.Mockito.verify;
Sundeep Ghuman71f4a822017-04-18 19:51:46 -070034import static org.mockito.Mockito.verifyNoMoreInteractions;
Sundeep Ghuman5519b7b2016-12-14 17:53:31 -080035import static org.mockito.Mockito.when;
36
37import android.content.Context;
38import android.content.Intent;
Eric Schwarzenbach5e0535e2017-08-16 15:47:33 -070039import android.content.IntentFilter;
Sundeep Ghuman5519b7b2016-12-14 17:53:31 -080040import android.net.ConnectivityManager;
Sundeep Ghuman9c0b97e2017-04-13 16:05:46 -070041import android.net.Network;
Sundeep Ghuman2b489902017-02-22 18:17:29 -080042import android.net.NetworkInfo;
Sundeep Ghuman5519b7b2016-12-14 17:53:31 -080043import android.net.NetworkKey;
44import android.net.NetworkScoreManager;
Sundeep Ghuman5519b7b2016-12-14 17:53:31 -080045import android.net.RssiCurve;
Sundeep Ghuman9c0b97e2017-04-13 16:05:46 -070046import android.net.ScoredNetwork;
Sundeep Ghuman5519b7b2016-12-14 17:53:31 -080047import android.net.WifiKey;
Ajay Nadathur7d176bc2016-10-24 16:55:24 -070048import android.net.wifi.ScanResult;
49import android.net.wifi.WifiConfiguration;
Sundeep Ghuman2b489902017-02-22 18:17:29 -080050import android.net.wifi.WifiInfo;
Sundeep Ghuman5519b7b2016-12-14 17:53:31 -080051import android.net.wifi.WifiManager;
52import android.net.wifi.WifiNetworkScoreCache;
53import android.net.wifi.WifiSsid;
54import android.os.Bundle;
Sundeep Ghuman5519b7b2016-12-14 17:53:31 -080055import android.os.Handler;
56import android.os.HandlerThread;
57import android.os.Looper;
Sundeep Ghuman9c0b97e2017-04-13 16:05:46 -070058import android.os.SystemClock;
Sundeep Ghuman5519b7b2016-12-14 17:53:31 -080059import android.provider.Settings;
Ajay Nadathur7d176bc2016-10-24 16:55:24 -070060import android.support.test.InstrumentationRegistry;
61import android.support.test.filters.SmallTest;
62import android.support.test.runner.AndroidJUnit4;
Sundeep Ghuman266b4092017-06-16 15:12:56 -070063import android.support.test.filters.FlakyTest;
Ajay Nadathur7d176bc2016-10-24 16:55:24 -070064
Sundeep Ghuman5519b7b2016-12-14 17:53:31 -080065import org.junit.After;
66import org.junit.Before;
Ajay Nadathur7d176bc2016-10-24 16:55:24 -070067import org.junit.Test;
68import org.junit.runner.RunWith;
Sundeep Ghuman5519b7b2016-12-14 17:53:31 -080069import org.mockito.ArgumentCaptor;
Sundeep Ghuman5519b7b2016-12-14 17:53:31 -080070import org.mockito.Captor;
Sundeep Ghuman9c0b97e2017-04-13 16:05:46 -070071import org.mockito.Matchers;
Sundeep Ghuman5519b7b2016-12-14 17:53:31 -080072import org.mockito.Mock;
73import org.mockito.MockitoAnnotations;
74import org.mockito.invocation.InvocationOnMock;
75import org.mockito.stubbing.Answer;
76
Ajay Nadathur7d176bc2016-10-24 16:55:24 -070077import java.util.ArrayList;
78import java.util.Arrays;
79import java.util.BitSet;
80import java.util.List;
Sundeep Ghuman5519b7b2016-12-14 17:53:31 -080081import java.util.concurrent.CountDownLatch;
82import java.util.concurrent.TimeUnit;
Ajay Nadathur7d176bc2016-10-24 16:55:24 -070083
Sundeep Ghuman2b489902017-02-22 18:17:29 -080084// TODO(sghuman): Change these to robolectric tests b/35766684.
85
Ajay Nadathur7d176bc2016-10-24 16:55:24 -070086@SmallTest
87@RunWith(AndroidJUnit4.class)
88public class WifiTrackerTest {
89
Sundeep Ghuman5519b7b2016-12-14 17:53:31 -080090 private static final String TAG = "WifiTrackerTest";
Sundeep Ghumanac7b4362017-02-08 17:19:27 -080091 private static final int LATCH_TIMEOUT = 4000;
Sundeep Ghuman5519b7b2016-12-14 17:53:31 -080092
93 private static final String SSID_1 = "ssid1";
94 private static final String BSSID_1 = "00:00:00:00:00:00";
95 private static final NetworkKey NETWORK_KEY_1 =
96 new NetworkKey(new WifiKey('"' + SSID_1 + '"', BSSID_1));
97 private static final int RSSI_1 = -30;
98 private static final byte SCORE_1 = 10;
Sundeep Ghuman53200ed2017-06-21 16:54:36 -070099 private static final int BADGE_1 = AccessPoint.Speed.MODERATE;
Sundeep Ghuman5519b7b2016-12-14 17:53:31 -0800100
101 private static final String SSID_2 = "ssid2";
102 private static final String BSSID_2 = "AA:AA:AA:AA:AA:AA";
103 private static final NetworkKey NETWORK_KEY_2 =
104 new NetworkKey(new WifiKey('"' + SSID_2 + '"', BSSID_2));
105 private static final int RSSI_2 = -30;
106 private static final byte SCORE_2 = 15;
Sundeep Ghuman53200ed2017-06-21 16:54:36 -0700107 private static final int BADGE_2 = AccessPoint.Speed.FAST;
Sundeep Ghuman5519b7b2016-12-14 17:53:31 -0800108
Sundeep Ghuman8c792882017-04-04 17:23:29 -0700109 private static final int CONNECTED_NETWORK_ID = 123;
110 private static final int CONNECTED_RSSI = -50;
111 private static final WifiInfo CONNECTED_AP_1_INFO = new WifiInfo();
112 static {
113 CONNECTED_AP_1_INFO.setSSID(WifiSsid.createFromAsciiEncoded(SSID_1));
114 CONNECTED_AP_1_INFO.setBSSID(BSSID_1);
115 CONNECTED_AP_1_INFO.setNetworkId(CONNECTED_NETWORK_ID);
116 CONNECTED_AP_1_INFO.setRssi(CONNECTED_RSSI);
117 }
118
Sundeep Ghuman5519b7b2016-12-14 17:53:31 -0800119 @Captor ArgumentCaptor<WifiNetworkScoreCache> mScoreCacheCaptor;
120 @Mock private ConnectivityManager mockConnectivityManager;
121 @Mock private NetworkScoreManager mockNetworkScoreManager;
122 @Mock private RssiCurve mockCurve1;
123 @Mock private RssiCurve mockCurve2;
124 @Mock private RssiCurve mockBadgeCurve1;
125 @Mock private RssiCurve mockBadgeCurve2;
126 @Mock private WifiManager mockWifiManager;
127 @Mock private WifiTracker.WifiListener mockWifiListener;
128
129 private final List<NetworkKey> mRequestedKeys = new ArrayList<>();
130
131 private Context mContext;
132 private CountDownLatch mAccessPointsChangedLatch;
133 private CountDownLatch mRequestScoresLatch;
134 private Handler mScannerHandler;
135 private HandlerThread mMainThread;
136 private HandlerThread mWorkerThread;
Sundeep Ghuman71f4a822017-04-18 19:51:46 -0700137 private Looper mWorkerLooper;
Sundeep Ghuman5519b7b2016-12-14 17:53:31 -0800138 private Looper mMainLooper;
Sundeep Ghuman42058742017-07-21 18:42:10 -0700139
Sundeep Ghumane869d832017-01-25 16:23:43 -0800140 private int mOriginalScoringUiSettingValue;
Sundeep Ghuman5519b7b2016-12-14 17:53:31 -0800141
142 @Before
143 public void setUp() {
Sundeep Ghuman5519b7b2016-12-14 17:53:31 -0800144 MockitoAnnotations.initMocks(this);
145
Sundeep Ghuman2b489902017-02-22 18:17:29 -0800146 mContext = InstrumentationRegistry.getTargetContext();
147
Sundeep Ghuman5519b7b2016-12-14 17:53:31 -0800148 mWorkerThread = new HandlerThread("TestHandlerWorkerThread");
149 mWorkerThread.start();
Sundeep Ghuman71f4a822017-04-18 19:51:46 -0700150 mWorkerLooper = mWorkerThread.getLooper();
Sundeep Ghuman5519b7b2016-12-14 17:53:31 -0800151 mMainThread = new HandlerThread("TestHandlerThread");
152 mMainThread.start();
153 mMainLooper = mMainThread.getLooper();
154
155 // Make sure the scanner doesn't try to run on the testing thread.
156 HandlerThread scannerThread = new HandlerThread("ScannerWorkerThread");
157 scannerThread.start();
158 mScannerHandler = new Handler(scannerThread.getLooper());
159
160 when(mockWifiManager.isWifiEnabled()).thenReturn(true);
161 when(mockWifiManager.getScanResults())
162 .thenReturn(Arrays.asList(buildScanResult1(), buildScanResult2()));
163
164
165 when(mockCurve1.lookupScore(RSSI_1)).thenReturn(SCORE_1);
166 when(mockCurve2.lookupScore(RSSI_2)).thenReturn(SCORE_2);
167
168 when(mockBadgeCurve1.lookupScore(RSSI_1)).thenReturn((byte) BADGE_1);
169 when(mockBadgeCurve2.lookupScore(RSSI_2)).thenReturn((byte) BADGE_2);
170
171 doNothing()
172 .when(mockNetworkScoreManager)
173 .registerNetworkScoreCache(
174 anyInt(),
175 mScoreCacheCaptor.capture(),
176 Matchers.anyInt());
177
178 // Capture requested keys and count down latch if present
179 doAnswer(
180 new Answer<Boolean>() {
181 @Override
182 public Boolean answer(InvocationOnMock input) {
183 if (mRequestScoresLatch != null) {
184 mRequestScoresLatch.countDown();
185 }
186 NetworkKey[] keys = (NetworkKey[]) input.getArguments()[0];
187 for (NetworkKey key : keys) {
188 mRequestedKeys.add(key);
189 }
190 return true;
191 }
192 }).when(mockNetworkScoreManager).requestScores(Matchers.<NetworkKey[]>any());
193
194 doAnswer(
195 new Answer<Void>() {
196 @Override
197 public Void answer (InvocationOnMock invocation) throws Throwable {
198 if (mAccessPointsChangedLatch != null) {
199 mAccessPointsChangedLatch.countDown();
200 }
201
202 return null;
203 }
204 }).when(mockWifiListener).onAccessPointsChanged();
205
Sundeep Ghumane869d832017-01-25 16:23:43 -0800206 // Turn on Scoring UI features
207 mOriginalScoringUiSettingValue = Settings.Global.getInt(
208 InstrumentationRegistry.getTargetContext().getContentResolver(),
209 Settings.Global.NETWORK_SCORING_UI_ENABLED,
210 0 /* disabled */);
211 Settings.Global.putInt(
212 InstrumentationRegistry.getTargetContext().getContentResolver(),
213 Settings.Global.NETWORK_SCORING_UI_ENABLED,
214 1 /* enabled */);
Sundeep Ghuman42058742017-07-21 18:42:10 -0700215
Sundeep Ghuman5519b7b2016-12-14 17:53:31 -0800216 }
217
218 @After
219 public void cleanUp() {
220 Settings.Global.putInt(
Sundeep Ghumane869d832017-01-25 16:23:43 -0800221 InstrumentationRegistry.getTargetContext().getContentResolver(),
222 Settings.Global.NETWORK_SCORING_UI_ENABLED,
223 mOriginalScoringUiSettingValue);
Sundeep Ghuman5519b7b2016-12-14 17:53:31 -0800224 }
225
226 private static ScanResult buildScanResult1() {
227 return new ScanResult(
228 WifiSsid.createFromAsciiEncoded(SSID_1),
229 BSSID_1,
230 0, // hessid
231 0, //anqpDomainId
232 null, // osuProviders
233 "", // capabilities
234 RSSI_1,
235 0, // frequency
236 SystemClock.elapsedRealtime() * 1000 /* microsecond timestamp */);
237 }
238
239 private static ScanResult buildScanResult2() {
240 return new ScanResult(
241 WifiSsid.createFromAsciiEncoded(SSID_2),
242 BSSID_2,
243 0, // hessid
244 0, //anqpDomainId
245 null, // osuProviders
246 "", // capabilities
247 RSSI_2,
248 0, // frequency
249 SystemClock.elapsedRealtime() * 1000 /* microsecond timestamp */);
250 }
251
Sundeep Ghuman2b489902017-02-22 18:17:29 -0800252 private WifiTracker createTrackerWithImmediateBroadcastsAndInjectInitialScanResults(
253 Intent ... intents)
254 throws InterruptedException {
Sundeep Ghuman5519b7b2016-12-14 17:53:31 -0800255 WifiTracker tracker = createMockedWifiTracker();
Sundeep Ghuman2b489902017-02-22 18:17:29 -0800256
Sundeep Ghuman5519b7b2016-12-14 17:53:31 -0800257 startTracking(tracker);
Sundeep Ghuman2b489902017-02-22 18:17:29 -0800258 for (Intent intent : intents) {
259 tracker.mReceiver.onReceive(mContext, intent);
260 }
Sundeep Ghuman5519b7b2016-12-14 17:53:31 -0800261
Sundeep Ghuman5519b7b2016-12-14 17:53:31 -0800262 sendScanResultsAndProcess(tracker);
Sundeep Ghumane8013092017-06-21 22:35:30 -0700263 waitForHandlersToProcessCurrentlyEnqueuedMessages(tracker);
Sundeep Ghuman5519b7b2016-12-14 17:53:31 -0800264
265 return tracker;
266 }
267
268 private WifiTracker createMockedWifiTracker() {
Eric Schwarzenbach5e0535e2017-08-16 15:47:33 -0700269 return new WifiTracker(
270 mContext,
271 mockWifiListener,
272 mWorkerLooper,
273 true,
274 true,
275 true,
276 mockWifiManager,
277 mockConnectivityManager,
278 mockNetworkScoreManager,
279 mMainLooper,
280 new IntentFilter()); // empty filter to ignore system broadcasts
Sundeep Ghuman5519b7b2016-12-14 17:53:31 -0800281 }
282
283 private void startTracking(WifiTracker tracker) throws InterruptedException {
284 CountDownLatch latch = new CountDownLatch(1);
285 mScannerHandler.post(new Runnable() {
286 @Override
287 public void run() {
288 tracker.startTracking();
289 latch.countDown();
290 }
291 });
Sundeep Ghumanac7b4362017-02-08 17:19:27 -0800292 assertTrue("Latch timed out", latch.await(LATCH_TIMEOUT, TimeUnit.MILLISECONDS));
Sundeep Ghuman5519b7b2016-12-14 17:53:31 -0800293 }
294
295 private void sendScanResultsAndProcess(WifiTracker tracker) throws InterruptedException {
296 mAccessPointsChangedLatch = new CountDownLatch(1);
297 Intent i = new Intent(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION);
298 tracker.mReceiver.onReceive(mContext, i);
299
Sundeep Ghumanac7b4362017-02-08 17:19:27 -0800300 assertTrue("Latch timed out",
301 mAccessPointsChangedLatch.await(LATCH_TIMEOUT, TimeUnit.MILLISECONDS));
Sundeep Ghuman5519b7b2016-12-14 17:53:31 -0800302 }
303
304 private void updateScores() {
305 Bundle attr1 = new Bundle();
306 attr1.putParcelable(ScoredNetwork.ATTRIBUTES_KEY_BADGING_CURVE, mockBadgeCurve1);
307 ScoredNetwork sc1 =
308 new ScoredNetwork(
309 NETWORK_KEY_1,
310 mockCurve1,
311 false /* meteredHint */,
312 attr1);
313
314 Bundle attr2 = new Bundle();
315 attr2.putParcelable(ScoredNetwork.ATTRIBUTES_KEY_BADGING_CURVE, mockBadgeCurve2);
316 ScoredNetwork sc2 =
317 new ScoredNetwork(
318 NETWORK_KEY_2,
319 mockCurve2,
Stephen Chen21f68682017-04-04 13:23:31 -0700320 true /* meteredHint */,
Sundeep Ghuman5519b7b2016-12-14 17:53:31 -0800321 attr2);
322
323 WifiNetworkScoreCache scoreCache = mScoreCacheCaptor.getValue();
324 scoreCache.updateScores(Arrays.asList(sc1, sc2));
325 }
326
Sundeep Ghuman2b489902017-02-22 18:17:29 -0800327 private WifiTracker createTrackerWithScanResultsAndAccessPoint1Connected()
328 throws InterruptedException {
Sundeep Ghuman8c792882017-04-04 17:23:29 -0700329 when(mockWifiManager.getConnectionInfo()).thenReturn(CONNECTED_AP_1_INFO);
Sundeep Ghuman2b489902017-02-22 18:17:29 -0800330
331 WifiConfiguration configuration = new WifiConfiguration();
332 configuration.SSID = SSID_1;
333 configuration.BSSID = BSSID_1;
Sundeep Ghuman8c792882017-04-04 17:23:29 -0700334 configuration.networkId = CONNECTED_NETWORK_ID;
Sundeep Ghuman2b489902017-02-22 18:17:29 -0800335 when(mockWifiManager.getConfiguredNetworks()).thenReturn(Arrays.asList(configuration));
336
337 NetworkInfo networkInfo = new NetworkInfo(
338 ConnectivityManager.TYPE_WIFI, 0, "Type Wifi", "subtype");
339 networkInfo.setDetailedState(NetworkInfo.DetailedState.CONNECTED, "connected", "test");
340
341 Intent intent = new Intent(WifiManager.NETWORK_STATE_CHANGED_ACTION);
342 intent.putExtra(WifiManager.EXTRA_NETWORK_INFO, networkInfo);
Sundeep Ghumandb2eabb2017-07-28 14:51:05 -0700343 WifiTracker tracker =
344 createTrackerWithImmediateBroadcastsAndInjectInitialScanResults(intent);
345 assertThat(tracker.isConnected()).isTrue();
346 return tracker;
Sundeep Ghuman2b489902017-02-22 18:17:29 -0800347 }
348
Sundeep Ghumane8013092017-06-21 22:35:30 -0700349 private void waitForHandlersToProcessCurrentlyEnqueuedMessages(WifiTracker tracker)
350 throws InterruptedException {
351 CountDownLatch workerLatch = new CountDownLatch(1);
352 tracker.mWorkHandler.post(() -> {
353 workerLatch.countDown();
354 });
355 assertTrue("Latch timed out while waiting for WorkerHandler",
356 workerLatch.await(LATCH_TIMEOUT, TimeUnit.MILLISECONDS));
357
358 CountDownLatch mainLatch = new CountDownLatch(1);
359 tracker.mMainHandler.post(() -> {
360 mainLatch.countDown();
361 });
362 assertTrue("Latch timed out while waiting for MainHandler",
363 mainLatch.await(LATCH_TIMEOUT, TimeUnit.MILLISECONDS));
364 }
365
Ajay Nadathur7d176bc2016-10-24 16:55:24 -0700366 @Test
367 public void testAccessPointListenerSetWhenLookingUpUsingScanResults() {
368 ScanResult scanResult = new ScanResult();
369 scanResult.level = 123;
370 scanResult.BSSID = "bssid-" + 111;
371 scanResult.timestamp = SystemClock.elapsedRealtime() * 1000;
372 scanResult.capabilities = "";
373
374 WifiTracker tracker = new WifiTracker(
Sundeep Ghuman71f4a822017-04-18 19:51:46 -0700375 InstrumentationRegistry.getTargetContext(), null, mWorkerLooper, true, true);
Ajay Nadathur7d176bc2016-10-24 16:55:24 -0700376
377 AccessPoint result = tracker.getCachedOrCreate(scanResult, new ArrayList<AccessPoint>());
378 assertTrue(result.mAccessPointListener != null);
379 }
380
381 @Test
382 public void testAccessPointListenerSetWhenLookingUpUsingWifiConfiguration() {
383 WifiConfiguration configuration = new WifiConfiguration();
384 configuration.SSID = "test123";
385 configuration.BSSID="bssid";
386 configuration.networkId = 123;
387 configuration.allowedKeyManagement = new BitSet();
388 configuration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
389
390 WifiTracker tracker = new WifiTracker(
Sundeep Ghuman71f4a822017-04-18 19:51:46 -0700391 InstrumentationRegistry.getTargetContext(), null, mWorkerLooper, true, true);
Ajay Nadathur7d176bc2016-10-24 16:55:24 -0700392
393 AccessPoint result = tracker.getCachedOrCreate(configuration, new ArrayList<AccessPoint>());
394 assertTrue(result.mAccessPointListener != null);
395 }
Sundeep Ghuman5519b7b2016-12-14 17:53:31 -0800396
397 @Test
398 public void startAndStopTrackingShouldRegisterAndUnregisterScoreCache()
399 throws InterruptedException {
400 WifiTracker tracker = createMockedWifiTracker();
401
402 // Test register
403 startTracking(tracker);
404 verify(mockNetworkScoreManager)
405 .registerNetworkScoreCache(
406 Matchers.anyInt(),
407 mScoreCacheCaptor.capture(),
408 Matchers.anyInt());
409
410 WifiNetworkScoreCache scoreCache = mScoreCacheCaptor.getValue();
411
Sundeep Ghumane869d832017-01-25 16:23:43 -0800412 CountDownLatch latch = new CountDownLatch(1);
413 doAnswer(
414 (invocation) -> {
415 latch.countDown();
416 return null;
417 }).when(mockNetworkScoreManager)
418 .unregisterNetworkScoreCache(NetworkKey.TYPE_WIFI, scoreCache);
419
Sundeep Ghuman5519b7b2016-12-14 17:53:31 -0800420 // Test unregister
421 tracker.stopTracking();
422
Sundeep Ghumanac7b4362017-02-08 17:19:27 -0800423 assertTrue("Latch timed out", latch.await(LATCH_TIMEOUT, TimeUnit.MILLISECONDS));
Sundeep Ghuman5519b7b2016-12-14 17:53:31 -0800424 verify(mockNetworkScoreManager)
425 .unregisterNetworkScoreCache(NetworkKey.TYPE_WIFI, scoreCache);
426 }
427
428 @Test
Amin Shaikha80ae0c2017-03-23 16:18:30 -0700429 public void testGetNumSavedNetworks() throws InterruptedException {
430 WifiConfiguration validConfig = new WifiConfiguration();
431 validConfig.SSID = SSID_1;
432 validConfig.BSSID = BSSID_1;
433
434 WifiConfiguration selfAddedNoAssociation = new WifiConfiguration();
Peter Qiuabea7262017-05-31 10:18:17 -0700435 selfAddedNoAssociation.ephemeral = true;
Amin Shaikha80ae0c2017-03-23 16:18:30 -0700436 selfAddedNoAssociation.selfAdded = true;
437 selfAddedNoAssociation.numAssociation = 0;
438 selfAddedNoAssociation.SSID = SSID_2;
439 selfAddedNoAssociation.BSSID = BSSID_2;
440
441 when(mockWifiManager.getConfiguredNetworks())
442 .thenReturn(Arrays.asList(validConfig, selfAddedNoAssociation));
443
444 WifiTracker tracker = createTrackerWithImmediateBroadcastsAndInjectInitialScanResults();
445
446 assertEquals(1, tracker.getNumSavedNetworks());
447 }
448
449 @Test
Sundeep Ghuman2b489902017-02-22 18:17:29 -0800450 public void startTrackingShouldSetConnectedAccessPointAsActive() throws InterruptedException {
Sundeep Ghumane8013092017-06-21 22:35:30 -0700451 WifiTracker tracker = createTrackerWithScanResultsAndAccessPoint1Connected();
Sundeep Ghuman2b489902017-02-22 18:17:29 -0800452
453 List<AccessPoint> aps = tracker.getAccessPoints();
454
455 assertThat(aps).hasSize(2);
456 assertThat(aps.get(0).isActive()).isTrue();
457 }
458
459 @Test
Sundeep Ghuman71f4a822017-04-18 19:51:46 -0700460 public void startTrackingAfterStopTracking_shouldRequestNewScores()
461 throws InterruptedException {
Sundeep Ghuman5519b7b2016-12-14 17:53:31 -0800462 // Start the tracker and inject the initial scan results and then stop tracking
Sundeep Ghuman2b489902017-02-22 18:17:29 -0800463 WifiTracker tracker = createTrackerWithImmediateBroadcastsAndInjectInitialScanResults();
Sundeep Ghuman5519b7b2016-12-14 17:53:31 -0800464
465 tracker.stopTracking();
466 mRequestedKeys.clear();
467
Sundeep Ghumanac7b4362017-02-08 17:19:27 -0800468 mRequestScoresLatch = new CountDownLatch(1);
Sundeep Ghuman5519b7b2016-12-14 17:53:31 -0800469 startTracking(tracker);
Sundeep Ghuman71f4a822017-04-18 19:51:46 -0700470 tracker.forceUpdate();
Sundeep Ghumanac7b4362017-02-08 17:19:27 -0800471 assertTrue("Latch timed out",
472 mRequestScoresLatch.await(LATCH_TIMEOUT, TimeUnit.MILLISECONDS));
Sundeep Ghuman5519b7b2016-12-14 17:53:31 -0800473
474 assertTrue(mRequestedKeys.contains(NETWORK_KEY_1));
475 assertTrue(mRequestedKeys.contains(NETWORK_KEY_2));
476 }
477
478 @Test
Sundeep Ghuman75f94802017-06-26 16:05:40 -0700479 public void stopTracking_shouldNotClearExistingScores()
480 throws InterruptedException {
481 // Start the tracker and inject the initial scan results and then stop tracking
482 WifiTracker tracker = createTrackerWithImmediateBroadcastsAndInjectInitialScanResults();
483 updateScoresAndWaitForAccessPointsChangedCallback(tracker);
484 tracker.stopTracking();
485
486 assertThat(mScoreCacheCaptor.getValue().getScoredNetwork(NETWORK_KEY_1)).isNotNull();
487 }
488
489 @Test
Sundeep Ghuman8c792882017-04-04 17:23:29 -0700490 public void scoreCacheUpdateScoresShouldTriggerOnAccessPointsChanged()
491 throws InterruptedException {
Sundeep Ghuman5519b7b2016-12-14 17:53:31 -0800492 WifiTracker tracker = createMockedWifiTracker();
493 startTracking(tracker);
494 sendScanResultsAndProcess(tracker);
495
Sundeep Ghumane8013092017-06-21 22:35:30 -0700496 updateScoresAndWaitForAccessPointsChangedCallback(tracker);
Sundeep Ghuman5519b7b2016-12-14 17:53:31 -0800497 }
498
Sundeep Ghumane8013092017-06-21 22:35:30 -0700499 private void updateScoresAndWaitForAccessPointsChangedCallback(WifiTracker tracker)
500 throws InterruptedException {
Sundeep Ghumanac7b4362017-02-08 17:19:27 -0800501 // Updating scores can happen together or one after the other, so the latch countdown is set
502 // to 2.
Sundeep Ghumane8013092017-06-21 22:35:30 -0700503 mAccessPointsChangedLatch = new CountDownLatch(1);
Sundeep Ghuman5519b7b2016-12-14 17:53:31 -0800504 updateScores();
Sundeep Ghumane8013092017-06-21 22:35:30 -0700505 assertTrue("onAccessPointChanged was not called after updating scores",
Sundeep Ghumance6bab82017-04-19 16:21:46 -0700506 mAccessPointsChangedLatch.await(LATCH_TIMEOUT, TimeUnit.MILLISECONDS));
Sundeep Ghumane8013092017-06-21 22:35:30 -0700507 waitForHandlersToProcessCurrentlyEnqueuedMessages(tracker);
Sundeep Ghuman5519b7b2016-12-14 17:53:31 -0800508 }
509
Sundeep Ghuman266b4092017-06-16 15:12:56 -0700510 @FlakyTest
Sundeep Ghuman5519b7b2016-12-14 17:53:31 -0800511 @Test
512 public void scoreCacheUpdateScoresShouldChangeSortOrder() throws InterruptedException {
Sundeep Ghuman8c792882017-04-04 17:23:29 -0700513 WifiTracker tracker = createTrackerWithImmediateBroadcastsAndInjectInitialScanResults();
Sundeep Ghuman5519b7b2016-12-14 17:53:31 -0800514 List<AccessPoint> aps = tracker.getAccessPoints();
515 assertTrue(aps.size() == 2);
516 assertEquals(aps.get(0).getSsidStr(), SSID_1);
517 assertEquals(aps.get(1).getSsidStr(), SSID_2);
518
Sundeep Ghumane8013092017-06-21 22:35:30 -0700519 updateScoresAndWaitForAccessPointsChangedCallback(tracker);
Sundeep Ghuman5519b7b2016-12-14 17:53:31 -0800520
521 aps = tracker.getAccessPoints();
522 assertTrue(aps.size() == 2);
523 assertEquals(aps.get(0).getSsidStr(), SSID_2);
524 assertEquals(aps.get(1).getSsidStr(), SSID_1);
Sundeep Ghumane869d832017-01-25 16:23:43 -0800525 }
Sundeep Ghuman5519b7b2016-12-14 17:53:31 -0800526
Sundeep Ghumane869d832017-01-25 16:23:43 -0800527 @Test
528 public void scoreCacheUpdateScoresShouldNotChangeSortOrderWhenSortingDisabled()
529 throws InterruptedException {
530 Settings.Global.putInt(
531 InstrumentationRegistry.getTargetContext().getContentResolver(),
532 Settings.Global.NETWORK_SCORING_UI_ENABLED,
533 0 /* disabled */);
534
Sundeep Ghuman2b489902017-02-22 18:17:29 -0800535 WifiTracker tracker = createTrackerWithImmediateBroadcastsAndInjectInitialScanResults();
Sundeep Ghumane869d832017-01-25 16:23:43 -0800536 List<AccessPoint> aps = tracker.getAccessPoints();
537 assertTrue(aps.size() == 2);
538 assertEquals(aps.get(0).getSsidStr(), SSID_1);
539 assertEquals(aps.get(1).getSsidStr(), SSID_2);
540
Sundeep Ghumane8013092017-06-21 22:35:30 -0700541 updateScoresAndWaitForAccessPointsChangedCallback(tracker);
Sundeep Ghumane869d832017-01-25 16:23:43 -0800542
543 aps = tracker.getAccessPoints();
544 assertTrue(aps.size() == 2);
545 assertEquals(aps.get(0).getSsidStr(), SSID_1);
546 assertEquals(aps.get(1).getSsidStr(), SSID_2);
Sundeep Ghuman5519b7b2016-12-14 17:53:31 -0800547 }
548
Sundeep Ghuman266b4092017-06-16 15:12:56 -0700549 @FlakyTest
Sundeep Ghuman5519b7b2016-12-14 17:53:31 -0800550 @Test
Sundeep Ghuman55adc6b2017-06-05 16:46:59 -0700551 public void scoreCacheUpdateScoresShouldInsertSpeedIntoAccessPoint()
552 throws InterruptedException {
Sundeep Ghuman2b489902017-02-22 18:17:29 -0800553 WifiTracker tracker = createTrackerWithImmediateBroadcastsAndInjectInitialScanResults();
Sundeep Ghumane8013092017-06-21 22:35:30 -0700554 updateScoresAndWaitForAccessPointsChangedCallback(tracker);
Sundeep Ghuman5519b7b2016-12-14 17:53:31 -0800555
556 List<AccessPoint> aps = tracker.getAccessPoints();
557
558 for (AccessPoint ap : aps) {
559 if (ap.getSsidStr().equals(SSID_1)) {
Sundeep Ghuman55adc6b2017-06-05 16:46:59 -0700560 assertEquals(BADGE_1, ap.getSpeed());
Sundeep Ghuman5519b7b2016-12-14 17:53:31 -0800561 } else if (ap.getSsidStr().equals(SSID_2)) {
Sundeep Ghuman55adc6b2017-06-05 16:46:59 -0700562 assertEquals(BADGE_2, ap.getSpeed());
Sundeep Ghuman5519b7b2016-12-14 17:53:31 -0800563 }
564 }
565 }
566
567 @Test
Stephen Chen21f68682017-04-04 13:23:31 -0700568 public void scoreCacheUpdateMeteredShouldUpdateAccessPointMetering()
569 throws InterruptedException {
570 WifiTracker tracker = createTrackerWithImmediateBroadcastsAndInjectInitialScanResults();
Sundeep Ghumane8013092017-06-21 22:35:30 -0700571 updateScoresAndWaitForAccessPointsChangedCallback(tracker);
Stephen Chen21f68682017-04-04 13:23:31 -0700572
573 List<AccessPoint> aps = tracker.getAccessPoints();
574
575 for (AccessPoint ap : aps) {
576 if (ap.getSsidStr().equals(SSID_1)) {
577 assertFalse(ap.isMetered());
578 } else if (ap.getSsidStr().equals(SSID_2)) {
579 assertTrue(ap.isMetered());
580 }
581 }
582 }
583
584 @Test
Sundeep Ghuman55adc6b2017-06-05 16:46:59 -0700585 public void noSpeedsShouldBeInsertedIntoAccessPointWhenScoringUiDisabled()
Sundeep Ghumane869d832017-01-25 16:23:43 -0800586 throws InterruptedException {
587 Settings.Global.putInt(
588 InstrumentationRegistry.getTargetContext().getContentResolver(),
589 Settings.Global.NETWORK_SCORING_UI_ENABLED,
590 0 /* disabled */);
591
Sundeep Ghuman2b489902017-02-22 18:17:29 -0800592 WifiTracker tracker = createTrackerWithImmediateBroadcastsAndInjectInitialScanResults();
Sundeep Ghumane8013092017-06-21 22:35:30 -0700593 updateScoresAndWaitForAccessPointsChangedCallback(tracker);
Sundeep Ghumane869d832017-01-25 16:23:43 -0800594
595 List<AccessPoint> aps = tracker.getAccessPoints();
596
597 for (AccessPoint ap : aps) {
598 if (ap.getSsidStr().equals(SSID_1)) {
Sundeep Ghuman53200ed2017-06-21 16:54:36 -0700599 assertEquals(AccessPoint.Speed.NONE, ap.getSpeed());
Sundeep Ghumane869d832017-01-25 16:23:43 -0800600 } else if (ap.getSsidStr().equals(SSID_2)) {
Sundeep Ghuman53200ed2017-06-21 16:54:36 -0700601 assertEquals(AccessPoint.Speed.NONE, ap.getSpeed());
Sundeep Ghumane869d832017-01-25 16:23:43 -0800602 }
603 }
604 }
605
606 @Test
Sundeep Ghuman5519b7b2016-12-14 17:53:31 -0800607 public void scoresShouldBeRequestedForNewScanResultOnly() throws InterruptedException {
Sundeep Ghumanac7b4362017-02-08 17:19:27 -0800608 // Scores can be requested together or serially depending on how the scan results are
609 // processed.
Sundeep Ghuman5519b7b2016-12-14 17:53:31 -0800610 mRequestScoresLatch = new CountDownLatch(2);
Sundeep Ghuman2b489902017-02-22 18:17:29 -0800611 WifiTracker tracker = createTrackerWithImmediateBroadcastsAndInjectInitialScanResults();
Sundeep Ghuman5519b7b2016-12-14 17:53:31 -0800612 mRequestScoresLatch.await(LATCH_TIMEOUT, TimeUnit.MILLISECONDS);
613 mRequestedKeys.clear();
614
615 String ssid = "ssid3";
616 String bssid = "00:00:00:00:00:00";
617 ScanResult newResult = new ScanResult(
618 WifiSsid.createFromAsciiEncoded(ssid),
619 bssid,
620 0, // hessid
621 0, //anqpDomainId
622 null, // osuProviders
623 "", // capabilities
624 RSSI_1,
625 0, // frequency
626 SystemClock.elapsedRealtime() * 1000);
627 when(mockWifiManager.getScanResults())
628 .thenReturn(Arrays.asList(buildScanResult1(), buildScanResult2(), newResult));
629
630 mRequestScoresLatch = new CountDownLatch(1);
631 sendScanResultsAndProcess(tracker);
Sundeep Ghumanac7b4362017-02-08 17:19:27 -0800632 assertTrue(mRequestScoresLatch.await(LATCH_TIMEOUT, TimeUnit.MILLISECONDS));
Sundeep Ghuman5519b7b2016-12-14 17:53:31 -0800633
634 assertEquals(1, mRequestedKeys.size());
635 assertTrue(mRequestedKeys.contains(new NetworkKey(new WifiKey('"' + ssid + '"', bssid))));
636 }
Sundeep Ghumanac7b4362017-02-08 17:19:27 -0800637
638 @Test
639 public void scoreCacheAndListenerShouldBeUnregisteredWhenStopTrackingIsCalled() throws Exception
640 {
Sundeep Ghuman2b489902017-02-22 18:17:29 -0800641 WifiTracker tracker = createTrackerWithImmediateBroadcastsAndInjectInitialScanResults();
Sundeep Ghumanac7b4362017-02-08 17:19:27 -0800642 WifiNetworkScoreCache cache = mScoreCacheCaptor.getValue();
643
644 tracker.stopTracking();
645 verify(mockNetworkScoreManager).unregisterNetworkScoreCache(NetworkKey.TYPE_WIFI, cache);
646
647 // Verify listener is unregistered so updating a score does not throw an error by posting
648 // a message to the dead work handler
649 mWorkerThread.quit();
650 updateScores();
651 }
Peter Qiuf5628382017-03-28 13:24:34 -0700652
653 /**
654 * Verify that tracking a Passpoint AP on a device with Passpoint disabled doesn't cause
655 * any crash.
656 *
657 * @throws Exception
658 */
659 @Test
660 public void trackPasspointApWithPasspointDisabled() throws Exception {
661 WifiTracker tracker = createMockedWifiTracker();
662
663 // Add a Passpoint AP to the scan results.
664 List<ScanResult> results = new ArrayList<>();
665 ScanResult passpointAp = new ScanResult(
666 WifiSsid.createFromAsciiEncoded(SSID_1),
667 BSSID_1,
668 0, // hessid
669 0, //anqpDomainId
670 null, // osuProviders
671 "", // capabilities
672 RSSI_1,
673 0, // frequency
674 SystemClock.elapsedRealtime() * 1000 /* microsecond timestamp */);
675 passpointAp.setFlag(ScanResult.FLAG_PASSPOINT_NETWORK);
676 results.add(passpointAp);
677
678 // Update access point and verify UnsupportedOperationException is being caught for
679 // call to WifiManager#getMatchingWifiConfig.
680 when(mockWifiManager.getConfiguredNetworks())
681 .thenReturn(new ArrayList<WifiConfiguration>());
682 when(mockWifiManager.getScanResults()).thenReturn(results);
683 doThrow(new UnsupportedOperationException())
684 .when(mockWifiManager).getMatchingWifiConfig(any(ScanResult.class));
685 tracker.forceUpdate();
686 verify(mockWifiManager).getMatchingWifiConfig(any(ScanResult.class));
687 }
Sundeep Ghuman8c792882017-04-04 17:23:29 -0700688
689 @Test
690 public void rssiChangeBroadcastShouldUpdateConnectedAp() throws Exception {
691 WifiTracker tracker = createTrackerWithScanResultsAndAccessPoint1Connected();
692 assertThat(tracker.getAccessPoints().get(0).isActive()).isTrue();
693
Sundeep Ghuman8c792882017-04-04 17:23:29 -0700694 int newRssi = CONNECTED_RSSI + 10;
695 WifiInfo info = new WifiInfo(CONNECTED_AP_1_INFO);
696 info.setRssi(newRssi);
Sundeep Ghuman8c792882017-04-04 17:23:29 -0700697
Sundeep Ghuman71f4a822017-04-18 19:51:46 -0700698 CountDownLatch latch = new CountDownLatch(1);
699
700 // Once the new info has been fetched, we need to wait for the access points to be copied
701 doAnswer(invocation -> {
702 latch.countDown();
703 mAccessPointsChangedLatch = new CountDownLatch(1);
704 return info;
705 }).when(mockWifiManager).getConnectionInfo();
706
Sundeep Ghuman8c792882017-04-04 17:23:29 -0700707 tracker.mReceiver.onReceive(mContext, new Intent(WifiManager.RSSI_CHANGED_ACTION));
Sundeep Ghuman71f4a822017-04-18 19:51:46 -0700708 assertTrue("New connection info never retrieved",
709 latch.await(LATCH_TIMEOUT, TimeUnit.MILLISECONDS));
710 assertTrue("onAccessPointsChanged never called",
711 mAccessPointsChangedLatch.await(LATCH_TIMEOUT, TimeUnit.MILLISECONDS));
Sundeep Ghuman8c792882017-04-04 17:23:29 -0700712
Sundeep Ghuman8c792882017-04-04 17:23:29 -0700713 assertThat(tracker.getAccessPoints().get(0).getRssi()).isEqualTo(newRssi);
714 }
Sundeep Ghuman9c0b97e2017-04-13 16:05:46 -0700715
716 @Test
717 public void forceUpdateShouldSynchronouslyFetchLatestInformation() throws Exception {
Sundeep Ghumance6bab82017-04-19 16:21:46 -0700718 Network mockNetwork = mock(Network.class);
719 when(mockWifiManager.getCurrentNetwork()).thenReturn(mockNetwork);
Sundeep Ghuman71f4a822017-04-18 19:51:46 -0700720
Sundeep Ghuman9c0b97e2017-04-13 16:05:46 -0700721 when(mockWifiManager.getConnectionInfo()).thenReturn(CONNECTED_AP_1_INFO);
722
723 WifiConfiguration configuration = new WifiConfiguration();
724 configuration.SSID = SSID_1;
725 configuration.BSSID = BSSID_1;
726 configuration.networkId = CONNECTED_NETWORK_ID;
727 when(mockWifiManager.getConfiguredNetworks()).thenReturn(Arrays.asList(configuration));
728
729 NetworkInfo networkInfo = new NetworkInfo(
730 ConnectivityManager.TYPE_WIFI, 0, "Type Wifi", "subtype");
731 networkInfo.setDetailedState(NetworkInfo.DetailedState.CONNECTED, "connected", "test");
732 when(mockConnectivityManager.getNetworkInfo(any(Network.class))).thenReturn(networkInfo);
733
Sundeep Ghuman9c0b97e2017-04-13 16:05:46 -0700734 WifiTracker tracker = createMockedWifiTracker();
Sundeep Ghuman9c0b97e2017-04-13 16:05:46 -0700735 tracker.forceUpdate();
736
Sundeep Ghumance6bab82017-04-19 16:21:46 -0700737 verify(mockWifiManager).getConnectionInfo();
738 verify(mockWifiManager, times(2)).getConfiguredNetworks();
739 verify(mockConnectivityManager).getNetworkInfo(any(Network.class));
740
Sundeep Ghumand2b84a82017-07-05 14:19:30 -0700741 verify(mockWifiListener, never()).onAccessPointsChanged(); // mStaleAccessPoints is true
Sundeep Ghuman9c0b97e2017-04-13 16:05:46 -0700742 assertThat(tracker.getAccessPoints().size()).isEqualTo(2);
743 assertThat(tracker.getAccessPoints().get(0).isActive()).isTrue();
744 }
Sundeep Ghuman71f4a822017-04-18 19:51:46 -0700745
746 @Test
747 public void stopTrackingShouldRemoveWifiListenerCallbacks() throws Exception {
748 WifiTracker tracker = createMockedWifiTracker();
749 startTracking(tracker);
750
751 CountDownLatch latch = new CountDownLatch(1);
752 CountDownLatch lock = new CountDownLatch(1);
753 tracker.mMainHandler.post(() -> {
754 try {
755 lock.await();
756 latch.countDown();
757 } catch (InterruptedException e) {
758 fail("Interrupted Exception while awaiting lock release: " + e);
759 }
760 });
761
762 // Enqueue messages
763 tracker.mMainHandler.sendEmptyMessage(
764 WifiTracker.MainHandler.MSG_ACCESS_POINT_CHANGED);
765 tracker.mMainHandler.sendEmptyMessage(
766 WifiTracker.MainHandler.MSG_CONNECTED_CHANGED);
767 tracker.mMainHandler.sendEmptyMessage(
768 WifiTracker.MainHandler.MSG_WIFI_STATE_CHANGED);
769
770 tracker.stopTracking();
771
772 verify(mockWifiListener, atMost(1)).onAccessPointsChanged();
773 verify(mockWifiListener, atMost(1)).onConnectedChanged();
774 verify(mockWifiListener, atMost(1)).onWifiStateChanged(anyInt());
775
776 lock.countDown();
Sundeep Ghumance6bab82017-04-19 16:21:46 -0700777 assertTrue("Latch timed out", latch.await(LATCH_TIMEOUT, TimeUnit.MILLISECONDS));
Sundeep Ghuman71f4a822017-04-18 19:51:46 -0700778
779 assertThat(tracker.mMainHandler.hasMessages(
780 WifiTracker.MainHandler.MSG_ACCESS_POINT_CHANGED)).isFalse();
781 assertThat(tracker.mMainHandler.hasMessages(
782 WifiTracker.MainHandler.MSG_CONNECTED_CHANGED)).isFalse();
783 assertThat(tracker.mMainHandler.hasMessages(
784 WifiTracker.MainHandler.MSG_WIFI_STATE_CHANGED)).isFalse();
785
786 verifyNoMoreInteractions(mockWifiListener);
787 }
Sundeep Ghumand4a79ac2017-06-07 18:11:39 -0700788
789 @Test
790 public void stopTrackingShouldSetStaleBitWhichPreventsCallbacksUntilNextScanResult()
791 throws Exception {
792 WifiTracker tracker = createMockedWifiTracker();
793 startTracking(tracker);
Sundeep Ghumane8013092017-06-21 22:35:30 -0700794 waitForHandlersToProcessCurrentlyEnqueuedMessages(tracker);
Sundeep Ghumand4a79ac2017-06-07 18:11:39 -0700795
Sundeep Ghumane8013092017-06-21 22:35:30 -0700796 tracker.stopTracking();
797 waitForHandlersToProcessCurrentlyEnqueuedMessages(tracker);
Sundeep Ghumand4a79ac2017-06-07 18:11:39 -0700798
799 startTracking(tracker);
800
801 tracker.mReceiver.onReceive(mContext, new Intent(WifiManager.WIFI_STATE_CHANGED_ACTION));
802 tracker.mReceiver.onReceive(
803 mContext, new Intent(WifiManager.CONFIGURED_NETWORKS_CHANGED_ACTION));
804 tracker.mReceiver.onReceive(
805 mContext, new Intent(WifiManager.LINK_CONFIGURATION_CHANGED_ACTION));
806
Sundeep Ghumane8013092017-06-21 22:35:30 -0700807 waitForHandlersToProcessCurrentlyEnqueuedMessages(tracker);
Sundeep Ghumand4a79ac2017-06-07 18:11:39 -0700808
809 verify(mockWifiListener, never()).onAccessPointsChanged();
810
811 sendScanResultsAndProcess(tracker); // verifies onAccessPointsChanged is invoked
812 }
Sundeep Ghumane8013092017-06-21 22:35:30 -0700813
814 @Test
Sundeep Ghumand2b84a82017-07-05 14:19:30 -0700815 public void startTrackingShouldNotSendAnyCallbacksUntilScanResultsAreProcessed()
816 throws Exception {
817 WifiTracker tracker = createMockedWifiTracker();
818 startTracking(tracker);
819 waitForHandlersToProcessCurrentlyEnqueuedMessages(tracker);
820
821 tracker.mReceiver.onReceive(mContext, new Intent(WifiManager.WIFI_STATE_CHANGED_ACTION));
822 tracker.mReceiver.onReceive(
823 mContext, new Intent(WifiManager.CONFIGURED_NETWORKS_CHANGED_ACTION));
824 tracker.mReceiver.onReceive(
825 mContext, new Intent(WifiManager.LINK_CONFIGURATION_CHANGED_ACTION));
826
827 waitForHandlersToProcessCurrentlyEnqueuedMessages(tracker);
828 verify(mockWifiListener, never()).onAccessPointsChanged();
829
830 sendScanResultsAndProcess(tracker); // verifies onAccessPointsChanged is invoked
831 }
832
833 @Test
Sundeep Ghumane8013092017-06-21 22:35:30 -0700834 public void disablingWifiShouldClearExistingAccessPoints() throws Exception {
835 WifiTracker tracker = createTrackerWithScanResultsAndAccessPoint1Connected();
836
837 when(mockWifiManager.isWifiEnabled()).thenReturn(false);
838 mAccessPointsChangedLatch = new CountDownLatch(1);
839 tracker.mReceiver.onReceive(mContext, new Intent(WifiManager.WIFI_STATE_CHANGED_ACTION));
840
841 mAccessPointsChangedLatch.await(LATCH_TIMEOUT, TimeUnit.MILLISECONDS);
842 waitForHandlersToProcessCurrentlyEnqueuedMessages(tracker);
843
844 assertThat(tracker.getAccessPoints()).isEmpty();
845 }
Sundeep Ghuman42058742017-07-21 18:42:10 -0700846
847 @Test
848 public void onConnectedChangedCallback_shouldNotBeInvokedWhenNoStateChange() throws Exception {
849 WifiTracker tracker = createTrackerWithScanResultsAndAccessPoint1Connected();
850 verify(mockWifiListener, times(1)).onConnectedChanged();
851
852 NetworkInfo networkInfo = new NetworkInfo(
853 ConnectivityManager.TYPE_WIFI, 0, "Type Wifi", "subtype");
854 networkInfo.setDetailedState(NetworkInfo.DetailedState.CONNECTED, "connected", "test");
855
856 Intent intent = new Intent(WifiManager.NETWORK_STATE_CHANGED_ACTION);
857 intent.putExtra(WifiManager.EXTRA_NETWORK_INFO, networkInfo);
858 tracker.mReceiver.onReceive(mContext, intent);
859
Sundeep Ghumandb2eabb2017-07-28 14:51:05 -0700860 waitForHandlersToProcessCurrentlyEnqueuedMessages(tracker);
Sundeep Ghuman42058742017-07-21 18:42:10 -0700861 verify(mockWifiListener, times(1)).onConnectedChanged();
862 }
863
864 @Test
Sundeep Ghumandb2eabb2017-07-28 14:51:05 -0700865 public void onConnectedChangedCallback_shouldBeInvokedWhenStateChanges() throws Exception {
Sundeep Ghuman42058742017-07-21 18:42:10 -0700866 WifiTracker tracker = createTrackerWithScanResultsAndAccessPoint1Connected();
867 verify(mockWifiListener, times(1)).onConnectedChanged();
868
869 NetworkInfo networkInfo = new NetworkInfo(
870 ConnectivityManager.TYPE_WIFI, 0, "Type Wifi", "subtype");
871 networkInfo.setDetailedState(
Sundeep Ghumandb2eabb2017-07-28 14:51:05 -0700872 NetworkInfo.DetailedState.DISCONNECTED, "disconnected", "test");
Sundeep Ghuman42058742017-07-21 18:42:10 -0700873
874 Intent intent = new Intent(WifiManager.NETWORK_STATE_CHANGED_ACTION);
875 intent.putExtra(WifiManager.EXTRA_NETWORK_INFO, networkInfo);
876 tracker.mReceiver.onReceive(mContext, intent);
877
Sundeep Ghumandb2eabb2017-07-28 14:51:05 -0700878 waitForHandlersToProcessCurrentlyEnqueuedMessages(tracker);
879 assertThat(tracker.isConnected()).isFalse();
Sundeep Ghuman42058742017-07-21 18:42:10 -0700880 verify(mockWifiListener, times(2)).onConnectedChanged();
881 }
Peter Qiuabea7262017-05-31 10:18:17 -0700882}