1 /* 2 * Copyright (C) 2019 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.phone; 18 19 import static android.content.pm.PackageManager.PERMISSION_DENIED; 20 import static android.content.pm.PackageManager.PERMISSION_GRANTED; 21 import static android.provider.Telephony.ServiceStateTable; 22 import static android.provider.Telephony.ServiceStateTable.DATA_NETWORK_TYPE; 23 import static android.provider.Telephony.ServiceStateTable.DATA_REG_STATE; 24 import static android.provider.Telephony.ServiceStateTable.DUPLEX_MODE; 25 import static android.provider.Telephony.ServiceStateTable.VOICE_OPERATOR_NUMERIC; 26 import static android.provider.Telephony.ServiceStateTable.VOICE_REG_STATE; 27 import static android.provider.Telephony.ServiceStateTable.getUriForSubscriptionId; 28 import static android.telephony.NetworkRegistrationInfo.REGISTRATION_STATE_HOME; 29 30 import static org.junit.Assert.assertEquals; 31 import static org.junit.Assert.assertFalse; 32 import static org.junit.Assert.assertNotNull; 33 import static org.junit.Assert.assertThrows; 34 import static org.junit.Assert.assertTrue; 35 import static org.mockito.ArgumentMatchers.any; 36 import static org.mockito.ArgumentMatchers.anyInt; 37 import static org.mockito.ArgumentMatchers.anyString; 38 import static org.mockito.ArgumentMatchers.eq; 39 import static org.mockito.ArgumentMatchers.nullable; 40 import static org.mockito.Mockito.doReturn; 41 import static org.mockito.Mockito.when; 42 43 import android.Manifest; 44 import android.app.AppOpsManager; 45 import android.content.Context; 46 import android.content.pm.ApplicationInfo; 47 import android.content.pm.PackageManager; 48 import android.content.pm.ProviderInfo; 49 import android.database.ContentObserver; 50 import android.database.Cursor; 51 import android.location.LocationManager; 52 import android.net.Uri; 53 import android.os.Build; 54 import android.os.UserHandle; 55 import android.telephony.AccessNetworkConstants; 56 import android.telephony.NetworkRegistrationInfo; 57 import android.telephony.ServiceState; 58 import android.telephony.SubscriptionManager; 59 import android.telephony.TelephonyManager; 60 import android.test.mock.MockContentResolver; 61 import android.test.suitebuilder.annotation.SmallTest; 62 63 import androidx.test.ext.junit.runners.AndroidJUnit4; 64 65 import org.junit.After; 66 import org.junit.Before; 67 import org.junit.Ignore; 68 import org.junit.Test; 69 import org.junit.runner.RunWith; 70 import org.mockito.Mock; 71 import org.mockito.MockitoAnnotations; 72 73 /** 74 * Tests for simple queries of ServiceStateProvider. 75 * 76 * Build, install and run the tests by running the commands below: 77 * atest ServiceStateProviderTest 78 */ 79 @RunWith(AndroidJUnit4.class) 80 public class ServiceStateProviderTest { 81 private static final String TAG = "ServiceStateProviderTest"; 82 private static final int TEST_NETWORK_ID = 123; 83 private static final int TEST_SYSTEM_ID = 123; 84 85 private MockContentResolver mContentResolver; 86 private ServiceState mTestServiceState; 87 private ServiceState mTestServiceStateForSubId1; 88 89 @Mock Context mContext; 90 @Mock AppOpsManager mAppOpsManager; 91 @Mock LocationManager mLocationManager; 92 @Mock PackageManager mPackageManager; 93 94 // Exception used internally to verify if the Resolver#notifyChange has been called. 95 private class TestNotifierException extends RuntimeException { TestNotifierException()96 TestNotifierException() { 97 super(); 98 } 99 } 100 101 @Before setUp()102 public void setUp() throws Exception { 103 MockitoAnnotations.initMocks(this); 104 mockSystemService(AppOpsManager.class, mAppOpsManager, Context.APP_OPS_SERVICE); 105 mockSystemService(LocationManager.class, mLocationManager, Context.LOCATION_SERVICE); 106 doReturn(mPackageManager).when(mContext).getPackageManager(); 107 108 mContentResolver = new MockContentResolver() { 109 @Override 110 public void notifyChange(Uri uri, ContentObserver observer, boolean syncToNetwork) { 111 throw new TestNotifierException(); 112 } 113 }; 114 doReturn(mContentResolver).when(mContext).getContentResolver(); 115 116 mTestServiceState = new ServiceState(); 117 mTestServiceState.setStateOutOfService(); 118 mTestServiceState.setCdmaSystemAndNetworkId(TEST_SYSTEM_ID, TEST_NETWORK_ID); 119 mTestServiceStateForSubId1 = new ServiceState(); 120 mTestServiceStateForSubId1.setStateOff(); 121 122 // Add NRI to trigger SS with non-default values (e.g. duplex mode) 123 NetworkRegistrationInfo nriWwan = new NetworkRegistrationInfo.Builder() 124 .setTransportType(AccessNetworkConstants.TRANSPORT_TYPE_WWAN) 125 .setAccessNetworkTechnology(TelephonyManager.NETWORK_TYPE_LTE) 126 .setDomain(NetworkRegistrationInfo.DOMAIN_PS) 127 .build(); 128 mTestServiceStateForSubId1.addNetworkRegistrationInfo(nriWwan); 129 mTestServiceStateForSubId1.setChannelNumber(65536); // EutranBand.BAND_65, DUPLEX_MODE_FDD 130 131 // Mock out the actual phone state 132 ServiceStateProvider provider = new ServiceStateProvider() { 133 @Override 134 public ServiceState getServiceState(int subId) { 135 if (subId == 1) { 136 return mTestServiceStateForSubId1; 137 } else { 138 return mTestServiceState; 139 } 140 } 141 142 @Override 143 public int getDefaultSubId() { 144 return 0; 145 } 146 }; 147 ProviderInfo providerInfo = new ProviderInfo(); 148 providerInfo.authority = "service-state"; 149 provider.attachInfoForTesting(mContext, providerInfo); 150 mContentResolver.addProvider("service-state", provider); 151 152 // By default, test with app target R, no READ_PRIVILEGED_PHONE_STATE permission 153 setTargetSdkVersion(Build.VERSION_CODES.R); 154 setCanReadPrivilegedPhoneState(false); 155 156 // TODO(b/191995565): Turn on all ignored cases once location access is allow to be off 157 // Do not allow phone process to always access location so we can test various scenarios 158 // LocationAccessPolicy.alwaysAllowPrivilegedProcessToAccessLocationForTesting(false); 159 } 160 161 @After tearDown()162 public void tearDown() throws Exception { 163 // LocationAccessPolicy.alwaysAllowPrivilegedProcessToAccessLocationForTesting(true); 164 } 165 166 /** 167 * Verify that when calling query with no subId in the uri the default ServiceState is returned. 168 * In this case the subId is set to 0 and the expected service state is mTestServiceState. 169 */ 170 // TODO(b/191995565): Turn this on when location access can be off 171 @Ignore 172 @SmallTest testQueryServiceState_withNoSubId_withoutLocation()173 public void testQueryServiceState_withNoSubId_withoutLocation() { 174 setLocationPermissions(false); 175 176 verifyServiceStateForSubId(ServiceStateTable.CONTENT_URI, mTestServiceState, 177 false /*hasLocation*/); 178 } 179 180 @Test 181 @SmallTest testQueryServiceState_withNoSubId_withLocation()182 public void testQueryServiceState_withNoSubId_withLocation() { 183 setLocationPermissions(true); 184 185 verifyServiceStateForSubId(ServiceStateTable.CONTENT_URI, mTestServiceState, 186 true /*hasLocation*/); 187 } 188 189 /** 190 * Verify that when calling with the DEFAULT_SUBSCRIPTION_ID the correct ServiceState is 191 * returned. In this case the subId is set to 0 and the expected service state is 192 * mTestServiceState. 193 */ 194 // TODO(b/191995565): Turn case on when location access can be off 195 @Ignore 196 @SmallTest testGetServiceState_withDefaultSubId_withoutLocation()197 public void testGetServiceState_withDefaultSubId_withoutLocation() { 198 setLocationPermissions(false); 199 200 verifyServiceStateForSubId( 201 getUriForSubscriptionId(SubscriptionManager.DEFAULT_SUBSCRIPTION_ID), 202 mTestServiceState, false /*hasLocation*/); 203 } 204 205 @Test 206 @SmallTest testGetServiceState_withDefaultSubId_withLocation()207 public void testGetServiceState_withDefaultSubId_withLocation() { 208 setLocationPermissions(true); 209 210 verifyServiceStateForSubId( 211 getUriForSubscriptionId(SubscriptionManager.DEFAULT_SUBSCRIPTION_ID), 212 mTestServiceState, true /*hasLocation*/); 213 } 214 215 /** 216 * Verify that when calling with a specific subId the correct ServiceState is returned. In this 217 * case the subId is set to 1 and the expected service state is mTestServiceStateForSubId1 218 */ 219 @Test 220 @SmallTest testGetServiceStateForSubId_withoutLocation()221 public void testGetServiceStateForSubId_withoutLocation() { 222 setLocationPermissions(false); 223 224 verifyServiceStateForSubId(getUriForSubscriptionId(1), mTestServiceStateForSubId1, 225 false /*hasLocation*/); 226 } 227 228 @Test 229 @SmallTest testGetServiceStateForSubId_withLocation()230 public void testGetServiceStateForSubId_withLocation() { 231 setLocationPermissions(true); 232 233 verifyServiceStateForSubId(getUriForSubscriptionId(1), mTestServiceStateForSubId1, 234 true /*hasLocation*/); 235 } 236 237 /** 238 * Verify that apps target S+ without READ_PRIVILEGED_PHONE_STATE permission can access the 239 * public columns of ServiceStateTable. 240 */ 241 @Test query_publicColumns_targetS_noReadPrivilege_getPublicColumns()242 public void query_publicColumns_targetS_noReadPrivilege_getPublicColumns() { 243 setTargetSdkVersion(Build.VERSION_CODES.S); 244 setCanReadPrivilegedPhoneState(false); 245 246 verifyServiceStateWithPublicColumns(mTestServiceState, null /*projection*/); 247 } 248 249 /** 250 * Verify that apps target S+ without READ_PRIVILEGED_PHONE_STATE permission try to access 251 * non-public columns should throw IllegalArgumentException. 252 */ 253 @Test query_hideColumn_targetS_noReadPrivilege_throwIllegalArgumentException()254 public void query_hideColumn_targetS_noReadPrivilege_throwIllegalArgumentException() { 255 setTargetSdkVersion(Build.VERSION_CODES.S); 256 setCanReadPrivilegedPhoneState(false); 257 258 // DATA_ROAMING_TYPE is a non-public column 259 String[] projection = new String[]{"data_roaming_type"}; 260 261 assertThrows(IllegalArgumentException.class, 262 () -> verifyServiceStateWithPublicColumns(mTestServiceState, projection)); 263 } 264 265 /** 266 * Verify that apps target S+ with READ_PRIVILEGED_PHONE_STATE and location permissions should 267 * be able to access all columns. 268 */ 269 @Test query_allColumn_targetS_withReadPrivilegedAndLocation_getAllStateUnredacted()270 public void query_allColumn_targetS_withReadPrivilegedAndLocation_getAllStateUnredacted() { 271 setTargetSdkVersion(Build.VERSION_CODES.S); 272 setCanReadPrivilegedPhoneState(true); 273 setLocationPermissions(true); 274 275 verifyServiceStateForSubId( 276 getUriForSubscriptionId(SubscriptionManager.DEFAULT_SUBSCRIPTION_ID), 277 mTestServiceState, true /*hasPermission*/); 278 } 279 280 /** 281 * Verify that apps target S+ with READ_PRIVILEGED_PHONE_STATE permission but no location 282 * permission, try to access location sensitive columns should throw SecurityException. 283 */ 284 // TODO(b/191995565): Turn this on once b/191995565 is integrated 285 @Ignore query_locationColumn_targetS_withReadPrivilegeNoLocation_throwSecurityExecption()286 public void query_locationColumn_targetS_withReadPrivilegeNoLocation_throwSecurityExecption() { 287 setTargetSdkVersion(Build.VERSION_CODES.S); 288 setCanReadPrivilegedPhoneState(true); 289 setLocationPermissions(false); 290 291 // NETWORK_ID is a location-sensitive column 292 String[] projection = new String[]{"network_id"}; 293 294 assertThrows(SecurityException.class, 295 () -> verifyServiceStateWithLocationColumns(mTestServiceState, projection)); 296 } 297 298 /** 299 * Verify that apps target R- with location permissions should be able to access all columns. 300 */ 301 @Test query_allColumn_targetR_withLocation_getAllStateUnredacted()302 public void query_allColumn_targetR_withLocation_getAllStateUnredacted() { 303 setTargetSdkVersion(Build.VERSION_CODES.R); 304 setLocationPermissions(true); 305 306 verifyServiceStateForSubId( 307 getUriForSubscriptionId(SubscriptionManager.DEFAULT_SUBSCRIPTION_ID), 308 mTestServiceState, true /*hasPermission*/); 309 } 310 311 /** 312 * Verify that apps target R- w/o location permissions should be able to access all columns but 313 * with redacted ServiceState. 314 */ 315 // TODO(b/191995565): Turn case on when location access can be off 316 @Ignore query_allColumn_targetR_noLocation_getRedacted()317 public void query_allColumn_targetR_noLocation_getRedacted() { 318 setTargetSdkVersion(Build.VERSION_CODES.R); 319 setLocationPermissions(false); 320 321 verifyServiceStateForSubId( 322 getUriForSubscriptionId(SubscriptionManager.DEFAULT_SUBSCRIPTION_ID), 323 ServiceStateProvider.getLocationRedactedServiceState(mTestServiceState), 324 true /*hasPermission*/); 325 } 326 verifyServiceStateWithLocationColumns(ServiceState ss, String[] projection)327 private void verifyServiceStateWithLocationColumns(ServiceState ss, String[] projection) { 328 try (Cursor cursor = mContentResolver.query(ServiceStateTable.CONTENT_URI, projection, null, 329 null)) { 330 assertNotNull(cursor); 331 } 332 } 333 verifyServiceStateWithPublicColumns(ServiceState ss, String[] projection)334 private void verifyServiceStateWithPublicColumns(ServiceState ss, String[] projection) { 335 try (Cursor cursor = mContentResolver.query(ServiceStateTable.CONTENT_URI, projection, null, 336 null)) { 337 assertNotNull(cursor); 338 assertEquals(cursor.getColumnCount(), ServiceStateProvider.PUBLIC_COLUMNS.length); 339 340 cursor.moveToFirst(); 341 assertEquals(ss.getVoiceRegState(), 342 cursor.getInt(cursor.getColumnIndex(VOICE_REG_STATE))); 343 assertEquals(ss.getDataRegistrationState(), 344 cursor.getInt(cursor.getColumnIndex(DATA_REG_STATE))); 345 assertEquals(ss.getOperatorNumeric(), 346 cursor.getString(cursor.getColumnIndex(VOICE_OPERATOR_NUMERIC))); 347 assertEquals(ss.getDataNetworkType(), 348 cursor.getInt(cursor.getColumnIndex(DATA_NETWORK_TYPE))); 349 assertEquals(ss.getDuplexMode(), cursor.getInt(cursor.getColumnIndex(DUPLEX_MODE))); 350 } 351 } 352 verifyServiceStateForSubId(Uri uri, ServiceState ss, boolean hasLocation)353 private void verifyServiceStateForSubId(Uri uri, ServiceState ss, boolean hasLocation) { 354 Cursor cursor = mContentResolver.query(uri, ServiceStateProvider.ALL_COLUMNS, "", 355 null, null); 356 assertNotNull(cursor); 357 cursor.moveToFirst(); 358 359 final int voiceRegState = ss.getState(); 360 final int dataRegState = ss.getDataRegistrationState(); 361 final int voiceRoamingType = ss.getVoiceRoamingType(); 362 final int dataRoamingType = ss.getDataRoamingType(); 363 final String voiceOperatorAlphaLong = hasLocation ? ss.getOperatorAlphaLong() : null; 364 final String voiceOperatorAlphaShort = hasLocation ? ss.getOperatorAlphaShort() : null; 365 final String voiceOperatorNumeric = hasLocation ? ss.getOperatorNumeric() : null; 366 final String dataOperatorAlphaLong = hasLocation ? ss.getOperatorAlphaLong() : null; 367 final String dataOperatorAlphaShort = hasLocation ? ss.getOperatorAlphaShort() : null; 368 final String dataOperatorNumeric = hasLocation ? ss.getOperatorNumeric() : null; 369 final int isManualNetworkSelection = (ss.getIsManualSelection()) ? 1 : 0; 370 final int rilVoiceRadioTechnology = ss.getRilVoiceRadioTechnology(); 371 final int rilDataRadioTechnology = ss.getRilDataRadioTechnology(); 372 final int cssIndicator = ss.getCssIndicator(); 373 final int networkId = hasLocation ? ss.getCdmaNetworkId() : ServiceState.UNKNOWN_ID; 374 final int systemId = hasLocation ? ss.getCdmaSystemId() : ServiceState.UNKNOWN_ID; 375 final int cdmaRoamingIndicator = ss.getCdmaRoamingIndicator(); 376 final int cdmaDefaultRoamingIndicator = ss.getCdmaDefaultRoamingIndicator(); 377 final int cdmaEriIconIndex = ss.getCdmaEriIconIndex(); 378 final int cdmaEriIconMode = ss.getCdmaEriIconMode(); 379 final int isEmergencyOnly = (ss.isEmergencyOnly()) ? 1 : 0; 380 final int isUsingCarrierAggregation = (ss.isUsingCarrierAggregation()) ? 1 : 0; 381 final String operatorAlphaLongRaw = ss.getOperatorAlphaLongRaw(); 382 final String operatorAlphaShortRaw = ss.getOperatorAlphaShortRaw(); 383 final int dataNetworkType = ss.getDataNetworkType(); 384 final int duplexMode = ss.getDuplexMode(); 385 386 assertEquals(voiceRegState, cursor.getInt(0)); 387 assertEquals(dataRegState, cursor.getInt(1)); 388 assertEquals(voiceRoamingType, cursor.getInt(2)); 389 assertEquals(dataRoamingType, cursor.getInt(3)); 390 assertEquals(voiceOperatorAlphaLong, cursor.getString(4)); 391 assertEquals(voiceOperatorAlphaShort, cursor.getString(5)); 392 assertEquals(voiceOperatorNumeric, cursor.getString(6)); 393 assertEquals(dataOperatorAlphaLong, cursor.getString(7)); 394 assertEquals(dataOperatorAlphaShort, cursor.getString(8)); 395 assertEquals(dataOperatorNumeric, cursor.getString(9)); 396 assertEquals(isManualNetworkSelection, cursor.getInt(10)); 397 assertEquals(rilVoiceRadioTechnology, cursor.getInt(11)); 398 assertEquals(rilDataRadioTechnology, cursor.getInt(12)); 399 assertEquals(cssIndicator, cursor.getInt(13)); 400 assertEquals(networkId, cursor.getInt(14)); 401 assertEquals(systemId, cursor.getInt(15)); 402 assertEquals(cdmaRoamingIndicator, cursor.getInt(16)); 403 assertEquals(cdmaDefaultRoamingIndicator, cursor.getInt(17)); 404 assertEquals(cdmaEriIconIndex, cursor.getInt(18)); 405 assertEquals(cdmaEriIconMode, cursor.getInt(19)); 406 assertEquals(isEmergencyOnly, cursor.getInt(20)); 407 assertEquals(isUsingCarrierAggregation, cursor.getInt(21)); 408 assertEquals(operatorAlphaLongRaw, cursor.getString(22)); 409 assertEquals(operatorAlphaShortRaw, cursor.getString(23)); 410 assertEquals(dataNetworkType, cursor.getInt(24)); 411 assertEquals(duplexMode, cursor.getInt(25)); 412 } 413 414 /** 415 * Test that we don't notify for certain field changes. (e.g. we don't notify when the NetworkId 416 * or SystemId change) This is an intentional behavior change from the broadcast. 417 */ 418 @Test 419 @SmallTest testNoNotify()420 public void testNoNotify() { 421 int subId = 0; 422 423 ServiceState oldSS = new ServiceState(); 424 oldSS.setStateOutOfService(); 425 oldSS.setCdmaSystemAndNetworkId(1, 1); 426 427 ServiceState newSS = new ServiceState(); 428 newSS.setStateOutOfService(); 429 newSS.setCdmaSystemAndNetworkId(0, 0); 430 431 // Test that notifyChange is not called for these fields 432 assertFalse(notifyChangeCalledForSubIdAndField(oldSS, newSS, subId)); 433 } 434 435 @Test 436 @SmallTest testNotifyChanged_noStateUpdated()437 public void testNotifyChanged_noStateUpdated() { 438 int subId = 0; 439 440 ServiceState oldSS = new ServiceState(); 441 oldSS.setStateOutOfService(); 442 oldSS.setVoiceRegState(ServiceState.STATE_OUT_OF_SERVICE); 443 444 ServiceState copyOfOldSS = new ServiceState(); 445 copyOfOldSS.setStateOutOfService(); 446 copyOfOldSS.setVoiceRegState(ServiceState.STATE_OUT_OF_SERVICE); 447 448 // Test that notifyChange is not called with no change in notifyChangeForSubIdAndField 449 assertFalse(notifyChangeCalledForSubId(oldSS, copyOfOldSS, subId)); 450 451 // Test that notifyChange is not called with no change in notifyChangeForSubId 452 assertFalse(notifyChangeCalledForSubIdAndField(oldSS, copyOfOldSS, subId)); 453 } 454 455 @Test 456 @SmallTest testNotifyChanged_voiceRegStateUpdated()457 public void testNotifyChanged_voiceRegStateUpdated() { 458 int subId = 0; 459 460 ServiceState oldSS = new ServiceState(); 461 oldSS.setStateOutOfService(); 462 oldSS.setVoiceRegState(ServiceState.STATE_OUT_OF_SERVICE); 463 464 ServiceState newSS = new ServiceState(); 465 newSS.setStateOutOfService(); 466 newSS.setVoiceRegState(ServiceState.STATE_POWER_OFF); 467 468 // Test that notifyChange is called by notifyChangeForSubIdAndField when the voice_reg_state 469 // changes 470 assertTrue(notifyChangeCalledForSubId(oldSS, newSS, subId)); 471 472 // Test that notifyChange is called by notifyChangeForSubId when the voice_reg_state changes 473 assertTrue(notifyChangeCalledForSubIdAndField(oldSS, newSS, subId)); 474 } 475 476 @Test 477 @SmallTest testNotifyChanged_dataNetworkTypeUpdated()478 public void testNotifyChanged_dataNetworkTypeUpdated() { 479 int subId = 0; 480 481 // While we don't have a method to directly set dataNetworkType, we emulate a ServiceState 482 // change that will trigger the change of dataNetworkType, according to the logic in 483 // ServiceState#getDataNetworkType 484 ServiceState oldSS = new ServiceState(); 485 oldSS.setStateOutOfService(); 486 487 ServiceState newSS = new ServiceState(); 488 newSS.setStateOutOfService(); 489 490 NetworkRegistrationInfo nriWwan = new NetworkRegistrationInfo.Builder() 491 .setTransportType(AccessNetworkConstants.TRANSPORT_TYPE_WWAN) 492 .setAccessNetworkTechnology(TelephonyManager.NETWORK_TYPE_LTE) 493 .setDomain(NetworkRegistrationInfo.DOMAIN_PS) 494 .setRegistrationState(REGISTRATION_STATE_HOME) 495 .build(); 496 newSS.addNetworkRegistrationInfo(nriWwan); 497 498 // Test that notifyChange is called by notifyChangeForSubId when the 499 // data_network_type changes 500 assertTrue(notifyChangeCalledForSubId(oldSS, newSS, subId)); 501 502 // Test that notifyChange is called by notifyChangeForSubIdAndField when the 503 // data_network_type changes 504 assertTrue(notifyChangeCalledForSubIdAndField(oldSS, newSS, subId)); 505 } 506 507 @Test 508 @SmallTest testNotifyChanged_dataRegStateUpdated()509 public void testNotifyChanged_dataRegStateUpdated() { 510 int subId = 0; 511 512 ServiceState oldSS = new ServiceState(); 513 oldSS.setStateOutOfService(); 514 oldSS.setDataRegState(ServiceState.STATE_OUT_OF_SERVICE); 515 516 ServiceState newSS = new ServiceState(); 517 newSS.setStateOutOfService(); 518 newSS.setDataRegState(ServiceState.STATE_POWER_OFF); 519 520 // Test that notifyChange is called by notifyChangeForSubId 521 // when the data_reg_state changes 522 assertTrue(notifyChangeCalledForSubId(oldSS, newSS, subId)); 523 524 // Test that notifyChange is called by notifyChangeForSubIdAndField 525 // when the data_reg_state changes 526 assertTrue(notifyChangeCalledForSubIdAndField(oldSS, newSS, subId)); 527 } 528 529 // Check if notifyChange was called by notifyChangeForSubId notifyChangeCalledForSubId(ServiceState oldSS, ServiceState newSS, int subId)530 private boolean notifyChangeCalledForSubId(ServiceState oldSS, 531 ServiceState newSS, int subId) { 532 try { 533 ServiceStateProvider.notifyChangeForSubId(mContext, oldSS, newSS, subId); 534 } catch (TestNotifierException e) { 535 return true; 536 } 537 return false; 538 } 539 540 // Check if notifyChange was called by notifyChangeForSubIdAndField notifyChangeCalledForSubIdAndField(ServiceState oldSS, ServiceState newSS, int subId)541 private boolean notifyChangeCalledForSubIdAndField(ServiceState oldSS, 542 ServiceState newSS, int subId) { 543 try { 544 ServiceStateProvider.notifyChangeForSubIdAndField(mContext, oldSS, newSS, subId); 545 } catch (TestNotifierException e) { 546 return true; 547 } 548 return false; 549 } 550 setLocationPermissions(boolean hasPermission)551 private void setLocationPermissions(boolean hasPermission) { 552 if (!hasPermission) { 553 // System location off, LocationAccessPolicy#checkLocationPermission returns DENIED_SOFT 554 when(mLocationManager.isLocationEnabledForUser(any(UserHandle.class))) 555 .thenReturn(false); 556 } else { 557 // Turn on all to let LocationAccessPolicy#checkLocationPermission returns ALLOWED 558 when(mContext.checkPermission(eq(Manifest.permission.ACCESS_FINE_LOCATION), 559 anyInt(), anyInt())).thenReturn(PackageManager.PERMISSION_GRANTED); 560 561 when(mContext.checkPermission(eq(Manifest.permission.ACCESS_COARSE_LOCATION), 562 anyInt(), anyInt())).thenReturn(PackageManager.PERMISSION_GRANTED); 563 564 when(mAppOpsManager.noteOpNoThrow(eq(AppOpsManager.OPSTR_FINE_LOCATION), 565 anyInt(), anyString(), nullable(String.class), nullable(String.class))) 566 .thenReturn(AppOpsManager.MODE_ALLOWED); 567 when(mAppOpsManager.noteOpNoThrow(eq(AppOpsManager.OPSTR_COARSE_LOCATION), 568 anyInt(), anyString(), nullable(String.class), nullable(String.class))) 569 .thenReturn(AppOpsManager.MODE_ALLOWED); 570 571 when(mLocationManager.isLocationEnabledForUser(any(UserHandle.class))).thenReturn(true); 572 when(mContext.checkPermission(eq(Manifest.permission.INTERACT_ACROSS_USERS_FULL), 573 anyInt(), anyInt())).thenReturn(PackageManager.PERMISSION_GRANTED); 574 } 575 } 576 mockSystemService(Class<T> clazz , T obj, String serviceName)577 private <T> void mockSystemService(Class<T> clazz , T obj, String serviceName) { 578 when(mContext.getSystemServiceName(eq(clazz))).thenReturn(serviceName); 579 when(mContext.getSystemService(eq(serviceName))).thenReturn(obj); 580 } 581 setTargetSdkVersion(int version)582 private void setTargetSdkVersion(int version) { 583 ApplicationInfo testAppInfo = new ApplicationInfo(); 584 testAppInfo.targetSdkVersion = version; 585 try { 586 when(mPackageManager.getApplicationInfoAsUser(anyString(), anyInt(), any())) 587 .thenReturn(testAppInfo); 588 } catch (Exception ignored) { 589 } 590 } 591 setCanReadPrivilegedPhoneState(boolean granted)592 private void setCanReadPrivilegedPhoneState(boolean granted) { 593 doReturn(granted ? PERMISSION_GRANTED : PERMISSION_DENIED).when(mContext) 594 .checkCallingOrSelfPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE); 595 } 596 } 597