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