1 /* 2 * Copyright (C) 2014 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 17 package com.android.server; 18 19 import static junit.framework.Assert.assertEquals; 20 import static junit.framework.Assert.assertNotNull; 21 import static junit.framework.Assert.assertNull; 22 import static junit.framework.Assert.assertTrue; 23 24 import static org.junit.Assert.assertFalse; 25 import static org.mockito.ArgumentMatchers.anyString; 26 import static org.mockito.Matchers.any; 27 import static org.mockito.Matchers.anyInt; 28 import static org.mockito.Matchers.eq; 29 import static org.mockito.Mockito.never; 30 import static org.mockito.Mockito.verify; 31 import static org.mockito.Mockito.when; 32 33 import android.Manifest.permission; 34 import android.app.AppOpsManager; 35 import android.content.ComponentName; 36 import android.content.Context; 37 import android.content.Intent; 38 import android.content.pm.ActivityInfo; 39 import android.content.pm.ApplicationInfo; 40 import android.content.pm.PackageManager; 41 import android.content.pm.ResolveInfo; 42 import android.content.pm.ServiceInfo; 43 import android.content.res.Resources; 44 import android.net.NetworkScoreManager; 45 import android.net.NetworkScorerAppData; 46 import android.os.Bundle; 47 import android.provider.Settings; 48 import android.support.test.runner.AndroidJUnit4; 49 50 import com.android.internal.R; 51 52 import org.junit.Before; 53 import org.junit.Test; 54 import org.junit.runner.RunWith; 55 import org.mockito.Mock; 56 import org.mockito.Mockito; 57 import org.mockito.MockitoAnnotations; 58 import org.mockito.compat.ArgumentMatcher; 59 60 import java.util.ArrayList; 61 import java.util.List; 62 63 @RunWith(AndroidJUnit4.class) 64 public class NetworkScorerAppManagerTest { 65 private static final int PACKAGE_UID = 924; 66 private static String MOCK_SERVICE_LABEL = "Mock Service"; 67 private static String MOCK_OVERRIDEN_SERVICE_LABEL = "Mock Service Label Override"; 68 private static String MOCK_NETWORK_AVAILABLE_NOTIFICATION_CHANNEL_ID = 69 "Mock Network Available Notification Channel Id"; 70 private static final ComponentName RECO_COMPONENT = new ComponentName("package1", "class1"); 71 72 @Mock private Context mMockContext; 73 @Mock private PackageManager mMockPm; 74 @Mock private Resources mResources; 75 @Mock private NetworkScorerAppManager.SettingsFacade mSettingsFacade; 76 @Mock private AppOpsManager mAppOpsManager; 77 private NetworkScorerAppManager mNetworkScorerAppManager; 78 private List<ResolveInfo> mAvailableServices; 79 80 @Before 81 public void setUp() throws Exception { 82 MockitoAnnotations.initMocks(this); 83 mAvailableServices = new ArrayList<>(); 84 when(mMockContext.getPackageManager()).thenReturn(mMockPm); 85 when(mMockPm.queryIntentServices(Mockito.argThat(new ArgumentMatcher<Intent>() { 86 @Override 87 public boolean matchesObject(Object object) { 88 Intent intent = (Intent) object; 89 return NetworkScoreManager.ACTION_RECOMMEND_NETWORKS.equals(intent.getAction()); 90 } 91 }), eq(PackageManager.GET_META_DATA))).thenReturn(mAvailableServices); 92 when(mMockContext.getResources()).thenReturn(mResources); 93 when(mMockContext.getSystemService(Context.APP_OPS_SERVICE)).thenReturn(mAppOpsManager); 94 95 mockLocationModeOn(); 96 mockLocationPermissionGranted(PACKAGE_UID, RECO_COMPONENT.getPackageName()); 97 98 mNetworkScorerAppManager = new NetworkScorerAppManager(mMockContext, mSettingsFacade); 99 } 100 101 @Test 102 public void testGetActiveScorer_providerAvailable() throws Exception { 103 setNetworkRecoPackageSetting(RECO_COMPONENT.getPackageName()); 104 mockScoreNetworksGranted(RECO_COMPONENT.getPackageName()); 105 mockRecommendationServiceAvailable(RECO_COMPONENT, PACKAGE_UID /* packageUid */); 106 107 final NetworkScorerAppData activeScorer = mNetworkScorerAppManager.getActiveScorer(); 108 assertNotNull(activeScorer); 109 assertEquals(RECO_COMPONENT, activeScorer.getRecommendationServiceComponent()); 110 assertEquals(PACKAGE_UID, activeScorer.packageUid); 111 assertEquals(MOCK_SERVICE_LABEL, activeScorer.getRecommendationServiceLabel()); 112 } 113 114 @Test 115 public void testGetActiveScorer_providerAvailable_serviceLabelOverride() throws Exception { 116 setNetworkRecoPackageSetting(RECO_COMPONENT.getPackageName()); 117 mockScoreNetworksGranted(RECO_COMPONENT.getPackageName()); 118 mockRecommendationServiceAvailable(RECO_COMPONENT, PACKAGE_UID /* packageUid */, 119 null /* enableUseOpenWifiPackageActivityPackage*/, true /* serviceLabelOverride */); 120 121 final NetworkScorerAppData activeScorer = mNetworkScorerAppManager.getActiveScorer(); 122 assertNotNull(activeScorer); 123 assertEquals(RECO_COMPONENT, activeScorer.getRecommendationServiceComponent()); 124 assertEquals(PACKAGE_UID, activeScorer.packageUid); 125 assertEquals(MOCK_OVERRIDEN_SERVICE_LABEL, activeScorer.getRecommendationServiceLabel()); 126 } 127 128 @Test 129 public void testGetActiveScorer_scoreNetworksPermissionMissing() throws Exception { 130 setNetworkRecoPackageSetting(RECO_COMPONENT.getPackageName()); 131 mockScoreNetworksDenied(RECO_COMPONENT.getPackageName()); 132 mockRecommendationServiceAvailable(RECO_COMPONENT, PACKAGE_UID /* packageUid */); 133 134 final NetworkScorerAppData activeScorer = mNetworkScorerAppManager.getActiveScorer(); 135 assertNull(activeScorer); 136 } 137 138 @Test 139 public void testGetActiveScorer_locationPermissionMissing() throws Exception { 140 setNetworkRecoPackageSetting(RECO_COMPONENT.getPackageName()); 141 mockScoreNetworksGranted(RECO_COMPONENT.getPackageName()); 142 mockLocationPermissionDenied(PACKAGE_UID, RECO_COMPONENT.getPackageName()); 143 mockRecommendationServiceAvailable(RECO_COMPONENT, PACKAGE_UID /* packageUid */); 144 145 final NetworkScorerAppData activeScorer = mNetworkScorerAppManager.getActiveScorer(); 146 assertNull(activeScorer); 147 } 148 149 @Test 150 public void testGetActiveScorer_locationModeOff() throws Exception { 151 setNetworkRecoPackageSetting(RECO_COMPONENT.getPackageName()); 152 mockScoreNetworksGranted(RECO_COMPONENT.getPackageName()); 153 mockLocationPermissionGranted(PACKAGE_UID, RECO_COMPONENT.getPackageName()); 154 mockLocationModeOff(); 155 mockRecommendationServiceAvailable(RECO_COMPONENT, PACKAGE_UID /* packageUid */); 156 157 final NetworkScorerAppData activeScorer = mNetworkScorerAppManager.getActiveScorer(); 158 assertNull(activeScorer); 159 } 160 161 @Test 162 public void testGetActiveScorer_providerAvailable_enableUseOpenWifiActivityNotSet() 163 throws Exception { 164 setNetworkRecoPackageSetting(RECO_COMPONENT.getPackageName()); 165 mockScoreNetworksGranted(RECO_COMPONENT.getPackageName()); 166 mockRecommendationServiceAvailable(RECO_COMPONENT, PACKAGE_UID /* packageUid */, 167 null /* enableUseOpenWifiPackageActivityPackage*/); 168 169 final NetworkScorerAppData activeScorer = mNetworkScorerAppManager.getActiveScorer(); 170 assertNotNull(activeScorer); 171 assertEquals(RECO_COMPONENT, activeScorer.getRecommendationServiceComponent()); 172 assertEquals(PACKAGE_UID, activeScorer.packageUid); 173 assertNull(activeScorer.getEnableUseOpenWifiActivity()); 174 } 175 176 @Test 177 public void testGetActiveScorer_providerAvailable_enableUseOpenWifiActivityNotResolved() 178 throws Exception { 179 setNetworkRecoPackageSetting(RECO_COMPONENT.getPackageName()); 180 mockScoreNetworksGranted(RECO_COMPONENT.getPackageName()); 181 mockRecommendationServiceAvailable(RECO_COMPONENT, PACKAGE_UID /* packageUid */, 182 "package2" /* enableUseOpenWifiPackageActivityPackage*/); 183 184 final NetworkScorerAppData activeScorer = mNetworkScorerAppManager.getActiveScorer(); 185 assertNotNull(activeScorer); 186 assertEquals(RECO_COMPONENT, activeScorer.getRecommendationServiceComponent()); 187 assertEquals(PACKAGE_UID, activeScorer.packageUid); 188 assertNull(activeScorer.getEnableUseOpenWifiActivity()); 189 } 190 191 @Test 192 public void testGetActiveScorer_providerAvailable_enableUseOpenWifiActivityResolved() 193 throws Exception { 194 final ComponentName enableUseOpenWifiComponent = new ComponentName("package2", "class2"); 195 setNetworkRecoPackageSetting(RECO_COMPONENT.getPackageName()); 196 mockScoreNetworksGranted(RECO_COMPONENT.getPackageName()); 197 mockRecommendationServiceAvailable(RECO_COMPONENT, PACKAGE_UID /* packageUid */, 198 enableUseOpenWifiComponent.getPackageName()); 199 mockEnableUseOpenWifiActivity(enableUseOpenWifiComponent); 200 201 final NetworkScorerAppData activeScorer = mNetworkScorerAppManager.getActiveScorer(); 202 assertNotNull(activeScorer); 203 assertEquals(RECO_COMPONENT, activeScorer.getRecommendationServiceComponent()); 204 assertEquals(PACKAGE_UID, activeScorer.packageUid); 205 assertEquals(enableUseOpenWifiComponent, activeScorer.getEnableUseOpenWifiActivity()); 206 assertNull(activeScorer.getNetworkAvailableNotificationChannelId()); 207 } 208 209 @Test 210 public void testGetActiveScorer_providerAvailable_networkAvailableNotificationChannelIdSet() { 211 setNetworkRecoPackageSetting(RECO_COMPONENT.getPackageName()); 212 mockScoreNetworksGranted(RECO_COMPONENT.getPackageName()); 213 mockRecommendationServiceAvailable(RECO_COMPONENT, PACKAGE_UID /* packageUid */, 214 null /* enableUseOpenWifiActivityPackage */, false /* serviceLabelOverride */, 215 true /* setNotificationChannelId */); 216 217 final NetworkScorerAppData activeScorer = mNetworkScorerAppManager.getActiveScorer(); 218 assertNotNull(activeScorer); 219 assertEquals(RECO_COMPONENT, activeScorer.getRecommendationServiceComponent()); 220 assertEquals(PACKAGE_UID, activeScorer.packageUid); 221 assertEquals(MOCK_NETWORK_AVAILABLE_NOTIFICATION_CHANNEL_ID, 222 activeScorer.getNetworkAvailableNotificationChannelId()); 223 } 224 225 @Test 226 public void testGetActiveScorer_packageSettingIsNull() 227 throws Exception { 228 // NETWORK_RECOMMENDATIONS_PACKAGE is null 229 230 final NetworkScorerAppData activeScorer = mNetworkScorerAppManager.getActiveScorer(); 231 assertNull(activeScorer); 232 } 233 234 @Test 235 public void testGetActiveScorer_packageSettingIsInvalid() throws Exception { 236 setDefaultNetworkRecommendationPackage(RECO_COMPONENT.getPackageName()); 237 mockScoreNetworksGranted(RECO_COMPONENT.getPackageName()); 238 // NETWORK_RECOMMENDATIONS_PACKAGE is set to a package that isn't a recommender. 239 240 final NetworkScorerAppData activeScorer = mNetworkScorerAppManager.getActiveScorer(); 241 assertNull(activeScorer); 242 } 243 244 @Test 245 public void testSetActiveScorer_noChange() throws Exception { 246 String packageName = "package"; 247 setNetworkRecoPackageSetting(packageName); 248 249 assertTrue(mNetworkScorerAppManager.setActiveScorer(packageName)); 250 verify(mSettingsFacade, never()).putString(any(), any(), any()); 251 } 252 253 @Test 254 public void testSetActiveScorer_nullPackage_currentIsSet() throws Exception { 255 setNetworkRecoPackageSetting("package"); 256 257 assertTrue(mNetworkScorerAppManager.setActiveScorer(null)); 258 verify(mSettingsFacade).putString(mMockContext, 259 Settings.Global.NETWORK_RECOMMENDATIONS_PACKAGE, null); 260 verify(mSettingsFacade).putInt(mMockContext, 261 Settings.Global.NETWORK_RECOMMENDATIONS_ENABLED, 262 NetworkScoreManager.RECOMMENDATIONS_ENABLED_FORCED_OFF); 263 } 264 265 @Test 266 public void testSetActiveScorer_nullPackage_currentIsNull() throws Exception { 267 setNetworkRecoPackageSetting(null); 268 269 assertTrue(mNetworkScorerAppManager.setActiveScorer(null)); 270 verify(mSettingsFacade, never()).putString(any(), any(), any()); 271 } 272 273 @Test 274 public void testSetActiveScorer_validPackage() throws Exception { 275 String newPackage = "newPackage"; 276 int newAppUid = 621; 277 final ComponentName recoComponent = new ComponentName(newPackage, "class1"); 278 mockScoreNetworksGranted(recoComponent.getPackageName()); 279 mockRecommendationServiceAvailable(recoComponent, newAppUid, null); 280 mockLocationPermissionGranted(newAppUid, recoComponent.getPackageName()); 281 282 assertTrue(mNetworkScorerAppManager.setActiveScorer(newPackage)); 283 verify(mSettingsFacade).putString(mMockContext, 284 Settings.Global.NETWORK_RECOMMENDATIONS_PACKAGE, newPackage); 285 verify(mSettingsFacade).putInt(mMockContext, 286 Settings.Global.NETWORK_RECOMMENDATIONS_ENABLED, 287 NetworkScoreManager.RECOMMENDATIONS_ENABLED_ON); 288 } 289 290 @Test 291 public void testSetActiveScorer_invalidPackage() throws Exception { 292 String packageName = "package"; 293 String newPackage = "newPackage"; 294 setNetworkRecoPackageSetting(packageName); 295 // newPackage doesn't resolve to a valid recommender 296 297 assertFalse(mNetworkScorerAppManager.setActiveScorer(newPackage)); 298 verify(mSettingsFacade, never()).putString(any(), any(), any()); 299 } 300 301 @Test 302 public void testUpdateState_recommendationsForcedOff() throws Exception { 303 setRecommendationsEnabledSetting(NetworkScoreManager.RECOMMENDATIONS_ENABLED_FORCED_OFF); 304 305 mNetworkScorerAppManager.updateState(); 306 307 verify(mSettingsFacade, never()).getString(any(), 308 eq(Settings.Global.NETWORK_RECOMMENDATIONS_PACKAGE)); 309 verify(mSettingsFacade, never()).putInt(any(), 310 eq(Settings.Global.NETWORK_RECOMMENDATIONS_ENABLED), anyInt()); 311 } 312 313 @Test 314 public void testUpdateState_currentPackageValid() throws Exception { 315 setNetworkRecoPackageSetting(RECO_COMPONENT.getPackageName()); 316 mockScoreNetworksGranted(RECO_COMPONENT.getPackageName()); 317 mockRecommendationServiceAvailable(RECO_COMPONENT, PACKAGE_UID , null); 318 319 mNetworkScorerAppManager.updateState(); 320 321 verify(mSettingsFacade, never()).putString(any(), 322 eq(Settings.Global.NETWORK_RECOMMENDATIONS_PACKAGE), any()); 323 verify(mSettingsFacade).putInt(mMockContext, 324 Settings.Global.NETWORK_RECOMMENDATIONS_ENABLED, 325 NetworkScoreManager.RECOMMENDATIONS_ENABLED_ON); 326 } 327 328 @Test 329 public void testUpdateState_currentPackageNotValid_validDefault() throws Exception { 330 final String defaultPackage = "defaultPackage"; 331 final int defaultAppUid = 621; 332 final ComponentName recoComponent = new ComponentName(defaultPackage, "class1"); 333 setDefaultNetworkRecommendationPackage(defaultPackage); 334 mockScoreNetworksGranted(recoComponent.getPackageName()); 335 mockRecommendationServiceAvailable(recoComponent, defaultAppUid, null); 336 mockLocationPermissionGranted(defaultAppUid, defaultPackage); 337 338 mNetworkScorerAppManager.updateState(); 339 340 verify(mSettingsFacade).putString(mMockContext, 341 Settings.Global.NETWORK_RECOMMENDATIONS_PACKAGE, defaultPackage); 342 verify(mSettingsFacade).putInt(mMockContext, 343 Settings.Global.NETWORK_RECOMMENDATIONS_ENABLED, 344 NetworkScoreManager.RECOMMENDATIONS_ENABLED_ON); 345 } 346 347 @Test 348 public void testUpdateState_currentPackageNotValid_invalidDefault() throws Exception { 349 String defaultPackage = "defaultPackage"; 350 setDefaultNetworkRecommendationPackage(defaultPackage); 351 setNetworkRecoPackageSetting("currentPackage"); 352 353 mNetworkScorerAppManager.updateState(); 354 355 verify(mSettingsFacade).putInt(mMockContext, 356 Settings.Global.NETWORK_RECOMMENDATIONS_ENABLED, 357 NetworkScoreManager.RECOMMENDATIONS_ENABLED_OFF); 358 } 359 360 @Test 361 public void testUpdateState_currentPackageNull_defaultNull() throws Exception { 362 setDefaultNetworkRecommendationPackage(null); 363 setNetworkRecoPackageSetting(null); 364 365 mNetworkScorerAppManager.updateState(); 366 367 verify(mSettingsFacade, never()).putString(any(), 368 eq(Settings.Global.NETWORK_RECOMMENDATIONS_PACKAGE), anyString()); 369 verify(mSettingsFacade).putInt(mMockContext, 370 Settings.Global.NETWORK_RECOMMENDATIONS_ENABLED, 371 NetworkScoreManager.RECOMMENDATIONS_ENABLED_OFF); 372 } 373 374 @Test 375 public void testUpdateState_currentPackageEmpty_defaultEmpty() throws Exception { 376 setDefaultNetworkRecommendationPackage(""); 377 setNetworkRecoPackageSetting(""); 378 379 mNetworkScorerAppManager.updateState(); 380 381 verify(mSettingsFacade, never()).putString(any(), 382 eq(Settings.Global.NETWORK_RECOMMENDATIONS_PACKAGE), anyString()); 383 verify(mSettingsFacade).putInt(mMockContext, 384 Settings.Global.NETWORK_RECOMMENDATIONS_ENABLED, 385 NetworkScoreManager.RECOMMENDATIONS_ENABLED_OFF); 386 } 387 388 @Test 389 public void testUpdateState_currentPackageNotValid_sameAsDefault() throws Exception { 390 String defaultPackage = "defaultPackage"; 391 setDefaultNetworkRecommendationPackage(defaultPackage); 392 setNetworkRecoPackageSetting(defaultPackage); 393 394 mNetworkScorerAppManager.updateState(); 395 396 verify(mSettingsFacade).putInt(mMockContext, 397 Settings.Global.NETWORK_RECOMMENDATIONS_ENABLED, 398 NetworkScoreManager.RECOMMENDATIONS_ENABLED_OFF); 399 } 400 401 @Test 402 public void testMigrateNetworkScorerAppSettingIfNeeded_networkScorerAppIsNull() 403 throws Exception { 404 when(mSettingsFacade.getString(mMockContext, 405 Settings.Global.NETWORK_SCORER_APP)).thenReturn(null); 406 407 mNetworkScorerAppManager.migrateNetworkScorerAppSettingIfNeeded(); 408 409 verify(mSettingsFacade, never()).putString(eq(mMockContext), 410 eq(Settings.Global.USE_OPEN_WIFI_PACKAGE), anyString()); 411 } 412 413 @Test 414 public void testMigrateNetworkScorerAppSettingIfNeeded_networkScorerAppIsEmpty() 415 throws Exception { 416 when(mSettingsFacade.getString(mMockContext, 417 Settings.Global.NETWORK_SCORER_APP)).thenReturn(""); 418 419 mNetworkScorerAppManager.migrateNetworkScorerAppSettingIfNeeded(); 420 421 verify(mSettingsFacade, never()).putString(eq(mMockContext), 422 eq(Settings.Global.USE_OPEN_WIFI_PACKAGE), anyString()); 423 } 424 425 @Test 426 public void testMigrateNetworkScorerAppSettingIfNeeded_networkScorerIsNotActive() 427 throws Exception { 428 when(mSettingsFacade.getString(mMockContext, 429 Settings.Global.NETWORK_SCORER_APP)).thenReturn("com.foo.package"); 430 // Make getActiveScorer() return null. 431 setRecommendationsEnabledSetting(NetworkScoreManager.RECOMMENDATIONS_ENABLED_FORCED_OFF); 432 433 mNetworkScorerAppManager.migrateNetworkScorerAppSettingIfNeeded(); 434 435 verify(mSettingsFacade, never()).putString(eq(mMockContext), 436 eq(Settings.Global.USE_OPEN_WIFI_PACKAGE), anyString()); 437 } 438 439 @Test 440 public void testMigrateNetworkScorerAppSettingIfNeeded_useOpenWifiSettingIsNotEmpty() 441 throws Exception { 442 final ComponentName enableUseOpenWifiComponent = new ComponentName("package2", "class2"); 443 setNetworkRecoPackageSetting(RECO_COMPONENT.getPackageName()); 444 mockScoreNetworksGranted(RECO_COMPONENT.getPackageName()); 445 mockRecommendationServiceAvailable(RECO_COMPONENT, PACKAGE_UID /* packageUid */, 446 enableUseOpenWifiComponent.getPackageName()); 447 mockEnableUseOpenWifiActivity(enableUseOpenWifiComponent); 448 when(mSettingsFacade.getString(mMockContext, 449 Settings.Global.NETWORK_SCORER_APP)) 450 .thenReturn(enableUseOpenWifiComponent.getPackageName()); 451 // The setting has a value so the migration shouldn't touch it. 452 when(mSettingsFacade.getString(mMockContext, 453 Settings.Global.USE_OPEN_WIFI_PACKAGE)) 454 .thenReturn(enableUseOpenWifiComponent.getPackageName()); 455 456 mNetworkScorerAppManager.migrateNetworkScorerAppSettingIfNeeded(); 457 458 verify(mSettingsFacade, never()).putString(eq(mMockContext), 459 eq(Settings.Global.USE_OPEN_WIFI_PACKAGE), anyString()); 460 verify(mSettingsFacade).putString(eq(mMockContext), 461 eq(Settings.Global.NETWORK_SCORER_APP), eq(null)); 462 } 463 464 @Test 465 public void testMigrateNetworkScorerAppSettingIfNeeded_useOpenWifiActivityNotAvail() 466 throws Exception { 467 final ComponentName enableUseOpenWifiComponent = new ComponentName("package2", "class2"); 468 setNetworkRecoPackageSetting(RECO_COMPONENT.getPackageName()); 469 mockScoreNetworksGranted(RECO_COMPONENT.getPackageName()); 470 // The active component doesn't have an open wifi activity so the migration shouldn't 471 // set USE_OPEN_WIFI_PACKAGE. 472 mockRecommendationServiceAvailable(RECO_COMPONENT, PACKAGE_UID /* packageUid */, 473 null /*useOpenWifiActivityPackage*/); 474 when(mSettingsFacade.getString(mMockContext, 475 Settings.Global.NETWORK_SCORER_APP)) 476 .thenReturn(enableUseOpenWifiComponent.getPackageName()); 477 when(mSettingsFacade.getString(mMockContext, 478 Settings.Global.USE_OPEN_WIFI_PACKAGE)).thenReturn(null); 479 480 mNetworkScorerAppManager.migrateNetworkScorerAppSettingIfNeeded(); 481 482 verify(mSettingsFacade, never()).putString(eq(mMockContext), 483 eq(Settings.Global.USE_OPEN_WIFI_PACKAGE), anyString()); 484 verify(mSettingsFacade).putString(eq(mMockContext), 485 eq(Settings.Global.NETWORK_SCORER_APP), eq(null)); 486 } 487 488 @Test 489 public void testMigrateNetworkScorerAppSettingIfNeeded_packageMismatch_activity() 490 throws Exception { 491 final ComponentName enableUseOpenWifiComponent = new ComponentName("package2", "class2"); 492 setNetworkRecoPackageSetting(RECO_COMPONENT.getPackageName()); 493 mockScoreNetworksGranted(RECO_COMPONENT.getPackageName()); 494 mockRecommendationServiceAvailable(RECO_COMPONENT, PACKAGE_UID /* packageUid */, 495 enableUseOpenWifiComponent.getPackageName()); 496 mockEnableUseOpenWifiActivity(enableUseOpenWifiComponent); 497 // The older network scorer app setting doesn't match the new use open wifi activity package 498 // so the migration shouldn't set USE_OPEN_WIFI_PACKAGE. 499 when(mSettingsFacade.getString(mMockContext, 500 Settings.Global.NETWORK_SCORER_APP)) 501 .thenReturn(enableUseOpenWifiComponent.getPackageName() + ".diff"); 502 when(mSettingsFacade.getString(mMockContext, 503 Settings.Global.USE_OPEN_WIFI_PACKAGE)).thenReturn(null); 504 505 mNetworkScorerAppManager.migrateNetworkScorerAppSettingIfNeeded(); 506 507 verify(mSettingsFacade, never()).putString(eq(mMockContext), 508 eq(Settings.Global.USE_OPEN_WIFI_PACKAGE), anyString()); 509 verify(mSettingsFacade).putString(eq(mMockContext), 510 eq(Settings.Global.NETWORK_SCORER_APP), eq(null)); 511 } 512 513 @Test 514 public void testMigrateNetworkScorerAppSettingIfNeeded_packageMismatch_service() 515 throws Exception { 516 final ComponentName enableUseOpenWifiComponent = new ComponentName("package2", "class2"); 517 setNetworkRecoPackageSetting(RECO_COMPONENT.getPackageName()); 518 mockScoreNetworksGranted(RECO_COMPONENT.getPackageName()); 519 mockRecommendationServiceAvailable(RECO_COMPONENT, PACKAGE_UID /* packageUid */, 520 enableUseOpenWifiComponent.getPackageName()); 521 mockEnableUseOpenWifiActivity(enableUseOpenWifiComponent); 522 // The older network scorer app setting doesn't match the active package so the migration 523 // shouldn't set USE_OPEN_WIFI_PACKAGE. 524 when(mSettingsFacade.getString(mMockContext, 525 Settings.Global.NETWORK_SCORER_APP)) 526 .thenReturn(RECO_COMPONENT.getPackageName() + ".diff"); 527 when(mSettingsFacade.getString(mMockContext, 528 Settings.Global.USE_OPEN_WIFI_PACKAGE)).thenReturn(null); 529 530 mNetworkScorerAppManager.migrateNetworkScorerAppSettingIfNeeded(); 531 532 verify(mSettingsFacade, never()).putString(eq(mMockContext), 533 eq(Settings.Global.USE_OPEN_WIFI_PACKAGE), anyString()); 534 verify(mSettingsFacade).putString(eq(mMockContext), 535 eq(Settings.Global.NETWORK_SCORER_APP), eq(null)); 536 } 537 538 @Test 539 public void testMigrateNetworkScorerAppSettingIfNeeded_packageMatch_activity() 540 throws Exception { 541 final ComponentName enableUseOpenWifiComponent = new ComponentName("package2", "class2"); 542 setNetworkRecoPackageSetting(RECO_COMPONENT.getPackageName()); 543 mockScoreNetworksGranted(RECO_COMPONENT.getPackageName()); 544 mockRecommendationServiceAvailable(RECO_COMPONENT, PACKAGE_UID /* packageUid */, 545 enableUseOpenWifiComponent.getPackageName()); 546 mockEnableUseOpenWifiActivity(enableUseOpenWifiComponent); 547 // Old setting matches the new activity package, migration should happen. 548 when(mSettingsFacade.getString(mMockContext, 549 Settings.Global.NETWORK_SCORER_APP)) 550 .thenReturn(enableUseOpenWifiComponent.getPackageName()); 551 when(mSettingsFacade.getString(mMockContext, 552 Settings.Global.USE_OPEN_WIFI_PACKAGE)).thenReturn(null); 553 554 mNetworkScorerAppManager.migrateNetworkScorerAppSettingIfNeeded(); 555 556 verify(mSettingsFacade).putString(eq(mMockContext), 557 eq(Settings.Global.USE_OPEN_WIFI_PACKAGE), 558 eq(enableUseOpenWifiComponent.getPackageName())); 559 verify(mSettingsFacade).putString(eq(mMockContext), 560 eq(Settings.Global.NETWORK_SCORER_APP), eq(null)); 561 } 562 563 private void setRecommendationsEnabledSetting(int value) { 564 when(mSettingsFacade.getInt(eq(mMockContext), 565 eq(Settings.Global.NETWORK_RECOMMENDATIONS_ENABLED), anyInt())).thenReturn(value); 566 } 567 568 private void setNetworkRecoPackageSetting(String packageName) { 569 when(mSettingsFacade.getString(mMockContext, 570 Settings.Global.NETWORK_RECOMMENDATIONS_PACKAGE)).thenReturn(packageName); 571 } 572 573 private void setDefaultNetworkRecommendationPackage(String name) { 574 when(mResources.getString(R.string.config_defaultNetworkRecommendationProviderPackage)) 575 .thenReturn(name); 576 } 577 578 private void mockScoreNetworksGranted(String packageName) { 579 when(mMockPm.checkPermission(permission.SCORE_NETWORKS, packageName)) 580 .thenReturn(PackageManager.PERMISSION_GRANTED); 581 } 582 583 private void mockScoreNetworksDenied(String packageName) { 584 when(mMockPm.checkPermission(permission.SCORE_NETWORKS, packageName)) 585 .thenReturn(PackageManager.PERMISSION_DENIED); 586 } 587 588 private void mockLocationModeOn() { 589 mockLocationModeValue(Settings.Secure.LOCATION_MODE_HIGH_ACCURACY); 590 } 591 592 private void mockLocationModeOff() { 593 mockLocationModeValue(Settings.Secure.LOCATION_MODE_OFF); 594 } 595 596 private void mockLocationModeValue(int returnVal) { 597 when(mSettingsFacade.getSecureInt(eq(mMockContext), 598 eq(Settings.Secure.LOCATION_MODE), anyInt())).thenReturn(returnVal); 599 } 600 601 private void mockLocationPermissionGranted(int uid, String packageName) { 602 when(mMockPm.checkPermission(permission.ACCESS_COARSE_LOCATION, packageName)) 603 .thenReturn(PackageManager.PERMISSION_GRANTED); 604 when(mAppOpsManager.noteOp(AppOpsManager.OP_COARSE_LOCATION, uid, packageName)) 605 .thenReturn(AppOpsManager.MODE_ALLOWED); 606 } 607 608 private void mockLocationPermissionDenied(int uid, String packageName) { 609 when(mMockPm.checkPermission(permission.ACCESS_COARSE_LOCATION, packageName)) 610 .thenReturn(PackageManager.PERMISSION_DENIED); 611 when(mAppOpsManager.noteOp(AppOpsManager.OP_COARSE_LOCATION, uid, packageName)) 612 .thenReturn(AppOpsManager.MODE_IGNORED); 613 } 614 615 private void mockRecommendationServiceAvailable(final ComponentName compName, int packageUid) { 616 mockRecommendationServiceAvailable(compName, packageUid, null, false); 617 } 618 619 private void mockRecommendationServiceAvailable(final ComponentName compName, int packageUid, 620 String enableUseOpenWifiActivityPackage) { 621 mockRecommendationServiceAvailable( 622 compName, packageUid, enableUseOpenWifiActivityPackage, false); 623 } 624 625 private void mockRecommendationServiceAvailable(final ComponentName compName, int packageUid, 626 String enableUseOpenWifiActivityPackage, boolean serviceLabelOverride) { 627 mockRecommendationServiceAvailable(compName, packageUid, enableUseOpenWifiActivityPackage, 628 serviceLabelOverride, false); 629 } 630 631 private void mockRecommendationServiceAvailable(final ComponentName compName, int packageUid, 632 String enableUseOpenWifiActivityPackage, boolean serviceLabelOverride, 633 boolean setNotificationChannel) { 634 final ResolveInfo serviceInfo = new ResolveInfo(); 635 serviceInfo.serviceInfo = new ServiceInfo(); 636 serviceInfo.serviceInfo.name = compName.getClassName(); 637 serviceInfo.serviceInfo.packageName = compName.getPackageName(); 638 serviceInfo.serviceInfo.applicationInfo = new ApplicationInfo(); 639 serviceInfo.serviceInfo.applicationInfo.uid = packageUid; 640 if (enableUseOpenWifiActivityPackage != null) { 641 serviceInfo.serviceInfo.metaData = new Bundle(); 642 serviceInfo.serviceInfo.metaData.putString( 643 NetworkScoreManager.USE_OPEN_WIFI_PACKAGE_META_DATA, 644 enableUseOpenWifiActivityPackage); 645 } 646 if (serviceLabelOverride) { 647 if (serviceInfo.serviceInfo.metaData == null) { 648 serviceInfo.serviceInfo.metaData = new Bundle(); 649 } 650 serviceInfo.serviceInfo.metaData.putString( 651 NetworkScoreManager.RECOMMENDATION_SERVICE_LABEL_META_DATA, 652 MOCK_OVERRIDEN_SERVICE_LABEL); 653 } else { 654 serviceInfo.serviceInfo.nonLocalizedLabel = MOCK_SERVICE_LABEL; 655 } 656 if (setNotificationChannel) { 657 if (serviceInfo.serviceInfo.metaData == null) { 658 serviceInfo.serviceInfo.metaData = new Bundle(); 659 } 660 serviceInfo.serviceInfo.metaData.putString( 661 NetworkScoreManager.NETWORK_AVAILABLE_NOTIFICATION_CHANNEL_ID_META_DATA, 662 MOCK_NETWORK_AVAILABLE_NOTIFICATION_CHANNEL_ID); 663 } 664 665 final int flags = PackageManager.GET_META_DATA; 666 when(mMockPm.resolveService( 667 Mockito.argThat(new ArgumentMatcher<Intent>() { 668 @Override 669 public boolean matchesObject(Object object) { 670 Intent intent = (Intent) object; 671 return NetworkScoreManager.ACTION_RECOMMEND_NETWORKS 672 .equals(intent.getAction()) 673 && compName.getPackageName().equals(intent.getPackage()); 674 } 675 }), Mockito.eq(flags))).thenReturn(serviceInfo); 676 677 mAvailableServices.add(serviceInfo); 678 } 679 680 private void mockEnableUseOpenWifiActivity(final ComponentName useOpenWifiComp) { 681 final ResolveInfo resolveActivityInfo = new ResolveInfo(); 682 resolveActivityInfo.activityInfo = new ActivityInfo(); 683 resolveActivityInfo.activityInfo.name = useOpenWifiComp.getClassName(); 684 resolveActivityInfo.activityInfo.packageName = useOpenWifiComp.getPackageName(); 685 686 final int flags = 0; 687 when(mMockPm.resolveActivity( 688 Mockito.argThat(new ArgumentMatcher<Intent>() { 689 @Override 690 public boolean matchesObject(Object object) { 691 Intent intent = (Intent) object; 692 return NetworkScoreManager.ACTION_CUSTOM_ENABLE.equals(intent.getAction()) 693 && useOpenWifiComp.getPackageName().equals(intent.getPackage()); 694 } 695 }), Mockito.eq(flags))).thenReturn(resolveActivityInfo); 696 } 697 } 698