blob: df6587e5042f8c47cfd0bcec0d54a27ec60c902c [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;
39import android.net.ConnectivityManager;
Sundeep Ghuman9c0b97e2017-04-13 16:05:46 -070040import android.net.Network;
Sundeep Ghuman2b489902017-02-22 18:17:29 -080041import android.net.NetworkInfo;
Sundeep Ghuman5519b7b2016-12-14 17:53:31 -080042import android.net.NetworkKey;
43import android.net.NetworkScoreManager;
Sundeep Ghuman5519b7b2016-12-14 17:53:31 -080044import android.net.RssiCurve;
Sundeep Ghuman9c0b97e2017-04-13 16:05:46 -070045import android.net.ScoredNetwork;
Sundeep Ghuman5519b7b2016-12-14 17:53:31 -080046import android.net.WifiKey;
Ajay Nadathur7d176bc2016-10-24 16:55:24 -070047import android.net.wifi.ScanResult;
48import android.net.wifi.WifiConfiguration;
Sundeep Ghuman2b489902017-02-22 18:17:29 -080049import android.net.wifi.WifiInfo;
Sundeep Ghuman5519b7b2016-12-14 17:53:31 -080050import android.net.wifi.WifiManager;
51import android.net.wifi.WifiNetworkScoreCache;
52import android.net.wifi.WifiSsid;
53import android.os.Bundle;
Sundeep Ghuman5519b7b2016-12-14 17:53:31 -080054import android.os.Handler;
55import android.os.HandlerThread;
56import android.os.Looper;
Sundeep Ghuman9c0b97e2017-04-13 16:05:46 -070057import android.os.SystemClock;
Sundeep Ghuman5519b7b2016-12-14 17:53:31 -080058import android.provider.Settings;
Ajay Nadathur7d176bc2016-10-24 16:55:24 -070059import android.support.test.InstrumentationRegistry;
60import android.support.test.filters.SmallTest;
61import android.support.test.runner.AndroidJUnit4;
Sundeep Ghuman266b4092017-06-16 15:12:56 -070062import android.support.test.filters.FlakyTest;
Ajay Nadathur7d176bc2016-10-24 16:55:24 -070063
Sundeep Ghuman5519b7b2016-12-14 17:53:31 -080064import org.junit.After;
65import org.junit.Before;
Ajay Nadathur7d176bc2016-10-24 16:55:24 -070066import org.junit.Test;
67import org.junit.runner.RunWith;
Sundeep Ghuman5519b7b2016-12-14 17:53:31 -080068import org.mockito.ArgumentCaptor;
Sundeep Ghuman5519b7b2016-12-14 17:53:31 -080069import org.mockito.Captor;
Sundeep Ghuman9c0b97e2017-04-13 16:05:46 -070070import org.mockito.Matchers;
Sundeep Ghuman5519b7b2016-12-14 17:53:31 -080071import org.mockito.Mock;
72import org.mockito.MockitoAnnotations;
73import org.mockito.invocation.InvocationOnMock;
74import org.mockito.stubbing.Answer;
75
Ajay Nadathur7d176bc2016-10-24 16:55:24 -070076import java.util.ArrayList;
77import java.util.Arrays;
78import java.util.BitSet;
79import java.util.List;
Sundeep Ghuman5519b7b2016-12-14 17:53:31 -080080import java.util.concurrent.CountDownLatch;
81import java.util.concurrent.TimeUnit;
Ajay Nadathur7d176bc2016-10-24 16:55:24 -070082
Sundeep Ghuman2b489902017-02-22 18:17:29 -080083// TODO(sghuman): Change these to robolectric tests b/35766684.
84
Ajay Nadathur7d176bc2016-10-24 16:55:24 -070085@SmallTest
86@RunWith(AndroidJUnit4.class)
87public class WifiTrackerTest {
88
Sundeep Ghuman5519b7b2016-12-14 17:53:31 -080089 private static final String TAG = "WifiTrackerTest";
Sundeep Ghumanac7b4362017-02-08 17:19:27 -080090 private static final int LATCH_TIMEOUT = 4000;
Sundeep Ghuman5519b7b2016-12-14 17:53:31 -080091
92 private static final String SSID_1 = "ssid1";
93 private static final String BSSID_1 = "00:00:00:00:00:00";
94 private static final NetworkKey NETWORK_KEY_1 =
95 new NetworkKey(new WifiKey('"' + SSID_1 + '"', BSSID_1));
96 private static final int RSSI_1 = -30;
97 private static final byte SCORE_1 = 10;
Sundeep Ghuman53200ed2017-06-21 16:54:36 -070098 private static final int BADGE_1 = AccessPoint.Speed.MODERATE;
Sundeep Ghuman5519b7b2016-12-14 17:53:31 -080099
100 private static final String SSID_2 = "ssid2";
101 private static final String BSSID_2 = "AA:AA:AA:AA:AA:AA";
102 private static final NetworkKey NETWORK_KEY_2 =
103 new NetworkKey(new WifiKey('"' + SSID_2 + '"', BSSID_2));
104 private static final int RSSI_2 = -30;
105 private static final byte SCORE_2 = 15;
Sundeep Ghuman53200ed2017-06-21 16:54:36 -0700106 private static final int BADGE_2 = AccessPoint.Speed.FAST;
Sundeep Ghuman5519b7b2016-12-14 17:53:31 -0800107
Sundeep Ghuman8c792882017-04-04 17:23:29 -0700108 private static final int CONNECTED_NETWORK_ID = 123;
109 private static final int CONNECTED_RSSI = -50;
110 private static final WifiInfo CONNECTED_AP_1_INFO = new WifiInfo();
111 static {
112 CONNECTED_AP_1_INFO.setSSID(WifiSsid.createFromAsciiEncoded(SSID_1));
113 CONNECTED_AP_1_INFO.setBSSID(BSSID_1);
114 CONNECTED_AP_1_INFO.setNetworkId(CONNECTED_NETWORK_ID);
115 CONNECTED_AP_1_INFO.setRssi(CONNECTED_RSSI);
116 }
117
Sundeep Ghuman5519b7b2016-12-14 17:53:31 -0800118 @Captor ArgumentCaptor<WifiNetworkScoreCache> mScoreCacheCaptor;
119 @Mock private ConnectivityManager mockConnectivityManager;
120 @Mock private NetworkScoreManager mockNetworkScoreManager;
121 @Mock private RssiCurve mockCurve1;
122 @Mock private RssiCurve mockCurve2;
123 @Mock private RssiCurve mockBadgeCurve1;
124 @Mock private RssiCurve mockBadgeCurve2;
125 @Mock private WifiManager mockWifiManager;
126 @Mock private WifiTracker.WifiListener mockWifiListener;
127
128 private final List<NetworkKey> mRequestedKeys = new ArrayList<>();
129
130 private Context mContext;
131 private CountDownLatch mAccessPointsChangedLatch;
132 private CountDownLatch mRequestScoresLatch;
133 private Handler mScannerHandler;
134 private HandlerThread mMainThread;
135 private HandlerThread mWorkerThread;
Sundeep Ghuman71f4a822017-04-18 19:51:46 -0700136 private Looper mWorkerLooper;
Sundeep Ghuman5519b7b2016-12-14 17:53:31 -0800137 private Looper mMainLooper;
Sundeep Ghuman42058742017-07-21 18:42:10 -0700138
Sundeep Ghumane869d832017-01-25 16:23:43 -0800139 private int mOriginalScoringUiSettingValue;
Sundeep Ghuman5519b7b2016-12-14 17:53:31 -0800140
141 @Before
142 public void setUp() {
Sundeep Ghuman5519b7b2016-12-14 17:53:31 -0800143 MockitoAnnotations.initMocks(this);
144
Sundeep Ghuman2b489902017-02-22 18:17:29 -0800145 mContext = InstrumentationRegistry.getTargetContext();
146
Sundeep Ghuman5519b7b2016-12-14 17:53:31 -0800147 mWorkerThread = new HandlerThread("TestHandlerWorkerThread");
148 mWorkerThread.start();
Sundeep Ghuman71f4a822017-04-18 19:51:46 -0700149 mWorkerLooper = mWorkerThread.getLooper();
Sundeep Ghuman5519b7b2016-12-14 17:53:31 -0800150 mMainThread = new HandlerThread("TestHandlerThread");
151 mMainThread.start();
152 mMainLooper = mMainThread.getLooper();
153
154 // Make sure the scanner doesn't try to run on the testing thread.
155 HandlerThread scannerThread = new HandlerThread("ScannerWorkerThread");
156 scannerThread.start();
157 mScannerHandler = new Handler(scannerThread.getLooper());
158
159 when(mockWifiManager.isWifiEnabled()).thenReturn(true);
160 when(mockWifiManager.getScanResults())
161 .thenReturn(Arrays.asList(buildScanResult1(), buildScanResult2()));
162
163
164 when(mockCurve1.lookupScore(RSSI_1)).thenReturn(SCORE_1);
165 when(mockCurve2.lookupScore(RSSI_2)).thenReturn(SCORE_2);
166
167 when(mockBadgeCurve1.lookupScore(RSSI_1)).thenReturn((byte) BADGE_1);
168 when(mockBadgeCurve2.lookupScore(RSSI_2)).thenReturn((byte) BADGE_2);
169
170 doNothing()
171 .when(mockNetworkScoreManager)
172 .registerNetworkScoreCache(
173 anyInt(),
174 mScoreCacheCaptor.capture(),
175 Matchers.anyInt());
176
177 // Capture requested keys and count down latch if present
178 doAnswer(
179 new Answer<Boolean>() {
180 @Override
181 public Boolean answer(InvocationOnMock input) {
182 if (mRequestScoresLatch != null) {
183 mRequestScoresLatch.countDown();
184 }
185 NetworkKey[] keys = (NetworkKey[]) input.getArguments()[0];
186 for (NetworkKey key : keys) {
187 mRequestedKeys.add(key);
188 }
189 return true;
190 }
191 }).when(mockNetworkScoreManager).requestScores(Matchers.<NetworkKey[]>any());
192
193 doAnswer(
194 new Answer<Void>() {
195 @Override
196 public Void answer (InvocationOnMock invocation) throws Throwable {
197 if (mAccessPointsChangedLatch != null) {
198 mAccessPointsChangedLatch.countDown();
199 }
200
201 return null;
202 }
203 }).when(mockWifiListener).onAccessPointsChanged();
204
Sundeep Ghumane869d832017-01-25 16:23:43 -0800205 // Turn on Scoring UI features
206 mOriginalScoringUiSettingValue = Settings.Global.getInt(
207 InstrumentationRegistry.getTargetContext().getContentResolver(),
208 Settings.Global.NETWORK_SCORING_UI_ENABLED,
209 0 /* disabled */);
210 Settings.Global.putInt(
211 InstrumentationRegistry.getTargetContext().getContentResolver(),
212 Settings.Global.NETWORK_SCORING_UI_ENABLED,
213 1 /* enabled */);
Sundeep Ghuman42058742017-07-21 18:42:10 -0700214
Sundeep Ghuman5519b7b2016-12-14 17:53:31 -0800215 }
216
217 @After
218 public void cleanUp() {
219 Settings.Global.putInt(
Sundeep Ghumane869d832017-01-25 16:23:43 -0800220 InstrumentationRegistry.getTargetContext().getContentResolver(),
221 Settings.Global.NETWORK_SCORING_UI_ENABLED,
222 mOriginalScoringUiSettingValue);
Sundeep Ghuman5519b7b2016-12-14 17:53:31 -0800223 }
224
225 private static ScanResult buildScanResult1() {
226 return new ScanResult(
227 WifiSsid.createFromAsciiEncoded(SSID_1),
228 BSSID_1,
229 0, // hessid
230 0, //anqpDomainId
231 null, // osuProviders
232 "", // capabilities
233 RSSI_1,
234 0, // frequency
235 SystemClock.elapsedRealtime() * 1000 /* microsecond timestamp */);
236 }
237
238 private static ScanResult buildScanResult2() {
239 return new ScanResult(
240 WifiSsid.createFromAsciiEncoded(SSID_2),
241 BSSID_2,
242 0, // hessid
243 0, //anqpDomainId
244 null, // osuProviders
245 "", // capabilities
246 RSSI_2,
247 0, // frequency
248 SystemClock.elapsedRealtime() * 1000 /* microsecond timestamp */);
249 }
250
Sundeep Ghuman2b489902017-02-22 18:17:29 -0800251 private WifiTracker createTrackerWithImmediateBroadcastsAndInjectInitialScanResults(
252 Intent ... intents)
253 throws InterruptedException {
Sundeep Ghuman5519b7b2016-12-14 17:53:31 -0800254 WifiTracker tracker = createMockedWifiTracker();
Sundeep Ghuman2b489902017-02-22 18:17:29 -0800255
Sundeep Ghuman5519b7b2016-12-14 17:53:31 -0800256 startTracking(tracker);
Sundeep Ghuman2b489902017-02-22 18:17:29 -0800257 for (Intent intent : intents) {
258 tracker.mReceiver.onReceive(mContext, intent);
259 }
Sundeep Ghuman5519b7b2016-12-14 17:53:31 -0800260
Sundeep Ghuman5519b7b2016-12-14 17:53:31 -0800261 sendScanResultsAndProcess(tracker);
Sundeep Ghumane8013092017-06-21 22:35:30 -0700262 waitForHandlersToProcessCurrentlyEnqueuedMessages(tracker);
Sundeep Ghuman5519b7b2016-12-14 17:53:31 -0800263
264 return tracker;
265 }
266
267 private WifiTracker createMockedWifiTracker() {
268 WifiTracker tracker =
269 new WifiTracker(
Sundeep Ghuman2b489902017-02-22 18:17:29 -0800270 mContext,
271 mockWifiListener,
Sundeep Ghuman71f4a822017-04-18 19:51:46 -0700272 mWorkerLooper,
Sundeep Ghuman2b489902017-02-22 18:17:29 -0800273 true,
274 true,
275 true,
276 mockWifiManager,
277 mockConnectivityManager,
278 mockNetworkScoreManager,
279 mMainLooper
Sundeep Ghuman5519b7b2016-12-14 17:53:31 -0800280 );
281
282 return tracker;
283 }
284
285 private void startTracking(WifiTracker tracker) throws InterruptedException {
286 CountDownLatch latch = new CountDownLatch(1);
287 mScannerHandler.post(new Runnable() {
288 @Override
289 public void run() {
290 tracker.startTracking();
291 latch.countDown();
292 }
293 });
Sundeep Ghumanac7b4362017-02-08 17:19:27 -0800294 assertTrue("Latch timed out", latch.await(LATCH_TIMEOUT, TimeUnit.MILLISECONDS));
Sundeep Ghuman5519b7b2016-12-14 17:53:31 -0800295 }
296
297 private void sendScanResultsAndProcess(WifiTracker tracker) throws InterruptedException {
298 mAccessPointsChangedLatch = new CountDownLatch(1);
299 Intent i = new Intent(WifiManager.SCAN_RESULTS_AVAILABLE_ACTION);
300 tracker.mReceiver.onReceive(mContext, i);
301
Sundeep Ghumanac7b4362017-02-08 17:19:27 -0800302 assertTrue("Latch timed out",
303 mAccessPointsChangedLatch.await(LATCH_TIMEOUT, TimeUnit.MILLISECONDS));
Sundeep Ghuman5519b7b2016-12-14 17:53:31 -0800304 }
305
306 private void updateScores() {
307 Bundle attr1 = new Bundle();
308 attr1.putParcelable(ScoredNetwork.ATTRIBUTES_KEY_BADGING_CURVE, mockBadgeCurve1);
309 ScoredNetwork sc1 =
310 new ScoredNetwork(
311 NETWORK_KEY_1,
312 mockCurve1,
313 false /* meteredHint */,
314 attr1);
315
316 Bundle attr2 = new Bundle();
317 attr2.putParcelable(ScoredNetwork.ATTRIBUTES_KEY_BADGING_CURVE, mockBadgeCurve2);
318 ScoredNetwork sc2 =
319 new ScoredNetwork(
320 NETWORK_KEY_2,
321 mockCurve2,
Stephen Chen21f68682017-04-04 13:23:31 -0700322 true /* meteredHint */,
Sundeep Ghuman5519b7b2016-12-14 17:53:31 -0800323 attr2);
324
325 WifiNetworkScoreCache scoreCache = mScoreCacheCaptor.getValue();
326 scoreCache.updateScores(Arrays.asList(sc1, sc2));
327 }
328
Sundeep Ghuman2b489902017-02-22 18:17:29 -0800329 private WifiTracker createTrackerWithScanResultsAndAccessPoint1Connected()
330 throws InterruptedException {
Sundeep Ghuman8c792882017-04-04 17:23:29 -0700331 when(mockWifiManager.getConnectionInfo()).thenReturn(CONNECTED_AP_1_INFO);
Sundeep Ghuman2b489902017-02-22 18:17:29 -0800332
333 WifiConfiguration configuration = new WifiConfiguration();
334 configuration.SSID = SSID_1;
335 configuration.BSSID = BSSID_1;
Sundeep Ghuman8c792882017-04-04 17:23:29 -0700336 configuration.networkId = CONNECTED_NETWORK_ID;
Sundeep Ghuman2b489902017-02-22 18:17:29 -0800337 when(mockWifiManager.getConfiguredNetworks()).thenReturn(Arrays.asList(configuration));
338
339 NetworkInfo networkInfo = new NetworkInfo(
340 ConnectivityManager.TYPE_WIFI, 0, "Type Wifi", "subtype");
341 networkInfo.setDetailedState(NetworkInfo.DetailedState.CONNECTED, "connected", "test");
342
343 Intent intent = new Intent(WifiManager.NETWORK_STATE_CHANGED_ACTION);
344 intent.putExtra(WifiManager.EXTRA_NETWORK_INFO, networkInfo);
Sundeep Ghumandb2eabb2017-07-28 14:51:05 -0700345 WifiTracker tracker =
346 createTrackerWithImmediateBroadcastsAndInjectInitialScanResults(intent);
347 assertThat(tracker.isConnected()).isTrue();
348 return tracker;
Sundeep Ghuman2b489902017-02-22 18:17:29 -0800349 }
350
Sundeep Ghumane8013092017-06-21 22:35:30 -0700351 private void waitForHandlersToProcessCurrentlyEnqueuedMessages(WifiTracker tracker)
352 throws InterruptedException {
353 CountDownLatch workerLatch = new CountDownLatch(1);
354 tracker.mWorkHandler.post(() -> {
355 workerLatch.countDown();
356 });
357 assertTrue("Latch timed out while waiting for WorkerHandler",
358 workerLatch.await(LATCH_TIMEOUT, TimeUnit.MILLISECONDS));
359
360 CountDownLatch mainLatch = new CountDownLatch(1);
361 tracker.mMainHandler.post(() -> {
362 mainLatch.countDown();
363 });
364 assertTrue("Latch timed out while waiting for MainHandler",
365 mainLatch.await(LATCH_TIMEOUT, TimeUnit.MILLISECONDS));
366 }
367
Ajay Nadathur7d176bc2016-10-24 16:55:24 -0700368 @Test
369 public void testAccessPointListenerSetWhenLookingUpUsingScanResults() {
370 ScanResult scanResult = new ScanResult();
371 scanResult.level = 123;
372 scanResult.BSSID = "bssid-" + 111;
373 scanResult.timestamp = SystemClock.elapsedRealtime() * 1000;
374 scanResult.capabilities = "";
375
376 WifiTracker tracker = new WifiTracker(
Sundeep Ghuman71f4a822017-04-18 19:51:46 -0700377 InstrumentationRegistry.getTargetContext(), null, mWorkerLooper, true, true);
Ajay Nadathur7d176bc2016-10-24 16:55:24 -0700378
379 AccessPoint result = tracker.getCachedOrCreate(scanResult, new ArrayList<AccessPoint>());
380 assertTrue(result.mAccessPointListener != null);
381 }
382
383 @Test
384 public void testAccessPointListenerSetWhenLookingUpUsingWifiConfiguration() {
385 WifiConfiguration configuration = new WifiConfiguration();
386 configuration.SSID = "test123";
387 configuration.BSSID="bssid";
388 configuration.networkId = 123;
389 configuration.allowedKeyManagement = new BitSet();
390 configuration.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
391
392 WifiTracker tracker = new WifiTracker(
Sundeep Ghuman71f4a822017-04-18 19:51:46 -0700393 InstrumentationRegistry.getTargetContext(), null, mWorkerLooper, true, true);
Ajay Nadathur7d176bc2016-10-24 16:55:24 -0700394
395 AccessPoint result = tracker.getCachedOrCreate(configuration, new ArrayList<AccessPoint>());
396 assertTrue(result.mAccessPointListener != null);
397 }
Sundeep Ghuman5519b7b2016-12-14 17:53:31 -0800398
399 @Test
400 public void startAndStopTrackingShouldRegisterAndUnregisterScoreCache()
401 throws InterruptedException {
402 WifiTracker tracker = createMockedWifiTracker();
403
404 // Test register
405 startTracking(tracker);
406 verify(mockNetworkScoreManager)
407 .registerNetworkScoreCache(
408 Matchers.anyInt(),
409 mScoreCacheCaptor.capture(),
410 Matchers.anyInt());
411
412 WifiNetworkScoreCache scoreCache = mScoreCacheCaptor.getValue();
413
Sundeep Ghumane869d832017-01-25 16:23:43 -0800414 CountDownLatch latch = new CountDownLatch(1);
415 doAnswer(
416 (invocation) -> {
417 latch.countDown();
418 return null;
419 }).when(mockNetworkScoreManager)
420 .unregisterNetworkScoreCache(NetworkKey.TYPE_WIFI, scoreCache);
421
Sundeep Ghuman5519b7b2016-12-14 17:53:31 -0800422 // Test unregister
423 tracker.stopTracking();
424
Sundeep Ghumanac7b4362017-02-08 17:19:27 -0800425 assertTrue("Latch timed out", latch.await(LATCH_TIMEOUT, TimeUnit.MILLISECONDS));
Sundeep Ghuman5519b7b2016-12-14 17:53:31 -0800426 verify(mockNetworkScoreManager)
427 .unregisterNetworkScoreCache(NetworkKey.TYPE_WIFI, scoreCache);
428 }
429
430 @Test
Amin Shaikha80ae0c2017-03-23 16:18:30 -0700431 public void testGetNumSavedNetworks() throws InterruptedException {
432 WifiConfiguration validConfig = new WifiConfiguration();
433 validConfig.SSID = SSID_1;
434 validConfig.BSSID = BSSID_1;
435
436 WifiConfiguration selfAddedNoAssociation = new WifiConfiguration();
Peter Qiuabea7262017-05-31 10:18:17 -0700437 selfAddedNoAssociation.ephemeral = true;
Amin Shaikha80ae0c2017-03-23 16:18:30 -0700438 selfAddedNoAssociation.selfAdded = true;
439 selfAddedNoAssociation.numAssociation = 0;
440 selfAddedNoAssociation.SSID = SSID_2;
441 selfAddedNoAssociation.BSSID = BSSID_2;
442
443 when(mockWifiManager.getConfiguredNetworks())
444 .thenReturn(Arrays.asList(validConfig, selfAddedNoAssociation));
445
446 WifiTracker tracker = createTrackerWithImmediateBroadcastsAndInjectInitialScanResults();
447
448 assertEquals(1, tracker.getNumSavedNetworks());
449 }
450
451 @Test
Sundeep Ghuman2b489902017-02-22 18:17:29 -0800452 public void startTrackingShouldSetConnectedAccessPointAsActive() throws InterruptedException {
Sundeep Ghumane8013092017-06-21 22:35:30 -0700453 WifiTracker tracker = createTrackerWithScanResultsAndAccessPoint1Connected();
Sundeep Ghuman2b489902017-02-22 18:17:29 -0800454
455 List<AccessPoint> aps = tracker.getAccessPoints();
456
457 assertThat(aps).hasSize(2);
458 assertThat(aps.get(0).isActive()).isTrue();
459 }
460
461 @Test
Sundeep Ghuman71f4a822017-04-18 19:51:46 -0700462 public void startTrackingAfterStopTracking_shouldRequestNewScores()
463 throws InterruptedException {
Sundeep Ghuman5519b7b2016-12-14 17:53:31 -0800464 // Start the tracker and inject the initial scan results and then stop tracking
Sundeep Ghuman2b489902017-02-22 18:17:29 -0800465 WifiTracker tracker = createTrackerWithImmediateBroadcastsAndInjectInitialScanResults();
Sundeep Ghuman5519b7b2016-12-14 17:53:31 -0800466
467 tracker.stopTracking();
468 mRequestedKeys.clear();
469
Sundeep Ghumanac7b4362017-02-08 17:19:27 -0800470 mRequestScoresLatch = new CountDownLatch(1);
Sundeep Ghuman5519b7b2016-12-14 17:53:31 -0800471 startTracking(tracker);
Sundeep Ghuman71f4a822017-04-18 19:51:46 -0700472 tracker.forceUpdate();
Sundeep Ghumanac7b4362017-02-08 17:19:27 -0800473 assertTrue("Latch timed out",
474 mRequestScoresLatch.await(LATCH_TIMEOUT, TimeUnit.MILLISECONDS));
Sundeep Ghuman5519b7b2016-12-14 17:53:31 -0800475
476 assertTrue(mRequestedKeys.contains(NETWORK_KEY_1));
477 assertTrue(mRequestedKeys.contains(NETWORK_KEY_2));
478 }
479
480 @Test
Sundeep Ghuman75f94802017-06-26 16:05:40 -0700481 public void stopTracking_shouldNotClearExistingScores()
482 throws InterruptedException {
483 // Start the tracker and inject the initial scan results and then stop tracking
484 WifiTracker tracker = createTrackerWithImmediateBroadcastsAndInjectInitialScanResults();
485 updateScoresAndWaitForAccessPointsChangedCallback(tracker);
486 tracker.stopTracking();
487
488 assertThat(mScoreCacheCaptor.getValue().getScoredNetwork(NETWORK_KEY_1)).isNotNull();
489 }
490
491 @Test
Sundeep Ghuman8c792882017-04-04 17:23:29 -0700492 public void scoreCacheUpdateScoresShouldTriggerOnAccessPointsChanged()
493 throws InterruptedException {
Sundeep Ghuman5519b7b2016-12-14 17:53:31 -0800494 WifiTracker tracker = createMockedWifiTracker();
495 startTracking(tracker);
496 sendScanResultsAndProcess(tracker);
497
Sundeep Ghumane8013092017-06-21 22:35:30 -0700498 updateScoresAndWaitForAccessPointsChangedCallback(tracker);
Sundeep Ghuman5519b7b2016-12-14 17:53:31 -0800499 }
500
Sundeep Ghumane8013092017-06-21 22:35:30 -0700501 private void updateScoresAndWaitForAccessPointsChangedCallback(WifiTracker tracker)
502 throws InterruptedException {
Sundeep Ghumanac7b4362017-02-08 17:19:27 -0800503 // Updating scores can happen together or one after the other, so the latch countdown is set
504 // to 2.
Sundeep Ghumane8013092017-06-21 22:35:30 -0700505 mAccessPointsChangedLatch = new CountDownLatch(1);
Sundeep Ghuman5519b7b2016-12-14 17:53:31 -0800506 updateScores();
Sundeep Ghumane8013092017-06-21 22:35:30 -0700507 assertTrue("onAccessPointChanged was not called after updating scores",
Sundeep Ghumance6bab82017-04-19 16:21:46 -0700508 mAccessPointsChangedLatch.await(LATCH_TIMEOUT, TimeUnit.MILLISECONDS));
Sundeep Ghumane8013092017-06-21 22:35:30 -0700509 waitForHandlersToProcessCurrentlyEnqueuedMessages(tracker);
Sundeep Ghuman5519b7b2016-12-14 17:53:31 -0800510 }
511
Sundeep Ghuman266b4092017-06-16 15:12:56 -0700512 @FlakyTest
Sundeep Ghuman5519b7b2016-12-14 17:53:31 -0800513 @Test
514 public void scoreCacheUpdateScoresShouldChangeSortOrder() throws InterruptedException {
Sundeep Ghuman8c792882017-04-04 17:23:29 -0700515 WifiTracker tracker = createTrackerWithImmediateBroadcastsAndInjectInitialScanResults();
Sundeep Ghuman5519b7b2016-12-14 17:53:31 -0800516 List<AccessPoint> aps = tracker.getAccessPoints();
517 assertTrue(aps.size() == 2);
518 assertEquals(aps.get(0).getSsidStr(), SSID_1);
519 assertEquals(aps.get(1).getSsidStr(), SSID_2);
520
Sundeep Ghumane8013092017-06-21 22:35:30 -0700521 updateScoresAndWaitForAccessPointsChangedCallback(tracker);
Sundeep Ghuman5519b7b2016-12-14 17:53:31 -0800522
523 aps = tracker.getAccessPoints();
524 assertTrue(aps.size() == 2);
525 assertEquals(aps.get(0).getSsidStr(), SSID_2);
526 assertEquals(aps.get(1).getSsidStr(), SSID_1);
Sundeep Ghumane869d832017-01-25 16:23:43 -0800527 }
Sundeep Ghuman5519b7b2016-12-14 17:53:31 -0800528
Sundeep Ghumane869d832017-01-25 16:23:43 -0800529 @Test
530 public void scoreCacheUpdateScoresShouldNotChangeSortOrderWhenSortingDisabled()
531 throws InterruptedException {
532 Settings.Global.putInt(
533 InstrumentationRegistry.getTargetContext().getContentResolver(),
534 Settings.Global.NETWORK_SCORING_UI_ENABLED,
535 0 /* disabled */);
536
Sundeep Ghuman2b489902017-02-22 18:17:29 -0800537 WifiTracker tracker = createTrackerWithImmediateBroadcastsAndInjectInitialScanResults();
Sundeep Ghumane869d832017-01-25 16:23:43 -0800538 List<AccessPoint> aps = tracker.getAccessPoints();
539 assertTrue(aps.size() == 2);
540 assertEquals(aps.get(0).getSsidStr(), SSID_1);
541 assertEquals(aps.get(1).getSsidStr(), SSID_2);
542
Sundeep Ghumane8013092017-06-21 22:35:30 -0700543 updateScoresAndWaitForAccessPointsChangedCallback(tracker);
Sundeep Ghumane869d832017-01-25 16:23:43 -0800544
545 aps = tracker.getAccessPoints();
546 assertTrue(aps.size() == 2);
547 assertEquals(aps.get(0).getSsidStr(), SSID_1);
548 assertEquals(aps.get(1).getSsidStr(), SSID_2);
Sundeep Ghuman5519b7b2016-12-14 17:53:31 -0800549 }
550
Sundeep Ghuman266b4092017-06-16 15:12:56 -0700551 @FlakyTest
Sundeep Ghuman5519b7b2016-12-14 17:53:31 -0800552 @Test
Sundeep Ghuman55adc6b2017-06-05 16:46:59 -0700553 public void scoreCacheUpdateScoresShouldInsertSpeedIntoAccessPoint()
554 throws InterruptedException {
Sundeep Ghuman2b489902017-02-22 18:17:29 -0800555 WifiTracker tracker = createTrackerWithImmediateBroadcastsAndInjectInitialScanResults();
Sundeep Ghumane8013092017-06-21 22:35:30 -0700556 updateScoresAndWaitForAccessPointsChangedCallback(tracker);
Sundeep Ghuman5519b7b2016-12-14 17:53:31 -0800557
558 List<AccessPoint> aps = tracker.getAccessPoints();
559
560 for (AccessPoint ap : aps) {
561 if (ap.getSsidStr().equals(SSID_1)) {
Sundeep Ghuman55adc6b2017-06-05 16:46:59 -0700562 assertEquals(BADGE_1, ap.getSpeed());
Sundeep Ghuman5519b7b2016-12-14 17:53:31 -0800563 } else if (ap.getSsidStr().equals(SSID_2)) {
Sundeep Ghuman55adc6b2017-06-05 16:46:59 -0700564 assertEquals(BADGE_2, ap.getSpeed());
Sundeep Ghuman5519b7b2016-12-14 17:53:31 -0800565 }
566 }
567 }
568
569 @Test
Stephen Chen21f68682017-04-04 13:23:31 -0700570 public void scoreCacheUpdateMeteredShouldUpdateAccessPointMetering()
571 throws InterruptedException {
572 WifiTracker tracker = createTrackerWithImmediateBroadcastsAndInjectInitialScanResults();
Sundeep Ghumane8013092017-06-21 22:35:30 -0700573 updateScoresAndWaitForAccessPointsChangedCallback(tracker);
Stephen Chen21f68682017-04-04 13:23:31 -0700574
575 List<AccessPoint> aps = tracker.getAccessPoints();
576
577 for (AccessPoint ap : aps) {
578 if (ap.getSsidStr().equals(SSID_1)) {
579 assertFalse(ap.isMetered());
580 } else if (ap.getSsidStr().equals(SSID_2)) {
581 assertTrue(ap.isMetered());
582 }
583 }
584 }
585
586 @Test
Sundeep Ghuman55adc6b2017-06-05 16:46:59 -0700587 public void noSpeedsShouldBeInsertedIntoAccessPointWhenScoringUiDisabled()
Sundeep Ghumane869d832017-01-25 16:23:43 -0800588 throws InterruptedException {
589 Settings.Global.putInt(
590 InstrumentationRegistry.getTargetContext().getContentResolver(),
591 Settings.Global.NETWORK_SCORING_UI_ENABLED,
592 0 /* disabled */);
593
Sundeep Ghuman2b489902017-02-22 18:17:29 -0800594 WifiTracker tracker = createTrackerWithImmediateBroadcastsAndInjectInitialScanResults();
Sundeep Ghumane8013092017-06-21 22:35:30 -0700595 updateScoresAndWaitForAccessPointsChangedCallback(tracker);
Sundeep Ghumane869d832017-01-25 16:23:43 -0800596
597 List<AccessPoint> aps = tracker.getAccessPoints();
598
599 for (AccessPoint ap : aps) {
600 if (ap.getSsidStr().equals(SSID_1)) {
Sundeep Ghuman53200ed2017-06-21 16:54:36 -0700601 assertEquals(AccessPoint.Speed.NONE, ap.getSpeed());
Sundeep Ghumane869d832017-01-25 16:23:43 -0800602 } else if (ap.getSsidStr().equals(SSID_2)) {
Sundeep Ghuman53200ed2017-06-21 16:54:36 -0700603 assertEquals(AccessPoint.Speed.NONE, ap.getSpeed());
Sundeep Ghumane869d832017-01-25 16:23:43 -0800604 }
605 }
606 }
607
608 @Test
Sundeep Ghuman5519b7b2016-12-14 17:53:31 -0800609 public void scoresShouldBeRequestedForNewScanResultOnly() throws InterruptedException {
Sundeep Ghumanac7b4362017-02-08 17:19:27 -0800610 // Scores can be requested together or serially depending on how the scan results are
611 // processed.
Sundeep Ghuman5519b7b2016-12-14 17:53:31 -0800612 mRequestScoresLatch = new CountDownLatch(2);
Sundeep Ghuman2b489902017-02-22 18:17:29 -0800613 WifiTracker tracker = createTrackerWithImmediateBroadcastsAndInjectInitialScanResults();
Sundeep Ghuman5519b7b2016-12-14 17:53:31 -0800614 mRequestScoresLatch.await(LATCH_TIMEOUT, TimeUnit.MILLISECONDS);
615 mRequestedKeys.clear();
616
617 String ssid = "ssid3";
618 String bssid = "00:00:00:00:00:00";
619 ScanResult newResult = new ScanResult(
620 WifiSsid.createFromAsciiEncoded(ssid),
621 bssid,
622 0, // hessid
623 0, //anqpDomainId
624 null, // osuProviders
625 "", // capabilities
626 RSSI_1,
627 0, // frequency
628 SystemClock.elapsedRealtime() * 1000);
629 when(mockWifiManager.getScanResults())
630 .thenReturn(Arrays.asList(buildScanResult1(), buildScanResult2(), newResult));
631
632 mRequestScoresLatch = new CountDownLatch(1);
633 sendScanResultsAndProcess(tracker);
Sundeep Ghumanac7b4362017-02-08 17:19:27 -0800634 assertTrue(mRequestScoresLatch.await(LATCH_TIMEOUT, TimeUnit.MILLISECONDS));
Sundeep Ghuman5519b7b2016-12-14 17:53:31 -0800635
636 assertEquals(1, mRequestedKeys.size());
637 assertTrue(mRequestedKeys.contains(new NetworkKey(new WifiKey('"' + ssid + '"', bssid))));
638 }
Sundeep Ghumanac7b4362017-02-08 17:19:27 -0800639
640 @Test
641 public void scoreCacheAndListenerShouldBeUnregisteredWhenStopTrackingIsCalled() throws Exception
642 {
Sundeep Ghuman2b489902017-02-22 18:17:29 -0800643 WifiTracker tracker = createTrackerWithImmediateBroadcastsAndInjectInitialScanResults();
Sundeep Ghumanac7b4362017-02-08 17:19:27 -0800644 WifiNetworkScoreCache cache = mScoreCacheCaptor.getValue();
645
646 tracker.stopTracking();
647 verify(mockNetworkScoreManager).unregisterNetworkScoreCache(NetworkKey.TYPE_WIFI, cache);
648
649 // Verify listener is unregistered so updating a score does not throw an error by posting
650 // a message to the dead work handler
651 mWorkerThread.quit();
652 updateScores();
653 }
Peter Qiuf5628382017-03-28 13:24:34 -0700654
655 /**
656 * Verify that tracking a Passpoint AP on a device with Passpoint disabled doesn't cause
657 * any crash.
658 *
659 * @throws Exception
660 */
661 @Test
662 public void trackPasspointApWithPasspointDisabled() throws Exception {
663 WifiTracker tracker = createMockedWifiTracker();
664
665 // Add a Passpoint AP to the scan results.
666 List<ScanResult> results = new ArrayList<>();
667 ScanResult passpointAp = new ScanResult(
668 WifiSsid.createFromAsciiEncoded(SSID_1),
669 BSSID_1,
670 0, // hessid
671 0, //anqpDomainId
672 null, // osuProviders
673 "", // capabilities
674 RSSI_1,
675 0, // frequency
676 SystemClock.elapsedRealtime() * 1000 /* microsecond timestamp */);
677 passpointAp.setFlag(ScanResult.FLAG_PASSPOINT_NETWORK);
678 results.add(passpointAp);
679
680 // Update access point and verify UnsupportedOperationException is being caught for
681 // call to WifiManager#getMatchingWifiConfig.
682 when(mockWifiManager.getConfiguredNetworks())
683 .thenReturn(new ArrayList<WifiConfiguration>());
684 when(mockWifiManager.getScanResults()).thenReturn(results);
685 doThrow(new UnsupportedOperationException())
686 .when(mockWifiManager).getMatchingWifiConfig(any(ScanResult.class));
687 tracker.forceUpdate();
688 verify(mockWifiManager).getMatchingWifiConfig(any(ScanResult.class));
689 }
Sundeep Ghuman8c792882017-04-04 17:23:29 -0700690
691 @Test
692 public void rssiChangeBroadcastShouldUpdateConnectedAp() throws Exception {
693 WifiTracker tracker = createTrackerWithScanResultsAndAccessPoint1Connected();
694 assertThat(tracker.getAccessPoints().get(0).isActive()).isTrue();
695
Sundeep Ghuman8c792882017-04-04 17:23:29 -0700696 int newRssi = CONNECTED_RSSI + 10;
697 WifiInfo info = new WifiInfo(CONNECTED_AP_1_INFO);
698 info.setRssi(newRssi);
Sundeep Ghuman8c792882017-04-04 17:23:29 -0700699
Sundeep Ghuman71f4a822017-04-18 19:51:46 -0700700 CountDownLatch latch = new CountDownLatch(1);
701
702 // Once the new info has been fetched, we need to wait for the access points to be copied
703 doAnswer(invocation -> {
704 latch.countDown();
705 mAccessPointsChangedLatch = new CountDownLatch(1);
706 return info;
707 }).when(mockWifiManager).getConnectionInfo();
708
Sundeep Ghuman8c792882017-04-04 17:23:29 -0700709 tracker.mReceiver.onReceive(mContext, new Intent(WifiManager.RSSI_CHANGED_ACTION));
Sundeep Ghuman71f4a822017-04-18 19:51:46 -0700710 assertTrue("New connection info never retrieved",
711 latch.await(LATCH_TIMEOUT, TimeUnit.MILLISECONDS));
712 assertTrue("onAccessPointsChanged never called",
713 mAccessPointsChangedLatch.await(LATCH_TIMEOUT, TimeUnit.MILLISECONDS));
Sundeep Ghuman8c792882017-04-04 17:23:29 -0700714
Sundeep Ghuman8c792882017-04-04 17:23:29 -0700715 assertThat(tracker.getAccessPoints().get(0).getRssi()).isEqualTo(newRssi);
716 }
Sundeep Ghuman9c0b97e2017-04-13 16:05:46 -0700717
718 @Test
719 public void forceUpdateShouldSynchronouslyFetchLatestInformation() throws Exception {
Sundeep Ghumance6bab82017-04-19 16:21:46 -0700720 Network mockNetwork = mock(Network.class);
721 when(mockWifiManager.getCurrentNetwork()).thenReturn(mockNetwork);
Sundeep Ghuman71f4a822017-04-18 19:51:46 -0700722
Sundeep Ghuman9c0b97e2017-04-13 16:05:46 -0700723 when(mockWifiManager.getConnectionInfo()).thenReturn(CONNECTED_AP_1_INFO);
724
725 WifiConfiguration configuration = new WifiConfiguration();
726 configuration.SSID = SSID_1;
727 configuration.BSSID = BSSID_1;
728 configuration.networkId = CONNECTED_NETWORK_ID;
729 when(mockWifiManager.getConfiguredNetworks()).thenReturn(Arrays.asList(configuration));
730
731 NetworkInfo networkInfo = new NetworkInfo(
732 ConnectivityManager.TYPE_WIFI, 0, "Type Wifi", "subtype");
733 networkInfo.setDetailedState(NetworkInfo.DetailedState.CONNECTED, "connected", "test");
734 when(mockConnectivityManager.getNetworkInfo(any(Network.class))).thenReturn(networkInfo);
735
Sundeep Ghuman9c0b97e2017-04-13 16:05:46 -0700736 WifiTracker tracker = createMockedWifiTracker();
Sundeep Ghuman9c0b97e2017-04-13 16:05:46 -0700737 tracker.forceUpdate();
738
Sundeep Ghumance6bab82017-04-19 16:21:46 -0700739 verify(mockWifiManager).getConnectionInfo();
740 verify(mockWifiManager, times(2)).getConfiguredNetworks();
741 verify(mockConnectivityManager).getNetworkInfo(any(Network.class));
742
Sundeep Ghumand2b84a82017-07-05 14:19:30 -0700743 verify(mockWifiListener, never()).onAccessPointsChanged(); // mStaleAccessPoints is true
Sundeep Ghuman9c0b97e2017-04-13 16:05:46 -0700744 assertThat(tracker.getAccessPoints().size()).isEqualTo(2);
745 assertThat(tracker.getAccessPoints().get(0).isActive()).isTrue();
746 }
Sundeep Ghuman71f4a822017-04-18 19:51:46 -0700747
748 @Test
749 public void stopTrackingShouldRemoveWifiListenerCallbacks() throws Exception {
750 WifiTracker tracker = createMockedWifiTracker();
751 startTracking(tracker);
752
753 CountDownLatch latch = new CountDownLatch(1);
754 CountDownLatch lock = new CountDownLatch(1);
755 tracker.mMainHandler.post(() -> {
756 try {
757 lock.await();
758 latch.countDown();
759 } catch (InterruptedException e) {
760 fail("Interrupted Exception while awaiting lock release: " + e);
761 }
762 });
763
764 // Enqueue messages
765 tracker.mMainHandler.sendEmptyMessage(
766 WifiTracker.MainHandler.MSG_ACCESS_POINT_CHANGED);
767 tracker.mMainHandler.sendEmptyMessage(
768 WifiTracker.MainHandler.MSG_CONNECTED_CHANGED);
769 tracker.mMainHandler.sendEmptyMessage(
770 WifiTracker.MainHandler.MSG_WIFI_STATE_CHANGED);
771
772 tracker.stopTracking();
773
774 verify(mockWifiListener, atMost(1)).onAccessPointsChanged();
775 verify(mockWifiListener, atMost(1)).onConnectedChanged();
776 verify(mockWifiListener, atMost(1)).onWifiStateChanged(anyInt());
777
778 lock.countDown();
Sundeep Ghumance6bab82017-04-19 16:21:46 -0700779 assertTrue("Latch timed out", latch.await(LATCH_TIMEOUT, TimeUnit.MILLISECONDS));
Sundeep Ghuman71f4a822017-04-18 19:51:46 -0700780
781 assertThat(tracker.mMainHandler.hasMessages(
782 WifiTracker.MainHandler.MSG_ACCESS_POINT_CHANGED)).isFalse();
783 assertThat(tracker.mMainHandler.hasMessages(
784 WifiTracker.MainHandler.MSG_CONNECTED_CHANGED)).isFalse();
785 assertThat(tracker.mMainHandler.hasMessages(
786 WifiTracker.MainHandler.MSG_WIFI_STATE_CHANGED)).isFalse();
787
788 verifyNoMoreInteractions(mockWifiListener);
789 }
Sundeep Ghumand4a79ac2017-06-07 18:11:39 -0700790
791 @Test
792 public void stopTrackingShouldSetStaleBitWhichPreventsCallbacksUntilNextScanResult()
793 throws Exception {
794 WifiTracker tracker = createMockedWifiTracker();
795 startTracking(tracker);
Sundeep Ghumane8013092017-06-21 22:35:30 -0700796 waitForHandlersToProcessCurrentlyEnqueuedMessages(tracker);
Sundeep Ghumand4a79ac2017-06-07 18:11:39 -0700797
Sundeep Ghumane8013092017-06-21 22:35:30 -0700798 tracker.stopTracking();
799 waitForHandlersToProcessCurrentlyEnqueuedMessages(tracker);
Sundeep Ghumand4a79ac2017-06-07 18:11:39 -0700800
801 startTracking(tracker);
802
803 tracker.mReceiver.onReceive(mContext, new Intent(WifiManager.WIFI_STATE_CHANGED_ACTION));
804 tracker.mReceiver.onReceive(
805 mContext, new Intent(WifiManager.CONFIGURED_NETWORKS_CHANGED_ACTION));
806 tracker.mReceiver.onReceive(
807 mContext, new Intent(WifiManager.LINK_CONFIGURATION_CHANGED_ACTION));
808
Sundeep Ghumane8013092017-06-21 22:35:30 -0700809 waitForHandlersToProcessCurrentlyEnqueuedMessages(tracker);
Sundeep Ghumand4a79ac2017-06-07 18:11:39 -0700810
811 verify(mockWifiListener, never()).onAccessPointsChanged();
812
813 sendScanResultsAndProcess(tracker); // verifies onAccessPointsChanged is invoked
814 }
Sundeep Ghumane8013092017-06-21 22:35:30 -0700815
816 @Test
Sundeep Ghumand2b84a82017-07-05 14:19:30 -0700817 public void startTrackingShouldNotSendAnyCallbacksUntilScanResultsAreProcessed()
818 throws Exception {
819 WifiTracker tracker = createMockedWifiTracker();
820 startTracking(tracker);
821 waitForHandlersToProcessCurrentlyEnqueuedMessages(tracker);
822
823 tracker.mReceiver.onReceive(mContext, new Intent(WifiManager.WIFI_STATE_CHANGED_ACTION));
824 tracker.mReceiver.onReceive(
825 mContext, new Intent(WifiManager.CONFIGURED_NETWORKS_CHANGED_ACTION));
826 tracker.mReceiver.onReceive(
827 mContext, new Intent(WifiManager.LINK_CONFIGURATION_CHANGED_ACTION));
828
829 waitForHandlersToProcessCurrentlyEnqueuedMessages(tracker);
830 verify(mockWifiListener, never()).onAccessPointsChanged();
831
832 sendScanResultsAndProcess(tracker); // verifies onAccessPointsChanged is invoked
833 }
834
835 @Test
Sundeep Ghumane8013092017-06-21 22:35:30 -0700836 public void disablingWifiShouldClearExistingAccessPoints() throws Exception {
837 WifiTracker tracker = createTrackerWithScanResultsAndAccessPoint1Connected();
838
839 when(mockWifiManager.isWifiEnabled()).thenReturn(false);
840 mAccessPointsChangedLatch = new CountDownLatch(1);
841 tracker.mReceiver.onReceive(mContext, new Intent(WifiManager.WIFI_STATE_CHANGED_ACTION));
842
843 mAccessPointsChangedLatch.await(LATCH_TIMEOUT, TimeUnit.MILLISECONDS);
844 waitForHandlersToProcessCurrentlyEnqueuedMessages(tracker);
845
846 assertThat(tracker.getAccessPoints()).isEmpty();
847 }
Sundeep Ghuman42058742017-07-21 18:42:10 -0700848
849 @Test
850 public void onConnectedChangedCallback_shouldNotBeInvokedWhenNoStateChange() throws Exception {
851 WifiTracker tracker = createTrackerWithScanResultsAndAccessPoint1Connected();
852 verify(mockWifiListener, times(1)).onConnectedChanged();
853
854 NetworkInfo networkInfo = new NetworkInfo(
855 ConnectivityManager.TYPE_WIFI, 0, "Type Wifi", "subtype");
856 networkInfo.setDetailedState(NetworkInfo.DetailedState.CONNECTED, "connected", "test");
857
858 Intent intent = new Intent(WifiManager.NETWORK_STATE_CHANGED_ACTION);
859 intent.putExtra(WifiManager.EXTRA_NETWORK_INFO, networkInfo);
860 tracker.mReceiver.onReceive(mContext, intent);
861
Sundeep Ghumandb2eabb2017-07-28 14:51:05 -0700862 waitForHandlersToProcessCurrentlyEnqueuedMessages(tracker);
Sundeep Ghuman42058742017-07-21 18:42:10 -0700863 verify(mockWifiListener, times(1)).onConnectedChanged();
864 }
865
866 @Test
Sundeep Ghumandb2eabb2017-07-28 14:51:05 -0700867 public void onConnectedChangedCallback_shouldBeInvokedWhenStateChanges() throws Exception {
Sundeep Ghuman42058742017-07-21 18:42:10 -0700868 WifiTracker tracker = createTrackerWithScanResultsAndAccessPoint1Connected();
869 verify(mockWifiListener, times(1)).onConnectedChanged();
870
871 NetworkInfo networkInfo = new NetworkInfo(
872 ConnectivityManager.TYPE_WIFI, 0, "Type Wifi", "subtype");
873 networkInfo.setDetailedState(
Sundeep Ghumandb2eabb2017-07-28 14:51:05 -0700874 NetworkInfo.DetailedState.DISCONNECTED, "disconnected", "test");
Sundeep Ghuman42058742017-07-21 18:42:10 -0700875
876 Intent intent = new Intent(WifiManager.NETWORK_STATE_CHANGED_ACTION);
877 intent.putExtra(WifiManager.EXTRA_NETWORK_INFO, networkInfo);
878 tracker.mReceiver.onReceive(mContext, intent);
879
Sundeep Ghumandb2eabb2017-07-28 14:51:05 -0700880 waitForHandlersToProcessCurrentlyEnqueuedMessages(tracker);
881 assertThat(tracker.isConnected()).isFalse();
Sundeep Ghuman42058742017-07-21 18:42:10 -0700882 verify(mockWifiListener, times(2)).onConnectedChanged();
883 }
Peter Qiuabea7262017-05-31 10:18:17 -0700884}