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