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