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