Loading src/java/com/android/internal/telephony/subscription/SubscriptionManagerService.java +14 −4 Original line number Diff line number Diff line Loading @@ -2010,7 +2010,11 @@ public class SubscriptionManagerService extends ISub.Stub { enforcePermissions("getActiveSubscriptionInfoForIccId", Manifest.permission.READ_PRIVILEGED_PHONE_STATE); enforceTelephonyFeatureWithException(callingPackage, "getActiveSubscriptionInfoForIccId"); if (!mContext.getResources().getBoolean( com.android.internal.R.bool.config_force_phone_globals_creation)) { enforceTelephonyFeatureWithException(callingPackage, "getActiveSubscriptionInfoForIccId"); } final long identity = Binder.clearCallingIdentity(); try { Loading Loading @@ -2322,7 +2326,10 @@ public class SubscriptionManagerService extends ISub.Stub { + SubscriptionManager.subscriptionTypeToString(subscriptionType) + ", " + getCallingPackage()); if (!mContext.getResources().getBoolean( com.android.internal.R.bool.config_force_phone_globals_creation)) { enforceTelephonyFeatureWithException(getCurrentPackageName(), "addSubInfo"); } if (subscriptionType == SubscriptionManager.SUBSCRIPTION_TYPE_LOCAL_SIM) { if (!SubscriptionManager.isValidSlotIndex(slotIndex)) { Loading Loading @@ -2393,7 +2400,10 @@ public class SubscriptionManagerService extends ISub.Stub { + SubscriptionManager.subscriptionTypeToString(subscriptionType) + ", " + getCallingPackage()); if (!mContext.getResources().getBoolean( com.android.internal.R.bool.config_force_phone_globals_creation)) { enforceTelephonyFeatureWithException(getCurrentPackageName(), "removeSubInfo"); } final long identity = Binder.clearCallingIdentity(); try { Loading Loading @@ -3125,7 +3135,7 @@ public class SubscriptionManagerService extends ISub.Stub { @Override public int getDefaultSubIdAsUser(@UserIdInt int userId) { enforceTelephonyFeatureWithException(getCurrentPackageName(), "getDefaultVoiceSubIdAsUser"); "getDefaultSubIdAsUser"); return getDefaultAsUser(userId, mDefaultSubId.get()); } Loading tests/telephonytests/src/com/android/internal/telephony/subscription/SubscriptionManagerServiceTest.java +143 −0 Original line number Diff line number Diff line Loading @@ -3599,4 +3599,147 @@ public class SubscriptionManagerServiceTest extends TelephonyTest { public void testIsSatelliteProvisionedForNonIpDatagram() { assertFalse(mSubscriptionManagerServiceUT.isSatelliteProvisionedForNonIpDatagram(-1)); } /** * Simulates a device environment where the * {@link PackageManager#FEATURE_TELEPHONY_SUBSCRIPTION} feature is unavailable. * * This is necessary for testing scenarios specific to automotive devices, which * may not always have the telephony subscription feature enabled. It allows us to * verify the behavior of certain APIs when this feature is not available, even if the * test device technically supports it. These APIs should function regardless for * Remote SIM. */ private void simulateNoTelephonySubscriptionSupport() throws Exception { doReturn(false).when(mPackageManager).hasSystemFeature( eq(PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION)); int vendorApiLevel = Build.VERSION_CODES.BAKLAVA; replaceInstance(SubscriptionManagerService.class, "mVendorApiLevel", mSubscriptionManagerServiceUT, vendorApiLevel); mContextFixture.putBooleanResource( com.android.internal.R.bool.config_force_phone_globals_creation, true); } @Test @EnableCompatChanges({TelephonyManager.ENABLE_FEATURE_MAPPING}) public void testRemoteSimNoTelephonySubscription() throws Exception { simulateNoTelephonySubscriptionSupport(); mContextFixture.addCallingOrSelfPermission(Manifest.permission.MODIFY_PHONE_STATE); mContextFixture.addCallingOrSelfPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE); mSubscriptionManagerServiceUT.addSubInfo(FAKE_MAC_ADDRESS1, FAKE_CARRIER_NAME1, 0, SubscriptionManager.SUBSCRIPTION_TYPE_REMOTE_SIM); processAllMessages(); verify(mMockedSubscriptionManagerServiceCallback).onSubscriptionChanged(eq(1)); SubscriptionInfoInternal subInfo = mSubscriptionManagerServiceUT .getSubscriptionInfoInternal(1); assertThat(subInfo.getIccId()).isEqualTo(FAKE_MAC_ADDRESS1); assertThat(subInfo.getDisplayName()).isEqualTo(FAKE_CARRIER_NAME1); assertThat(subInfo.getSimSlotIndex()).isEqualTo( SubscriptionManager.INVALID_SIM_SLOT_INDEX); assertThat(subInfo.getSubscriptionType()).isEqualTo( SubscriptionManager.SUBSCRIPTION_TYPE_REMOTE_SIM); assertThat(mSubscriptionManagerServiceUT.removeSubInfo(FAKE_MAC_ADDRESS1, SubscriptionManager.SUBSCRIPTION_TYPE_REMOTE_SIM)).isEqualTo(true); assertThat(mSubscriptionManagerServiceUT.getAllSubInfoList( CALLING_PACKAGE, CALLING_FEATURE)).isEmpty(); assertThat(mSubscriptionManagerServiceUT.getActiveSubIdList(false)).isEmpty(); assertThat(mSubscriptionManagerServiceUT.getActiveSubscriptionInfoList( CALLING_PACKAGE, CALLING_FEATURE, true)).isEmpty(); setIdentifierAccess(true); mSubscriptionManagerServiceUT.addSubInfo(FAKE_MAC_ADDRESS2, FAKE_CARRIER_NAME2, 0, SubscriptionManager.SUBSCRIPTION_TYPE_REMOTE_SIM); assertThat(mSubscriptionManagerServiceUT.getActiveSubIdList(false)).isNotEmpty(); assertThat(mSubscriptionManagerServiceUT.getActiveSubscriptionInfoList( CALLING_PACKAGE, CALLING_FEATURE, true)).isNotEmpty(); assertThat(mSubscriptionManagerServiceUT.getActiveSubscriptionInfoList( CALLING_PACKAGE, CALLING_FEATURE, true).get(0).getIccId()) .isEqualTo(FAKE_MAC_ADDRESS2); } @Test @EnableCompatChanges({TelephonyManager.ENABLE_FEATURE_MAPPING}) public void testGetActiveSubscriptionInfoListNoTelephonySubscription() throws Exception { simulateNoTelephonySubscriptionSupport(); // Grant MODIFY_PHONE_STATE permission for insertion. mContextFixture.addCallingOrSelfPermission(Manifest.permission.MODIFY_PHONE_STATE); insertSubscription(FAKE_SUBSCRIPTION_INFO1); insertSubscription(new SubscriptionInfoInternal.Builder(FAKE_SUBSCRIPTION_INFO2) .setSimSlotIndex(SubscriptionManager.INVALID_SIM_SLOT_INDEX).build()); // Remove MODIFY_PHONE_STATE mContextFixture.removeCallingOrSelfPermission(Manifest.permission.MODIFY_PHONE_STATE); // Should get an empty list without READ_PHONE_STATE. assertThat(mSubscriptionManagerServiceUT.getActiveSubscriptionInfoList( CALLING_PACKAGE, CALLING_FEATURE, true)).isEmpty(); // Grant READ_PHONE_STATE permission for insertion. mContextFixture.addCallingOrSelfPermission(Manifest.permission.READ_PHONE_STATE); // Allow the application to perform. doReturn(AppOpsManager.MODE_ALLOWED).when(mAppOpsManager) .noteOpNoThrow(eq(AppOpsManager.OPSTR_READ_PHONE_STATE), anyInt(), nullable(String.class), nullable(String.class), nullable(String.class)); List<SubscriptionInfo> subInfos = mSubscriptionManagerServiceUT .getActiveSubscriptionInfoList(CALLING_PACKAGE, CALLING_FEATURE, true); // Identifying information removed assertThat(subInfos).hasSize(1); assertThat(subInfos.get(0).getIccId()).isEmpty(); assertThat(subInfos.get(0).getCardString()).isEmpty(); assertThat(subInfos.get(0).getNumber()).isEmpty(); assertThat(subInfos.get(0).getGroupUuid()).isNull(); // Grant carrier privilege setCarrierPrivilegesForSubId(true, 1); subInfos = mSubscriptionManagerServiceUT .getActiveSubscriptionInfoList(CALLING_PACKAGE, CALLING_FEATURE, true); assertThat(subInfos).hasSize(1); assertThat(subInfos.get(0)).isEqualTo(FAKE_SUBSCRIPTION_INFO1.toSubscriptionInfo()); } @Test @EnableCompatChanges({TelephonyManager.ENABLE_FEATURE_MAPPING}) public void testGetActiveSubscriptionInfoForIccIdNoTelephonySubscription() throws Exception { simulateNoTelephonySubscriptionSupport(); insertSubscription(FAKE_SUBSCRIPTION_INFO1); // Should fail without READ_PRIVILEGED_PHONE_STATE assertThrows(SecurityException.class, () -> mSubscriptionManagerServiceUT .getActiveSubscriptionInfoForIccId(FAKE_ICCID1, CALLING_PACKAGE, CALLING_FEATURE)); mContextFixture.addCallingOrSelfPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE); SubscriptionInfo subInfo = mSubscriptionManagerServiceUT.getActiveSubscriptionInfoForIccId( FAKE_ICCID1, CALLING_PACKAGE, CALLING_FEATURE); assertThat(subInfo).isEqualTo(FAKE_SUBSCRIPTION_INFO1.toSubscriptionInfo()); } @Test @EnableCompatChanges({TelephonyManager.ENABLE_FEATURE_MAPPING}) public void testRemoveSubInfoNoTelephonySubscription() throws Exception { simulateNoTelephonySubscriptionSupport(); insertSubscription(FAKE_SUBSCRIPTION_INFO1); insertSubscription(FAKE_SUBSCRIPTION_INFO2); assertThrows(SecurityException.class, () -> mSubscriptionManagerServiceUT .removeSubInfo(FAKE_ICCID1, SubscriptionManager.SUBSCRIPTION_TYPE_LOCAL_SIM)); mContextFixture.addCallingOrSelfPermission(Manifest.permission.MODIFY_PHONE_STATE); assertThat(mSubscriptionManagerServiceUT.removeSubInfo(FAKE_ICCID1, SubscriptionManager.SUBSCRIPTION_TYPE_LOCAL_SIM)).isEqualTo(true); assertThat(mSubscriptionManagerServiceUT.removeSubInfo(FAKE_ICCID2, SubscriptionManager.SUBSCRIPTION_TYPE_LOCAL_SIM)).isEqualTo(true); mContextFixture.addCallingOrSelfPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE); assertThat(mSubscriptionManagerServiceUT.getActiveSubscriptionInfoList( CALLING_PACKAGE, CALLING_FEATURE, true)).isEmpty(); } } Loading
src/java/com/android/internal/telephony/subscription/SubscriptionManagerService.java +14 −4 Original line number Diff line number Diff line Loading @@ -2010,7 +2010,11 @@ public class SubscriptionManagerService extends ISub.Stub { enforcePermissions("getActiveSubscriptionInfoForIccId", Manifest.permission.READ_PRIVILEGED_PHONE_STATE); enforceTelephonyFeatureWithException(callingPackage, "getActiveSubscriptionInfoForIccId"); if (!mContext.getResources().getBoolean( com.android.internal.R.bool.config_force_phone_globals_creation)) { enforceTelephonyFeatureWithException(callingPackage, "getActiveSubscriptionInfoForIccId"); } final long identity = Binder.clearCallingIdentity(); try { Loading Loading @@ -2322,7 +2326,10 @@ public class SubscriptionManagerService extends ISub.Stub { + SubscriptionManager.subscriptionTypeToString(subscriptionType) + ", " + getCallingPackage()); if (!mContext.getResources().getBoolean( com.android.internal.R.bool.config_force_phone_globals_creation)) { enforceTelephonyFeatureWithException(getCurrentPackageName(), "addSubInfo"); } if (subscriptionType == SubscriptionManager.SUBSCRIPTION_TYPE_LOCAL_SIM) { if (!SubscriptionManager.isValidSlotIndex(slotIndex)) { Loading Loading @@ -2393,7 +2400,10 @@ public class SubscriptionManagerService extends ISub.Stub { + SubscriptionManager.subscriptionTypeToString(subscriptionType) + ", " + getCallingPackage()); if (!mContext.getResources().getBoolean( com.android.internal.R.bool.config_force_phone_globals_creation)) { enforceTelephonyFeatureWithException(getCurrentPackageName(), "removeSubInfo"); } final long identity = Binder.clearCallingIdentity(); try { Loading Loading @@ -3125,7 +3135,7 @@ public class SubscriptionManagerService extends ISub.Stub { @Override public int getDefaultSubIdAsUser(@UserIdInt int userId) { enforceTelephonyFeatureWithException(getCurrentPackageName(), "getDefaultVoiceSubIdAsUser"); "getDefaultSubIdAsUser"); return getDefaultAsUser(userId, mDefaultSubId.get()); } Loading
tests/telephonytests/src/com/android/internal/telephony/subscription/SubscriptionManagerServiceTest.java +143 −0 Original line number Diff line number Diff line Loading @@ -3599,4 +3599,147 @@ public class SubscriptionManagerServiceTest extends TelephonyTest { public void testIsSatelliteProvisionedForNonIpDatagram() { assertFalse(mSubscriptionManagerServiceUT.isSatelliteProvisionedForNonIpDatagram(-1)); } /** * Simulates a device environment where the * {@link PackageManager#FEATURE_TELEPHONY_SUBSCRIPTION} feature is unavailable. * * This is necessary for testing scenarios specific to automotive devices, which * may not always have the telephony subscription feature enabled. It allows us to * verify the behavior of certain APIs when this feature is not available, even if the * test device technically supports it. These APIs should function regardless for * Remote SIM. */ private void simulateNoTelephonySubscriptionSupport() throws Exception { doReturn(false).when(mPackageManager).hasSystemFeature( eq(PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION)); int vendorApiLevel = Build.VERSION_CODES.BAKLAVA; replaceInstance(SubscriptionManagerService.class, "mVendorApiLevel", mSubscriptionManagerServiceUT, vendorApiLevel); mContextFixture.putBooleanResource( com.android.internal.R.bool.config_force_phone_globals_creation, true); } @Test @EnableCompatChanges({TelephonyManager.ENABLE_FEATURE_MAPPING}) public void testRemoteSimNoTelephonySubscription() throws Exception { simulateNoTelephonySubscriptionSupport(); mContextFixture.addCallingOrSelfPermission(Manifest.permission.MODIFY_PHONE_STATE); mContextFixture.addCallingOrSelfPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE); mSubscriptionManagerServiceUT.addSubInfo(FAKE_MAC_ADDRESS1, FAKE_CARRIER_NAME1, 0, SubscriptionManager.SUBSCRIPTION_TYPE_REMOTE_SIM); processAllMessages(); verify(mMockedSubscriptionManagerServiceCallback).onSubscriptionChanged(eq(1)); SubscriptionInfoInternal subInfo = mSubscriptionManagerServiceUT .getSubscriptionInfoInternal(1); assertThat(subInfo.getIccId()).isEqualTo(FAKE_MAC_ADDRESS1); assertThat(subInfo.getDisplayName()).isEqualTo(FAKE_CARRIER_NAME1); assertThat(subInfo.getSimSlotIndex()).isEqualTo( SubscriptionManager.INVALID_SIM_SLOT_INDEX); assertThat(subInfo.getSubscriptionType()).isEqualTo( SubscriptionManager.SUBSCRIPTION_TYPE_REMOTE_SIM); assertThat(mSubscriptionManagerServiceUT.removeSubInfo(FAKE_MAC_ADDRESS1, SubscriptionManager.SUBSCRIPTION_TYPE_REMOTE_SIM)).isEqualTo(true); assertThat(mSubscriptionManagerServiceUT.getAllSubInfoList( CALLING_PACKAGE, CALLING_FEATURE)).isEmpty(); assertThat(mSubscriptionManagerServiceUT.getActiveSubIdList(false)).isEmpty(); assertThat(mSubscriptionManagerServiceUT.getActiveSubscriptionInfoList( CALLING_PACKAGE, CALLING_FEATURE, true)).isEmpty(); setIdentifierAccess(true); mSubscriptionManagerServiceUT.addSubInfo(FAKE_MAC_ADDRESS2, FAKE_CARRIER_NAME2, 0, SubscriptionManager.SUBSCRIPTION_TYPE_REMOTE_SIM); assertThat(mSubscriptionManagerServiceUT.getActiveSubIdList(false)).isNotEmpty(); assertThat(mSubscriptionManagerServiceUT.getActiveSubscriptionInfoList( CALLING_PACKAGE, CALLING_FEATURE, true)).isNotEmpty(); assertThat(mSubscriptionManagerServiceUT.getActiveSubscriptionInfoList( CALLING_PACKAGE, CALLING_FEATURE, true).get(0).getIccId()) .isEqualTo(FAKE_MAC_ADDRESS2); } @Test @EnableCompatChanges({TelephonyManager.ENABLE_FEATURE_MAPPING}) public void testGetActiveSubscriptionInfoListNoTelephonySubscription() throws Exception { simulateNoTelephonySubscriptionSupport(); // Grant MODIFY_PHONE_STATE permission for insertion. mContextFixture.addCallingOrSelfPermission(Manifest.permission.MODIFY_PHONE_STATE); insertSubscription(FAKE_SUBSCRIPTION_INFO1); insertSubscription(new SubscriptionInfoInternal.Builder(FAKE_SUBSCRIPTION_INFO2) .setSimSlotIndex(SubscriptionManager.INVALID_SIM_SLOT_INDEX).build()); // Remove MODIFY_PHONE_STATE mContextFixture.removeCallingOrSelfPermission(Manifest.permission.MODIFY_PHONE_STATE); // Should get an empty list without READ_PHONE_STATE. assertThat(mSubscriptionManagerServiceUT.getActiveSubscriptionInfoList( CALLING_PACKAGE, CALLING_FEATURE, true)).isEmpty(); // Grant READ_PHONE_STATE permission for insertion. mContextFixture.addCallingOrSelfPermission(Manifest.permission.READ_PHONE_STATE); // Allow the application to perform. doReturn(AppOpsManager.MODE_ALLOWED).when(mAppOpsManager) .noteOpNoThrow(eq(AppOpsManager.OPSTR_READ_PHONE_STATE), anyInt(), nullable(String.class), nullable(String.class), nullable(String.class)); List<SubscriptionInfo> subInfos = mSubscriptionManagerServiceUT .getActiveSubscriptionInfoList(CALLING_PACKAGE, CALLING_FEATURE, true); // Identifying information removed assertThat(subInfos).hasSize(1); assertThat(subInfos.get(0).getIccId()).isEmpty(); assertThat(subInfos.get(0).getCardString()).isEmpty(); assertThat(subInfos.get(0).getNumber()).isEmpty(); assertThat(subInfos.get(0).getGroupUuid()).isNull(); // Grant carrier privilege setCarrierPrivilegesForSubId(true, 1); subInfos = mSubscriptionManagerServiceUT .getActiveSubscriptionInfoList(CALLING_PACKAGE, CALLING_FEATURE, true); assertThat(subInfos).hasSize(1); assertThat(subInfos.get(0)).isEqualTo(FAKE_SUBSCRIPTION_INFO1.toSubscriptionInfo()); } @Test @EnableCompatChanges({TelephonyManager.ENABLE_FEATURE_MAPPING}) public void testGetActiveSubscriptionInfoForIccIdNoTelephonySubscription() throws Exception { simulateNoTelephonySubscriptionSupport(); insertSubscription(FAKE_SUBSCRIPTION_INFO1); // Should fail without READ_PRIVILEGED_PHONE_STATE assertThrows(SecurityException.class, () -> mSubscriptionManagerServiceUT .getActiveSubscriptionInfoForIccId(FAKE_ICCID1, CALLING_PACKAGE, CALLING_FEATURE)); mContextFixture.addCallingOrSelfPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE); SubscriptionInfo subInfo = mSubscriptionManagerServiceUT.getActiveSubscriptionInfoForIccId( FAKE_ICCID1, CALLING_PACKAGE, CALLING_FEATURE); assertThat(subInfo).isEqualTo(FAKE_SUBSCRIPTION_INFO1.toSubscriptionInfo()); } @Test @EnableCompatChanges({TelephonyManager.ENABLE_FEATURE_MAPPING}) public void testRemoveSubInfoNoTelephonySubscription() throws Exception { simulateNoTelephonySubscriptionSupport(); insertSubscription(FAKE_SUBSCRIPTION_INFO1); insertSubscription(FAKE_SUBSCRIPTION_INFO2); assertThrows(SecurityException.class, () -> mSubscriptionManagerServiceUT .removeSubInfo(FAKE_ICCID1, SubscriptionManager.SUBSCRIPTION_TYPE_LOCAL_SIM)); mContextFixture.addCallingOrSelfPermission(Manifest.permission.MODIFY_PHONE_STATE); assertThat(mSubscriptionManagerServiceUT.removeSubInfo(FAKE_ICCID1, SubscriptionManager.SUBSCRIPTION_TYPE_LOCAL_SIM)).isEqualTo(true); assertThat(mSubscriptionManagerServiceUT.removeSubInfo(FAKE_ICCID2, SubscriptionManager.SUBSCRIPTION_TYPE_LOCAL_SIM)).isEqualTo(true); mContextFixture.addCallingOrSelfPermission(Manifest.permission.READ_PRIVILEGED_PHONE_STATE); assertThat(mSubscriptionManagerServiceUT.getActiveSubscriptionInfoList( CALLING_PACKAGE, CALLING_FEATURE, true)).isEmpty(); } }