NetworkScoreServiceTest.java revision b1a0139590448d706c778d22891efe80b05f11f2
1/* 2 * Copyright (C) 2012 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 17package com.android.server; 18 19import static android.net.NetworkScoreManager.CACHE_FILTER_NONE; 20 21import static junit.framework.Assert.assertEquals; 22import static junit.framework.Assert.assertFalse; 23import static junit.framework.Assert.assertTrue; 24import static junit.framework.Assert.fail; 25 26import static org.mockito.Matchers.any; 27import static org.mockito.Matchers.anyListOf; 28import static org.mockito.Matchers.anyString; 29import static org.mockito.Matchers.eq; 30import static org.mockito.Mockito.atLeastOnce; 31import static org.mockito.Mockito.doThrow; 32import static org.mockito.Mockito.never; 33import static org.mockito.Mockito.times; 34import static org.mockito.Mockito.verify; 35import static org.mockito.Mockito.verifyNoMoreInteractions; 36import static org.mockito.Mockito.verifyZeroInteractions; 37import static org.mockito.Mockito.when; 38 39import android.Manifest.permission; 40import android.content.ComponentName; 41import android.content.ContentResolver; 42import android.content.Context; 43import android.content.Intent; 44import android.content.pm.PackageManager; 45import android.content.res.Resources; 46import android.net.INetworkRecommendationProvider; 47import android.net.INetworkScoreCache; 48import android.net.NetworkKey; 49import android.net.NetworkScoreManager; 50import android.net.NetworkScorerAppData; 51import android.net.ScoredNetwork; 52import android.net.Uri; 53import android.net.WifiKey; 54import android.net.wifi.ScanResult; 55import android.net.wifi.WifiConfiguration; 56import android.net.wifi.WifiInfo; 57import android.net.wifi.WifiSsid; 58import android.os.Binder; 59import android.os.Bundle; 60import android.os.Handler; 61import android.os.HandlerThread; 62import android.os.IBinder; 63import android.os.Looper; 64import android.os.Message; 65import android.os.RemoteCallback; 66import android.os.RemoteException; 67import android.os.UserHandle; 68import android.support.test.InstrumentationRegistry; 69import android.support.test.filters.MediumTest; 70import android.support.test.runner.AndroidJUnit4; 71 72import com.android.server.devicepolicy.MockUtils; 73 74import com.google.android.collect.Lists; 75 76import org.junit.After; 77import org.junit.Before; 78import org.junit.Test; 79import org.junit.runner.RunWith; 80import org.mockito.ArgumentCaptor; 81import org.mockito.Captor; 82import org.mockito.Mock; 83import org.mockito.MockitoAnnotations; 84 85import java.io.FileDescriptor; 86import java.io.PrintWriter; 87import java.io.StringWriter; 88import java.util.ArrayList; 89import java.util.Collections; 90import java.util.List; 91import java.util.concurrent.CountDownLatch; 92import java.util.concurrent.TimeUnit; 93import java.util.function.UnaryOperator; 94 95/** 96 * Tests for {@link NetworkScoreService}. 97 */ 98@RunWith(AndroidJUnit4.class) 99@MediumTest 100public class NetworkScoreServiceTest { 101 private static final String SSID = "ssid"; 102 private static final String SSID_2 = "ssid_2"; 103 private static final String SSID_3 = "ssid_3"; 104 private static final String INVALID_BSSID = "invalid_bssid"; 105 private static final ComponentName RECOMMENDATION_SERVICE_COMP = 106 new ComponentName("newPackageName", "newScoringServiceClass"); 107 private static final String RECOMMENDATION_SERVICE_LABEL = "Test Recommendation Service"; 108 private static final ComponentName USE_WIFI_ENABLE_ACTIVITY_COMP = 109 new ComponentName("useWifiPackageName", "enableUseWifiActivityClass"); 110 private static final ScoredNetwork SCORED_NETWORK = 111 new ScoredNetwork(new NetworkKey(new WifiKey(quote(SSID), "00:00:00:00:00:00")), 112 null /* rssiCurve*/); 113 private static final ScoredNetwork SCORED_NETWORK_2 = 114 new ScoredNetwork(new NetworkKey(new WifiKey(quote(SSID_2), "00:00:00:00:00:00")), 115 null /* rssiCurve*/); 116 private static final String NETWORK_AVAILABLE_NOTIFICATION_CHANNEL_ID = 117 "networkAvailableNotificationChannelId"; 118 private static final NetworkScorerAppData NEW_SCORER = new NetworkScorerAppData( 119 1, RECOMMENDATION_SERVICE_COMP, RECOMMENDATION_SERVICE_LABEL, 120 USE_WIFI_ENABLE_ACTIVITY_COMP, NETWORK_AVAILABLE_NOTIFICATION_CHANNEL_ID); 121 122 @Mock private NetworkScorerAppManager mNetworkScorerAppManager; 123 @Mock private Context mContext; 124 @Mock private Resources mResources; 125 @Mock private INetworkScoreCache.Stub mNetworkScoreCache, mNetworkScoreCache2; 126 @Mock private IBinder mScoreCacheIBinder, mScoreCacheIBinder2; 127 @Mock private IBinder mServiceConnectionIBinder; 128 @Mock private INetworkRecommendationProvider mRecommendationProvider; 129 @Mock private UnaryOperator<List<ScoredNetwork>> mCurrentNetworkFilter; 130 @Mock private UnaryOperator<List<ScoredNetwork>> mScanResultsFilter; 131 @Mock private WifiInfo mWifiInfo; 132 @Mock private NetworkScoreService.ScoringServiceConnection mServiceConnection; 133 @Captor private ArgumentCaptor<List<ScoredNetwork>> mScoredNetworkCaptor; 134 135 private ContentResolver mContentResolver; 136 private NetworkScoreService mNetworkScoreService; 137 private HandlerThread mHandlerThread; 138 private List<ScanResult> mScanResults; 139 140 private static String quote(String str) { 141 return String.format("\"%s\"", str); 142 } 143 144 @Before 145 public void setUp() throws Exception { 146 MockitoAnnotations.initMocks(this); 147 when(mNetworkScoreCache.asBinder()).thenReturn(mScoreCacheIBinder); 148 when(mNetworkScoreCache2.asBinder()).thenReturn(mScoreCacheIBinder2); 149 when(mServiceConnectionIBinder.queryLocalInterface(anyString())) 150 .thenReturn(mRecommendationProvider); 151 mContentResolver = InstrumentationRegistry.getContext().getContentResolver(); 152 when(mContext.getContentResolver()).thenReturn(mContentResolver); 153 when(mContext.getResources()).thenReturn(mResources); 154 when(mWifiInfo.getSSID()).thenReturn(SCORED_NETWORK.networkKey.wifiKey.ssid); 155 when(mWifiInfo.getBSSID()).thenReturn(SCORED_NETWORK.networkKey.wifiKey.bssid); 156 when(mServiceConnection.getAppData()).thenReturn(NEW_SCORER); 157 when(mServiceConnection.getRecommendationProvider()).thenReturn(mRecommendationProvider); 158 when(mNetworkScorerAppManager.getActiveScorer()).thenReturn(NEW_SCORER); 159 mHandlerThread = new HandlerThread("NetworkScoreServiceTest"); 160 mHandlerThread.start(); 161 mNetworkScoreService = new NetworkScoreService(mContext, mNetworkScorerAppManager, 162 networkScorerAppData -> mServiceConnection, mHandlerThread.getLooper()); 163 WifiConfiguration configuration = new WifiConfiguration(); 164 configuration.SSID = "NetworkScoreServiceTest_SSID"; 165 configuration.BSSID = "NetworkScoreServiceTest_BSSID"; 166 populateScanResults(); 167 } 168 169 private void populateScanResults() { 170 mScanResults = new ArrayList<>(); 171 mScanResults.add(createScanResult(SSID, SCORED_NETWORK.networkKey.wifiKey.bssid)); 172 mScanResults.add(createScanResult(SSID_2, SCORED_NETWORK_2.networkKey.wifiKey.bssid)); 173 mScanResults.add(createScanResult(SSID_3, "10:10:00:00:10:10")); 174 } 175 176 private ScanResult createScanResult(String ssid, String bssid) { 177 ScanResult result = new ScanResult(); 178 result.wifiSsid = WifiSsid.createFromAsciiEncoded(ssid); 179 result.BSSID = bssid; 180 return result; 181 } 182 183 @After 184 public void tearDown() throws Exception { 185 mHandlerThread.quitSafely(); 186 } 187 188 @Test 189 public void testOnUserUnlocked() { 190 when(mNetworkScorerAppManager.getActiveScorer()).thenReturn(NEW_SCORER); 191 192 mNetworkScoreService.onUserUnlocked(0); 193 194 verify(mNetworkScorerAppManager).updateState(); 195 verify(mNetworkScorerAppManager).migrateNetworkScorerAppSettingIfNeeded(); 196 verify(mServiceConnection).bind(mContext); 197 } 198 199 @Test 200 public void testRequestScores_noPermission() throws Exception { 201 doThrow(new SecurityException()).when(mContext) 202 .enforceCallingOrSelfPermission(eq(permission.REQUEST_NETWORK_SCORES), 203 anyString()); 204 try { 205 mNetworkScoreService.requestScores(null); 206 fail("REQUEST_NETWORK_SCORES not enforced."); 207 } catch (SecurityException e) { 208 // expected 209 } 210 } 211 212 @Test 213 public void testRequestScores_providerNotConnected() throws Exception { 214 assertFalse(mNetworkScoreService.requestScores(new NetworkKey[0])); 215 verifyZeroInteractions(mRecommendationProvider); 216 } 217 218 @Test 219 public void testRequestScores_providerThrowsRemoteException() throws Exception { 220 doThrow(new RemoteException()).when(mRecommendationProvider) 221 .requestScores(any(NetworkKey[].class)); 222 mNetworkScoreService.onUserUnlocked(0); 223 224 assertFalse(mNetworkScoreService.requestScores(new NetworkKey[0])); 225 } 226 227 @Test 228 public void testRequestScores_providerAvailable() throws Exception { 229 mNetworkScoreService.onUserUnlocked(0); 230 231 final NetworkKey[] networks = new NetworkKey[0]; 232 assertTrue(mNetworkScoreService.requestScores(networks)); 233 verify(mRecommendationProvider).requestScores(networks); 234 } 235 236 @Test 237 public void dispatchingContentObserver_nullUri() throws Exception { 238 NetworkScoreService.DispatchingContentObserver observer = 239 new NetworkScoreService.DispatchingContentObserver(mContext, null /*handler*/); 240 241 observer.onChange(false, null); 242 // nothing to assert or verify but since we passed in a null handler we'd see a NPE 243 // if it were interacted with. 244 } 245 246 @Test 247 public void dispatchingContentObserver_dispatchUri() throws Exception { 248 final CountDownHandler handler = new CountDownHandler(mHandlerThread.getLooper()); 249 NetworkScoreService.DispatchingContentObserver observer = 250 new NetworkScoreService.DispatchingContentObserver(mContext, handler); 251 Uri uri = Uri.parse("content://settings/global/network_score_service_test"); 252 int expectedWhat = 24; 253 observer.observe(uri, expectedWhat); 254 255 observer.onChange(false, uri); 256 final boolean msgHandled = handler.latch.await(3, TimeUnit.SECONDS); 257 assertTrue(msgHandled); 258 assertEquals(expectedWhat, handler.receivedWhat); 259 } 260 261 @Test 262 public void testUpdateScores_notActiveScorer() { 263 bindToScorer(false /*callerIsScorer*/); 264 265 try { 266 mNetworkScoreService.updateScores(new ScoredNetwork[0]); 267 fail("SecurityException expected"); 268 } catch (SecurityException e) { 269 // expected 270 } 271 } 272 273 @Test 274 public void testUpdateScores_oneRegisteredCache() throws RemoteException { 275 bindToScorer(true /*callerIsScorer*/); 276 277 mNetworkScoreService.registerNetworkScoreCache(NetworkKey.TYPE_WIFI, 278 mNetworkScoreCache, CACHE_FILTER_NONE); 279 280 mNetworkScoreService.updateScores(new ScoredNetwork[]{SCORED_NETWORK}); 281 282 verify(mNetworkScoreCache).updateScores(mScoredNetworkCaptor.capture()); 283 284 assertEquals(1, mScoredNetworkCaptor.getValue().size()); 285 assertEquals(SCORED_NETWORK, mScoredNetworkCaptor.getValue().get(0)); 286 } 287 288 @Test 289 public void testUpdateScores_twoRegisteredCaches() throws RemoteException { 290 bindToScorer(true /*callerIsScorer*/); 291 292 mNetworkScoreService.registerNetworkScoreCache(NetworkKey.TYPE_WIFI, 293 mNetworkScoreCache, CACHE_FILTER_NONE); 294 mNetworkScoreService.registerNetworkScoreCache( 295 NetworkKey.TYPE_WIFI, mNetworkScoreCache2, CACHE_FILTER_NONE); 296 297 // updateScores should update both caches 298 mNetworkScoreService.updateScores(new ScoredNetwork[]{SCORED_NETWORK}); 299 300 verify(mNetworkScoreCache).updateScores(anyListOf(ScoredNetwork.class)); 301 verify(mNetworkScoreCache2).updateScores(anyListOf(ScoredNetwork.class)); 302 303 mNetworkScoreService.unregisterNetworkScoreCache( 304 NetworkKey.TYPE_WIFI, mNetworkScoreCache2); 305 306 // updateScores should only update the first cache since the 2nd has been unregistered 307 mNetworkScoreService.updateScores(new ScoredNetwork[]{SCORED_NETWORK}); 308 309 verify(mNetworkScoreCache, times(2)).updateScores(anyListOf(ScoredNetwork.class)); 310 311 mNetworkScoreService.unregisterNetworkScoreCache( 312 NetworkKey.TYPE_WIFI, mNetworkScoreCache); 313 314 // updateScores should not update any caches since they are both unregistered 315 mNetworkScoreService.updateScores(new ScoredNetwork[]{SCORED_NETWORK}); 316 317 // The register and unregister calls grab the binder from the score cache. 318 verify(mNetworkScoreCache, atLeastOnce()).asBinder(); 319 verify(mNetworkScoreCache2, atLeastOnce()).asBinder(); 320 verifyNoMoreInteractions(mNetworkScoreCache, mNetworkScoreCache2); 321 } 322 323 @Test 324 public void testClearScores_notActiveScorer_noRequestNetworkScoresPermission() { 325 bindToScorer(false /*callerIsScorer*/); 326 when(mContext.checkCallingOrSelfPermission(permission.REQUEST_NETWORK_SCORES)) 327 .thenReturn(PackageManager.PERMISSION_DENIED); 328 try { 329 mNetworkScoreService.clearScores(); 330 fail("SecurityException expected"); 331 } catch (SecurityException e) { 332 // expected 333 } 334 } 335 336 @Test 337 public void testClearScores_activeScorer_noRequestNetworkScoresPermission() { 338 bindToScorer(true /*callerIsScorer*/); 339 when(mContext.checkCallingOrSelfPermission(permission.REQUEST_NETWORK_SCORES)) 340 .thenReturn(PackageManager.PERMISSION_DENIED); 341 342 mNetworkScoreService.clearScores(); 343 } 344 345 @Test 346 public void testClearScores_activeScorer() throws RemoteException { 347 bindToScorer(true /*callerIsScorer*/); 348 349 mNetworkScoreService.registerNetworkScoreCache(NetworkKey.TYPE_WIFI, mNetworkScoreCache, 350 CACHE_FILTER_NONE); 351 mNetworkScoreService.clearScores(); 352 353 verify(mNetworkScoreCache).clearScores(); 354 } 355 356 @Test 357 public void testClearScores_notActiveScorer_hasRequestNetworkScoresPermission() 358 throws RemoteException { 359 bindToScorer(false /*callerIsScorer*/); 360 when(mContext.checkCallingOrSelfPermission(permission.REQUEST_NETWORK_SCORES)) 361 .thenReturn(PackageManager.PERMISSION_GRANTED); 362 363 mNetworkScoreService.registerNetworkScoreCache(NetworkKey.TYPE_WIFI, mNetworkScoreCache, 364 CACHE_FILTER_NONE); 365 mNetworkScoreService.clearScores(); 366 367 verify(mNetworkScoreCache).clearScores(); 368 } 369 370 @Test 371 public void testSetActiveScorer_noRequestNetworkScoresPermission() { 372 when(mContext.checkCallingOrSelfPermission(permission.REQUEST_NETWORK_SCORES)) 373 .thenReturn(PackageManager.PERMISSION_DENIED); 374 375 try { 376 mNetworkScoreService.setActiveScorer(null); 377 fail("SecurityException expected"); 378 } catch (SecurityException e) { 379 // expected 380 } 381 } 382 383 @Test 384 public void testSetActiveScorer_requestNetworkScoresPermission() { 385 when(mContext.checkCallingOrSelfPermission(permission.REQUEST_NETWORK_SCORES)) 386 .thenReturn(PackageManager.PERMISSION_GRANTED); 387 388 mNetworkScoreService.setActiveScorer(null); 389 } 390 391 @Test 392 public void testDisableScoring_notActiveScorer_noRequestNetworkScoresPermission() { 393 bindToScorer(false /*callerIsScorer*/); 394 when(mContext.checkCallingOrSelfPermission(permission.REQUEST_NETWORK_SCORES)) 395 .thenReturn(PackageManager.PERMISSION_DENIED); 396 397 try { 398 mNetworkScoreService.disableScoring(); 399 fail("SecurityException expected"); 400 } catch (SecurityException e) { 401 // expected 402 } 403 } 404 405 @Test 406 public void testDisableScoring_activeScorer_noRequestNetworkScoresPermission() { 407 bindToScorer(true /*callerIsScorer*/); 408 when(mContext.checkCallingOrSelfPermission(permission.REQUEST_NETWORK_SCORES)) 409 .thenReturn(PackageManager.PERMISSION_DENIED); 410 411 mNetworkScoreService.disableScoring(); 412 } 413 414 @Test 415 public void testGetAllValidScorer_noRequestNetworkScoresPermission() { 416 when(mContext.checkCallingOrSelfPermission(permission.REQUEST_NETWORK_SCORES)) 417 .thenReturn(PackageManager.PERMISSION_DENIED); 418 419 try { 420 mNetworkScoreService.getAllValidScorers(); 421 fail("SecurityException expected"); 422 } catch (SecurityException e) { 423 // expected 424 } 425 } 426 427 @Test 428 public void testGetAllValidScorer_requestNetworkScoresPermission() { 429 when(mContext.checkCallingOrSelfPermission(permission.REQUEST_NETWORK_SCORES)) 430 .thenReturn(PackageManager.PERMISSION_GRANTED); 431 432 mNetworkScoreService.getAllValidScorers(); 433 } 434 435 @Test 436 public void testRegisterNetworkScoreCache_noRequestNetworkScoresPermission() { 437 doThrow(new SecurityException()).when(mContext).enforceCallingOrSelfPermission( 438 eq(permission.REQUEST_NETWORK_SCORES), anyString()); 439 440 try { 441 mNetworkScoreService.registerNetworkScoreCache( 442 NetworkKey.TYPE_WIFI, mNetworkScoreCache, CACHE_FILTER_NONE); 443 fail("SecurityException expected"); 444 } catch (SecurityException e) { 445 // expected 446 } 447 } 448 449 @Test 450 public void testUnregisterNetworkScoreCache_noRequestNetworkScoresPermission() { 451 doThrow(new SecurityException()).when(mContext).enforceCallingOrSelfPermission( 452 eq(permission.REQUEST_NETWORK_SCORES), anyString()); 453 454 try { 455 mNetworkScoreService.unregisterNetworkScoreCache( 456 NetworkKey.TYPE_WIFI, mNetworkScoreCache); 457 fail("SecurityException expected"); 458 } catch (SecurityException e) { 459 // expected 460 } 461 } 462 463 @Test 464 public void testDump_doesNotCrash() { 465 when(mNetworkScorerAppManager.getActiveScorer()).thenReturn(NEW_SCORER); 466 StringWriter stringWriter = new StringWriter(); 467 468 mNetworkScoreService.dump( 469 new FileDescriptor(), new PrintWriter(stringWriter), new String[0]); 470 471 assertFalse(stringWriter.toString().isEmpty()); 472 } 473 474 @Test 475 public void testIsCallerActiveScorer_noBoundService() throws Exception { 476 // No active scorer. 477 when(mNetworkScorerAppManager.getActiveScorer()).thenReturn(null); 478 mNetworkScoreService.onUserUnlocked(0); 479 480 mNetworkScoreService.isCallerActiveScorer(Binder.getCallingUid()); 481 482 verify(mServiceConnection, never()).getAppData(); 483 } 484 485 @Test 486 public void testIsCallerActiveScorer_boundServiceIsNotCaller() throws Exception { 487 bindToScorer(false /*callerIsScorer*/); 488 489 assertFalse(mNetworkScoreService.isCallerActiveScorer(Binder.getCallingUid())); 490 } 491 492 @Test 493 public void testIsCallerActiveScorer_boundServiceIsCaller() throws Exception { 494 bindToScorer(true /*callerIsScorer*/); 495 496 assertTrue(mNetworkScoreService.isCallerActiveScorer(Binder.getCallingUid())); 497 } 498 499 @Test 500 public void testGetActiveScorerPackage_notActive() throws Exception { 501 // No active scorer. 502 when(mNetworkScorerAppManager.getActiveScorer()).thenReturn(null); 503 mNetworkScoreService.onUserUnlocked(0); 504 505 mNetworkScoreService.getActiveScorerPackage(); 506 507 verify(mServiceConnection, never()).getPackageName(); 508 } 509 510 @Test 511 public void testGetActiveScorerPackage_active() throws Exception { 512 when(mNetworkScorerAppManager.getActiveScorer()).thenReturn(NEW_SCORER); 513 mNetworkScoreService.onUserUnlocked(0); 514 515 mNetworkScoreService.getActiveScorerPackage(); 516 517 verify(mServiceConnection).getPackageName(); 518 } 519 520 @Test 521 public void testCacheUpdatingConsumer_nullFilter() throws Exception { 522 List<ScoredNetwork> scoredNetworkList = Lists.newArrayList(SCORED_NETWORK); 523 NetworkScoreService.FilteringCacheUpdatingConsumer consumer = 524 new NetworkScoreService.FilteringCacheUpdatingConsumer(mContext, 525 new ArrayList<>(scoredNetworkList), NetworkKey.TYPE_WIFI, 526 mCurrentNetworkFilter, mScanResultsFilter); 527 528 consumer.accept(mNetworkScoreCache, null /*cookie*/); 529 530 verify(mNetworkScoreCache).updateScores(scoredNetworkList); 531 verifyZeroInteractions(mCurrentNetworkFilter, mScanResultsFilter); 532 } 533 534 @Test 535 public void testCacheUpdatingConsumer_noneFilter() throws Exception { 536 List<ScoredNetwork> scoredNetworkList = Lists.newArrayList(SCORED_NETWORK); 537 NetworkScoreService.FilteringCacheUpdatingConsumer 538 consumer = new NetworkScoreService.FilteringCacheUpdatingConsumer(mContext, 539 new ArrayList<>(scoredNetworkList), 540 NetworkKey.TYPE_WIFI, mCurrentNetworkFilter, mScanResultsFilter); 541 542 consumer.accept(mNetworkScoreCache, NetworkScoreManager.CACHE_FILTER_NONE); 543 544 verify(mNetworkScoreCache).updateScores(scoredNetworkList); 545 verifyZeroInteractions(mCurrentNetworkFilter, mScanResultsFilter); 546 } 547 548 @Test 549 public void testCacheUpdatingConsumer_unknownFilter() throws Exception { 550 List<ScoredNetwork> scoredNetworkList = Lists.newArrayList(SCORED_NETWORK); 551 NetworkScoreService.FilteringCacheUpdatingConsumer 552 consumer = new NetworkScoreService.FilteringCacheUpdatingConsumer(mContext, 553 new ArrayList<>(scoredNetworkList), 554 NetworkKey.TYPE_WIFI, mCurrentNetworkFilter, mScanResultsFilter); 555 556 consumer.accept(mNetworkScoreCache, -1 /*cookie*/); 557 558 verify(mNetworkScoreCache).updateScores(scoredNetworkList); 559 verifyZeroInteractions(mCurrentNetworkFilter, mScanResultsFilter); 560 } 561 562 @Test 563 public void testCacheUpdatingConsumer_nonIntFilter() throws Exception { 564 List<ScoredNetwork> scoredNetworkList = Lists.newArrayList(SCORED_NETWORK); 565 NetworkScoreService.FilteringCacheUpdatingConsumer 566 consumer = new NetworkScoreService.FilteringCacheUpdatingConsumer(mContext, 567 new ArrayList<>(scoredNetworkList), 568 NetworkKey.TYPE_WIFI, mCurrentNetworkFilter, mScanResultsFilter); 569 570 consumer.accept(mNetworkScoreCache, "not an int" /*cookie*/); 571 572 verify(mNetworkScoreCache).updateScores(scoredNetworkList); 573 verifyZeroInteractions(mCurrentNetworkFilter, mScanResultsFilter); 574 } 575 576 @Test 577 public void testCacheUpdatingConsumer_emptyScoreList() throws Exception { 578 NetworkScoreService.FilteringCacheUpdatingConsumer 579 consumer = new NetworkScoreService.FilteringCacheUpdatingConsumer(mContext, 580 Collections.emptyList(), 581 NetworkKey.TYPE_WIFI, mCurrentNetworkFilter, mScanResultsFilter); 582 583 consumer.accept(mNetworkScoreCache, NetworkScoreManager.CACHE_FILTER_NONE); 584 585 verifyZeroInteractions(mNetworkScoreCache, mCurrentNetworkFilter, mScanResultsFilter); 586 } 587 588 @Test 589 public void testCacheUpdatingConsumer_currentNetworkFilter() throws Exception { 590 List<ScoredNetwork> scoredNetworkList = 591 Lists.newArrayList(SCORED_NETWORK, SCORED_NETWORK_2); 592 NetworkScoreService.FilteringCacheUpdatingConsumer 593 consumer = new NetworkScoreService.FilteringCacheUpdatingConsumer(mContext, 594 new ArrayList<>(scoredNetworkList), 595 NetworkKey.TYPE_WIFI, mCurrentNetworkFilter, mScanResultsFilter); 596 597 List<ScoredNetwork> filteredList = new ArrayList<>(scoredNetworkList); 598 filteredList.remove(SCORED_NETWORK); 599 when(mCurrentNetworkFilter.apply(scoredNetworkList)).thenReturn(filteredList); 600 consumer.accept(mNetworkScoreCache, NetworkScoreManager.CACHE_FILTER_CURRENT_NETWORK); 601 602 verify(mNetworkScoreCache).updateScores(filteredList); 603 verifyZeroInteractions(mScanResultsFilter); 604 } 605 606 @Test 607 public void testCacheUpdatingConsumer_scanResultsFilter() throws Exception { 608 List<ScoredNetwork> scoredNetworkList = 609 Lists.newArrayList(SCORED_NETWORK, SCORED_NETWORK_2); 610 NetworkScoreService.FilteringCacheUpdatingConsumer 611 consumer = new NetworkScoreService.FilteringCacheUpdatingConsumer(mContext, 612 new ArrayList<>(scoredNetworkList), 613 NetworkKey.TYPE_WIFI, mCurrentNetworkFilter, mScanResultsFilter); 614 615 List<ScoredNetwork> filteredList = new ArrayList<>(scoredNetworkList); 616 filteredList.remove(SCORED_NETWORK); 617 when(mScanResultsFilter.apply(scoredNetworkList)).thenReturn(filteredList); 618 consumer.accept(mNetworkScoreCache, NetworkScoreManager.CACHE_FILTER_SCAN_RESULTS); 619 620 verify(mNetworkScoreCache).updateScores(filteredList); 621 verifyZeroInteractions(mCurrentNetworkFilter); 622 } 623 624 @Test 625 public void testCurrentNetworkScoreCacheFilter_nullWifiInfo() throws Exception { 626 NetworkScoreService.CurrentNetworkScoreCacheFilter cacheFilter = 627 new NetworkScoreService.CurrentNetworkScoreCacheFilter(() -> null /*WifiInfo*/); 628 629 List<ScoredNetwork> actualList = 630 cacheFilter.apply(Lists.newArrayList(SCORED_NETWORK, SCORED_NETWORK_2)); 631 632 assertTrue(actualList.isEmpty()); 633 } 634 635 @Test 636 public void testCurrentNetworkScoreCacheFilter_invalidWifiInfo_nullSsid() throws Exception { 637 when(mWifiInfo.getSSID()).thenReturn(null); 638 NetworkScoreService.CurrentNetworkScoreCacheFilter cacheFilter = 639 new NetworkScoreService.CurrentNetworkScoreCacheFilter(() -> mWifiInfo); 640 641 List<ScoredNetwork> actualList = 642 cacheFilter.apply(Lists.newArrayList(SCORED_NETWORK, SCORED_NETWORK_2)); 643 644 assertTrue(actualList.isEmpty()); 645 } 646 647 @Test 648 public void testCurrentNetworkScoreCacheFilter_invalidWifiInfo_noneSsid() throws Exception { 649 when(mWifiInfo.getSSID()).thenReturn(WifiSsid.NONE); 650 NetworkScoreService.CurrentNetworkScoreCacheFilter cacheFilter = 651 new NetworkScoreService.CurrentNetworkScoreCacheFilter(() -> mWifiInfo); 652 653 List<ScoredNetwork> actualList = 654 cacheFilter.apply(Lists.newArrayList(SCORED_NETWORK, SCORED_NETWORK_2)); 655 656 assertTrue(actualList.isEmpty()); 657 } 658 659 @Test 660 public void testCurrentNetworkScoreCacheFilter_invalidWifiInfo_emptySsid() throws Exception { 661 when(mWifiInfo.getSSID()).thenReturn(""); 662 NetworkScoreService.CurrentNetworkScoreCacheFilter cacheFilter = 663 new NetworkScoreService.CurrentNetworkScoreCacheFilter(() -> mWifiInfo); 664 665 List<ScoredNetwork> actualList = 666 cacheFilter.apply(Lists.newArrayList(SCORED_NETWORK, SCORED_NETWORK_2)); 667 668 assertTrue(actualList.isEmpty()); 669 } 670 671 @Test 672 public void testCurrentNetworkScoreCacheFilter_invalidWifiInfo_invalidBssid() throws Exception { 673 when(mWifiInfo.getBSSID()).thenReturn(INVALID_BSSID); 674 NetworkScoreService.CurrentNetworkScoreCacheFilter cacheFilter = 675 new NetworkScoreService.CurrentNetworkScoreCacheFilter(() -> mWifiInfo); 676 677 List<ScoredNetwork> actualList = 678 cacheFilter.apply(Lists.newArrayList(SCORED_NETWORK, SCORED_NETWORK_2)); 679 680 assertTrue(actualList.isEmpty()); 681 } 682 683 @Test 684 public void testCurrentNetworkScoreCacheFilter_scoreFiltered() throws Exception { 685 NetworkScoreService.CurrentNetworkScoreCacheFilter cacheFilter = 686 new NetworkScoreService.CurrentNetworkScoreCacheFilter(() -> mWifiInfo); 687 688 List<ScoredNetwork> actualList = 689 cacheFilter.apply(Lists.newArrayList(SCORED_NETWORK, SCORED_NETWORK_2)); 690 691 List<ScoredNetwork> expectedList = Collections.singletonList(SCORED_NETWORK); 692 assertEquals(expectedList, actualList); 693 } 694 695 @Test 696 public void testCurrentNetworkScoreCacheFilter_currentNetworkNotInList() throws Exception { 697 when(mWifiInfo.getSSID()).thenReturn("\"notInList\""); 698 NetworkScoreService.CurrentNetworkScoreCacheFilter cacheFilter = 699 new NetworkScoreService.CurrentNetworkScoreCacheFilter(() -> mWifiInfo); 700 701 List<ScoredNetwork> actualList = 702 cacheFilter.apply(Lists.newArrayList(SCORED_NETWORK, SCORED_NETWORK_2)); 703 704 assertTrue(actualList.isEmpty()); 705 } 706 707 @Test 708 public void testScanResultsScoreCacheFilter_emptyScanResults() throws Exception { 709 NetworkScoreService.ScanResultsScoreCacheFilter cacheFilter = 710 new NetworkScoreService.ScanResultsScoreCacheFilter(Collections::emptyList); 711 712 List<ScoredNetwork> actualList = 713 cacheFilter.apply(Lists.newArrayList(SCORED_NETWORK, SCORED_NETWORK_2)); 714 715 assertTrue(actualList.isEmpty()); 716 } 717 718 @Test 719 public void testScanResultsScoreCacheFilter_invalidScanResults() throws Exception { 720 List<ScanResult> invalidScanResults = Lists.newArrayList( 721 new ScanResult(), 722 createScanResult("", SCORED_NETWORK.networkKey.wifiKey.bssid), 723 createScanResult(WifiSsid.NONE, SCORED_NETWORK.networkKey.wifiKey.bssid), 724 createScanResult(SSID, null), 725 createScanResult(SSID, INVALID_BSSID) 726 ); 727 NetworkScoreService.ScanResultsScoreCacheFilter cacheFilter = 728 new NetworkScoreService.ScanResultsScoreCacheFilter(() -> invalidScanResults); 729 730 List<ScoredNetwork> actualList = 731 cacheFilter.apply(Lists.newArrayList(SCORED_NETWORK, SCORED_NETWORK_2)); 732 733 assertTrue(actualList.isEmpty()); 734 } 735 736 @Test 737 public void testScanResultsScoreCacheFilter_scoresFiltered() throws Exception { 738 NetworkScoreService.ScanResultsScoreCacheFilter cacheFilter = 739 new NetworkScoreService.ScanResultsScoreCacheFilter(() -> mScanResults); 740 741 ScoredNetwork unmatchedScore = 742 new ScoredNetwork(new NetworkKey(new WifiKey(quote("newSsid"), 743 "00:00:00:00:00:00")), null /* rssiCurve*/); 744 745 List<ScoredNetwork> actualList = 746 cacheFilter.apply(Lists.newArrayList(SCORED_NETWORK, SCORED_NETWORK_2, 747 unmatchedScore)); 748 749 List<ScoredNetwork> expectedList = Lists.newArrayList(SCORED_NETWORK, SCORED_NETWORK_2); 750 assertEquals(expectedList, actualList); 751 } 752 753 @Test 754 public void testGetActiveScorer_notConnected_canRequestScores() throws Exception { 755 when(mContext.checkCallingOrSelfPermission(permission.REQUEST_NETWORK_SCORES)) 756 .thenReturn(PackageManager.PERMISSION_GRANTED); 757 when(mNetworkScorerAppManager.getActiveScorer()).thenReturn(null); 758 mNetworkScoreService.onUserUnlocked(0); 759 760 mNetworkScoreService.getActiveScorer(); 761 762 verify(mServiceConnection, never()).getAppData(); 763 } 764 765 @Test 766 public void testGetActiveScorer_notConnected_canNotRequestScores() throws Exception { 767 when(mContext.checkCallingOrSelfPermission(permission.REQUEST_NETWORK_SCORES)) 768 .thenReturn(PackageManager.PERMISSION_DENIED); 769 try { 770 mNetworkScoreService.getActiveScorer(); 771 fail("SecurityException expected."); 772 } catch (SecurityException e) { 773 // expected 774 } 775 } 776 777 @Test 778 public void testGetActiveScorer_connected_canRequestScores() 779 throws Exception { 780 when(mContext.checkCallingOrSelfPermission(permission.REQUEST_NETWORK_SCORES)) 781 .thenReturn(PackageManager.PERMISSION_GRANTED); 782 mNetworkScoreService.onUserUnlocked(0); 783 784 mNetworkScoreService.getActiveScorer(); 785 786 verify(mServiceConnection).getAppData(); 787 } 788 789 @Test 790 public void testGetActiveScorer_connected_canNotRequestScores() 791 throws Exception { 792 when(mContext.checkCallingOrSelfPermission(permission.REQUEST_NETWORK_SCORES)) 793 .thenReturn(PackageManager.PERMISSION_DENIED); 794 bindToScorer(false); 795 try { 796 mNetworkScoreService.getActiveScorer(); 797 fail("SecurityException expected."); 798 } catch (SecurityException e) { 799 // expected 800 } 801 } 802 803 @Test 804 public void testServiceConnection_bind_notBound() throws Exception { 805 NetworkScoreService.ScoringServiceConnection connection = new NetworkScoreService 806 .ScoringServiceConnection(NEW_SCORER); 807 connection.bind(mContext); 808 809 verify(mContext).bindServiceAsUser(MockUtils.checkIntent( 810 new Intent(NetworkScoreManager.ACTION_RECOMMEND_NETWORKS) 811 .setComponent(RECOMMENDATION_SERVICE_COMP)), 812 eq(connection), 813 eq(Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE), 814 eq(UserHandle.SYSTEM)); 815 } 816 817 @Test 818 public void testServiceConnection_bind_alreadyBound() throws Exception { 819 NetworkScoreService.ScoringServiceConnection connection = new NetworkScoreService 820 .ScoringServiceConnection(NEW_SCORER); 821 822 when(mContext.bindServiceAsUser(MockUtils.checkIntent( 823 new Intent(NetworkScoreManager.ACTION_RECOMMEND_NETWORKS) 824 .setComponent(RECOMMENDATION_SERVICE_COMP)), 825 eq(connection), 826 eq(Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE), 827 eq(UserHandle.SYSTEM))).thenReturn(true /*bound*/); 828 829 // Calling bind more than once should only result in 1 bindService call. 830 connection.bind(mContext); 831 connection.bind(mContext); 832 833 verify(mContext, times(1)).bindServiceAsUser(MockUtils.checkIntent( 834 new Intent(NetworkScoreManager.ACTION_RECOMMEND_NETWORKS) 835 .setComponent(RECOMMENDATION_SERVICE_COMP)), 836 eq(connection), 837 eq(Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE), 838 eq(UserHandle.SYSTEM)); 839 } 840 841 @Test 842 public void testServiceConnection_bindFails() throws Exception { 843 NetworkScoreService.ScoringServiceConnection connection = new NetworkScoreService 844 .ScoringServiceConnection(NEW_SCORER); 845 846 when(mContext.bindServiceAsUser(MockUtils.checkIntent( 847 new Intent(NetworkScoreManager.ACTION_RECOMMEND_NETWORKS) 848 .setComponent(RECOMMENDATION_SERVICE_COMP)), 849 eq(connection), 850 eq(Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE), 851 eq(UserHandle.SYSTEM))).thenReturn(false /*bound*/); 852 853 connection.bind(mContext); 854 855 verify(mContext).unbindService(connection); 856 } 857 858 @Test 859 public void testServiceConnection_unbind_notBound() throws Exception { 860 NetworkScoreService.ScoringServiceConnection connection = new NetworkScoreService 861 .ScoringServiceConnection(NEW_SCORER); 862 863 connection.unbind(mContext); 864 865 verify(mContext, never()).unbindService(connection); 866 } 867 868 @Test 869 public void testServiceConnection_unbind_alreadyBound() throws Exception { 870 NetworkScoreService.ScoringServiceConnection connection = new NetworkScoreService 871 .ScoringServiceConnection(NEW_SCORER); 872 873 when(mContext.bindServiceAsUser(MockUtils.checkIntent( 874 new Intent(NetworkScoreManager.ACTION_RECOMMEND_NETWORKS) 875 .setComponent(RECOMMENDATION_SERVICE_COMP)), 876 eq(connection), 877 eq(Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE), 878 eq(UserHandle.SYSTEM))).thenReturn(true /*bound*/); 879 880 connection.bind(mContext); 881 connection.unbind(mContext); 882 883 verify(mContext).unbindService(connection); 884 } 885 886 @Test 887 public void testServiceConnection_dump_doesNotCrash() throws Exception { 888 NetworkScoreService.ScoringServiceConnection connection = new NetworkScoreService 889 .ScoringServiceConnection(NEW_SCORER); 890 final StringWriter stringWriter = new StringWriter(); 891 892 connection.dump(new FileDescriptor(), new PrintWriter(stringWriter), new String[0]); 893 894 assertFalse(stringWriter.toString().isEmpty()); 895 } 896 897 private void bindToScorer(boolean callerIsScorer) { 898 final int callingUid = callerIsScorer ? Binder.getCallingUid() : Binder.getCallingUid() + 1; 899 NetworkScorerAppData appData = new NetworkScorerAppData(callingUid, 900 RECOMMENDATION_SERVICE_COMP, RECOMMENDATION_SERVICE_LABEL, 901 USE_WIFI_ENABLE_ACTIVITY_COMP, NETWORK_AVAILABLE_NOTIFICATION_CHANNEL_ID); 902 when(mServiceConnection.getAppData()).thenReturn(appData); 903 mNetworkScoreService.onUserUnlocked(0); 904 } 905 906 private static class CountDownHandler extends Handler { 907 CountDownLatch latch = new CountDownLatch(1); 908 int receivedWhat; 909 910 CountDownHandler(Looper looper) { 911 super(looper); 912 } 913 914 @Override 915 public void handleMessage(Message msg) { 916 latch.countDown(); 917 receivedWhat = msg.what; 918 } 919 } 920} 921