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