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