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