Loading src/java/com/android/internal/telephony/PhoneSubInfoController.java +126 −7 Original line number Diff line number Diff line Loading @@ -20,10 +20,12 @@ package com.android.internal.telephony; import static android.Manifest.permission.MODIFY_PHONE_STATE; import static android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE; import static android.telephony.TelephonyManager.ENABLE_FEATURE_MAPPING; import android.annotation.NonNull; import android.annotation.Nullable; import android.app.AppOpsManager; import android.app.compat.CompatChanges; import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.pm.PackageManager; Loading @@ -39,6 +41,8 @@ import android.telephony.TelephonyFrameworkInitializer; import android.text.TextUtils; import android.util.EventLog; import com.android.internal.telephony.flags.FeatureFlags; import com.android.internal.telephony.flags.FeatureFlagsImpl; import com.android.internal.telephony.subscription.SubscriptionInfoInternal; import com.android.internal.telephony.subscription.SubscriptionManagerService; import com.android.internal.telephony.uicc.IsimRecords; Loading @@ -58,8 +62,14 @@ public class PhoneSubInfoController extends IPhoneSubInfo.Stub { @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private final Context mContext; private AppOpsManager mAppOps; private FeatureFlags mFeatureFlags; private PackageManager mPackageManager; public PhoneSubInfoController(Context context) { this(context, new FeatureFlagsImpl()); } public PhoneSubInfoController(Context context, FeatureFlags featureFlags) { ServiceRegisterer phoneSubServiceRegisterer = TelephonyFrameworkInitializer .getTelephonyServiceManager() .getPhoneSubServiceRegisterer(); Loading @@ -68,6 +78,8 @@ public class PhoneSubInfoController extends IPhoneSubInfo.Stub { } mAppOps = context.getSystemService(AppOpsManager.class); mContext = context; mPackageManager = context.getPackageManager(); mFeatureFlags = featureFlags; } @Deprecated Loading @@ -89,7 +101,13 @@ public class PhoneSubInfoController extends IPhoneSubInfo.Stub { public String getNaiForSubscriber(int subId, String callingPackage, String callingFeatureId) { return callPhoneMethodForSubIdWithReadSubscriberIdentifiersCheck(subId, callingPackage, callingFeatureId, "getNai", (phone)-> phone.getNai()); callingFeatureId, "getNai", (phone)-> { enforceTelephonyFeatureWithException(callingPackage, PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION, "getNaiForSubscriber"); return phone.getNai(); }); } public String getImeiForSubscriber(int subId, String callingPackage, Loading @@ -102,7 +120,13 @@ public class PhoneSubInfoController extends IPhoneSubInfo.Stub { String callingPackage) { return callPhoneMethodForSubIdWithPrivilegedCheck(subId, "getCarrierInfoForImsiEncryption", (phone)-> phone.getCarrierInfoForImsiEncryption(keyType, true)); (phone)-> { enforceTelephonyFeatureWithException(callingPackage, PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION, "getCarrierInfoForImsiEncryption"); return phone.getCarrierInfoForImsiEncryption(keyType, true); }); } public void setCarrierInfoForImsiEncryption(int subId, String callingPackage, Loading @@ -126,6 +150,10 @@ public class PhoneSubInfoController extends IPhoneSubInfo.Stub { callPhoneMethodForSubIdWithModifyCheck(subId, callingPackage, "resetCarrierKeysForImsiEncryption", (phone)-> { enforceTelephonyFeatureWithException(callingPackage, PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION, "resetCarrierKeysForImsiEncryption"); phone.resetCarrierKeysForImsiEncryption(); return null; }); Loading Loading @@ -166,12 +194,22 @@ public class PhoneSubInfoController extends IPhoneSubInfo.Stub { } if (isActive) { return callPhoneMethodForSubIdWithReadSubscriberIdentifiersCheck(subId, callingPackage, callingFeatureId, message, (phone) -> phone.getSubscriberId()); callingFeatureId, message, (phone) -> { enforceTelephonyFeatureWithException(callingPackage, PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION, "getSubscriberIdForSubscriber"); return phone.getSubscriberId(); }); } else { if (!TelephonyPermissions.checkCallingOrSelfReadSubscriberIdentifiers( mContext, subId, callingPackage, callingFeatureId, message)) { return null; } enforceTelephonyFeatureWithException(callingPackage, PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION, "getSubscriberIdForSubscriber"); identity = Binder.clearCallingIdentity(); try { SubscriptionInfoInternal subInfo = SubscriptionManagerService.getInstance() Loading Loading @@ -202,7 +240,13 @@ public class PhoneSubInfoController extends IPhoneSubInfo.Stub { public String getIccSerialNumberForSubscriber(int subId, String callingPackage, String callingFeatureId) { return callPhoneMethodForSubIdWithReadSubscriberIdentifiersCheck(subId, callingPackage, callingFeatureId, "getIccSerialNumber", (phone) -> phone.getIccSerialNumber()); callingFeatureId, "getIccSerialNumber", (phone) -> { enforceTelephonyFeatureWithException(callingPackage, PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION, "getIccSerialNumberForSubscriber"); return phone.getIccSerialNumber(); }); } public String getLine1Number(String callingPackage, String callingFeatureId) { Loading @@ -216,7 +260,13 @@ public class PhoneSubInfoController extends IPhoneSubInfo.Stub { String callingFeatureId) { return callPhoneMethodForSubIdWithReadPhoneNumberCheck( subId, callingPackage, callingFeatureId, "getLine1Number", (phone)-> phone.getLine1Number()); (phone)-> { enforceTelephonyFeatureWithException(callingPackage, PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION, "getLine1NumberForSubscriber"); return phone.getLine1Number(); }); } public String getLine1AlphaTag(String callingPackage, String callingFeatureId) { Loading Loading @@ -251,6 +301,10 @@ public class PhoneSubInfoController extends IPhoneSubInfo.Stub { String callingFeatureId) { return callPhoneMethodForSubIdWithReadCheck(subId, callingPackage, callingFeatureId, "getVoiceMailNumber", (phone)-> { enforceTelephonyFeatureWithException(callingPackage, PackageManager.FEATURE_TELEPHONY_CALLING, "getVoiceMailNumberForSubscriber"); String number = PhoneNumberUtils.extractNetworkPortion( phone.getVoiceMailNumber()); if (VDBG) log("VM: getVoiceMailNUmber: " + number); Loading @@ -266,7 +320,13 @@ public class PhoneSubInfoController extends IPhoneSubInfo.Stub { public String getVoiceMailAlphaTagForSubscriber(int subId, String callingPackage, String callingFeatureId) { return callPhoneMethodForSubIdWithReadCheck(subId, callingPackage, callingFeatureId, "getVoiceMailAlphaTag", (phone)-> phone.getVoiceMailAlphaTag()); "getVoiceMailAlphaTag", (phone)-> { enforceTelephonyFeatureWithException(callingPackage, PackageManager.FEATURE_TELEPHONY_CALLING, "getVoiceMailAlphaTagForSubscriber"); return phone.getVoiceMailAlphaTag(); }); } /** Loading Loading @@ -381,6 +441,9 @@ public class PhoneSubInfoController extends IPhoneSubInfo.Stub { public String getIsimDomain(int subId) { return callPhoneMethodForSubIdWithPrivilegedCheck(subId, "getIsimDomain", (phone) -> { enforceTelephonyFeatureWithException(getCurrentPackageName(), PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION, "getIsimDomain"); IsimRecords isim = phone.getIsimRecords(); if (isim != null) { return isim.getIsimDomain(); Loading Loading @@ -422,6 +485,10 @@ public class PhoneSubInfoController extends IPhoneSubInfo.Stub { if (TelephonyPermissions. checkCallingOrSelfReadPrivilegedPhoneStatePermissionOrReadPhoneNumber( mContext, subId, callingPackage, callingFeatureId, "getImsPublicUserIdentities")) { enforceTelephonyFeatureWithException(callingPackage, PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION, "getImsPublicUserIdentities"); Phone phone = getPhone(subId); assert phone != null; IsimRecords isimRecords = phone.getIsimRecords(); Loading @@ -447,6 +514,9 @@ public class PhoneSubInfoController extends IPhoneSubInfo.Stub { public String getIsimIst(int subId) throws RemoteException { return callPhoneMethodForSubIdWithPrivilegedCheck(subId, "getIsimIst", (phone) -> { enforceTelephonyFeatureWithException(getCurrentPackageName(), PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION, "getIsimIst"); IsimRecords isim = phone.getIsimRecords(); if (isim != null) { return isim.getIsimIst(); Loading Loading @@ -478,6 +548,9 @@ public class PhoneSubInfoController extends IPhoneSubInfo.Stub { public String getSimServiceTable(int subId, int appType) throws RemoteException { return callPhoneMethodForSubIdWithPrivilegedCheck(subId, "getSimServiceTable", (phone) -> { enforceTelephonyFeatureWithException(getCurrentPackageName(), PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION, "getSimServiceTable"); UiccPort uiccPort = phone.getUiccPort(); if (uiccPort == null || uiccPort.getUiccProfile() == null) { loge("getSimServiceTable(): uiccPort or uiccProfile is null"); Loading @@ -498,6 +571,9 @@ public class PhoneSubInfoController extends IPhoneSubInfo.Stub { public String getIccSimChallengeResponse(int subId, int appType, int authType, String data, String callingPackage, String callingFeatureId) throws RemoteException { CallPhoneMethodHelper<String> toExecute = (phone)-> { enforceTelephonyFeatureWithException(callingPackage, PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION, "getIccSimChallengeResponse"); UiccPort uiccPort = phone.getUiccPort(); if (uiccPort == null) { loge("getIccSimChallengeResponse() uiccPort is null"); Loading Loading @@ -531,7 +607,13 @@ public class PhoneSubInfoController extends IPhoneSubInfo.Stub { public String getGroupIdLevel1ForSubscriber(int subId, String callingPackage, String callingFeatureId) { return callPhoneMethodForSubIdWithReadCheck(subId, callingPackage, callingFeatureId, "getGroupIdLevel1", (phone)-> phone.getGroupIdLevel1()); "getGroupIdLevel1", (phone)-> { enforceTelephonyFeatureWithException(callingPackage, PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION, "getGroupIdLevel1ForSubscriber"); return phone.getGroupIdLevel1(); }); } /** Below are utility methods that abstracts the flow that many public methods use: Loading Loading @@ -667,6 +749,9 @@ public class PhoneSubInfoController extends IPhoneSubInfo.Stub { public Uri getSmscIdentity(int subId, int appType) throws RemoteException { Uri smscIdentityUri = callPhoneMethodForSubIdWithPrivilegedCheck(subId, "getSmscIdentity", (phone) -> { enforceTelephonyFeatureWithException(getCurrentPackageName(), PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION, "getSmscIdentity"); try { String smscIdentity = null; UiccPort uiccPort = phone.getUiccPort(); Loading @@ -690,6 +775,40 @@ public class PhoneSubInfoController extends IPhoneSubInfo.Stub { return smscIdentityUri; } /** * Get the current calling package name. * @return the current calling package name */ @Nullable private String getCurrentPackageName() { if (mPackageManager == null) return null; String[] callingUids = mPackageManager.getPackagesForUid(Binder.getCallingUid()); return (callingUids == null) ? null : callingUids[0]; } /** * Make sure the device has required telephony feature * * @throws UnsupportedOperationException if the device does not have required telephony feature */ private void enforceTelephonyFeatureWithException(@Nullable String callingPackage, @NonNull String telephonyFeature, @NonNull String methodName) { if (callingPackage == null || mPackageManager == null) { return; } if (!mFeatureFlags.enforceTelephonyFeatureMappingForPublicApis() || !CompatChanges.isChangeEnabled(ENABLE_FEATURE_MAPPING, callingPackage, Binder.getCallingUserHandle())) { return; } if (!mPackageManager.hasSystemFeature(telephonyFeature)) { throw new UnsupportedOperationException( methodName + " is unsupported without " + telephonyFeature); } } private void log(String s) { Rlog.d(TAG, s); } Loading tests/telephonytests/src/com/android/internal/telephony/PhoneSubInfoControllerTest.java +58 −17 Original line number Diff line number Diff line Loading @@ -23,8 +23,10 @@ import static android.telephony.TelephonyManager.APPTYPE_USIM; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertThrows; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.ArgumentMatchers.nullable; import static org.mockito.Matchers.anyInt; import static org.mockito.Mockito.doReturn; Loading @@ -33,14 +35,15 @@ import static org.mockito.Mockito.mock; import android.app.AppOpsManager; import android.app.PropertyInvalidatedCache; import android.compat.testing.PlatformCompatChangeRule; import android.content.Context; import android.content.pm.PackageManager; import android.net.Uri; import android.os.Binder; import android.os.Build; import android.os.RemoteException; import androidx.test.filters.SmallTest; import android.telephony.TelephonyManager; import android.test.suitebuilder.annotation.SmallTest; import com.android.internal.telephony.uicc.IsimUiccRecords; import com.android.internal.telephony.uicc.SIMRecords; Loading @@ -48,10 +51,14 @@ import com.android.internal.telephony.uicc.UiccCardApplication; import com.android.internal.telephony.uicc.UiccPort; import com.android.internal.telephony.uicc.UiccProfile; import libcore.junit.util.compat.CoreCompatChangeRule.EnableCompatChanges; import org.junit.After; import org.junit.Assert; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.rules.TestRule; import org.mockito.Mockito; import java.util.List; Loading @@ -63,6 +70,9 @@ public class PhoneSubInfoControllerTest extends TelephonyTest { private static final String PSI_SMSC_TEL2 = "tel:+91987654321"; private static final String PSI_SMSC_SIP2 = "sip:+19876543210@dcf.pc.operetor2.com;user=phone"; @Rule public TestRule compatChangeRule = new PlatformCompatChangeRule(); private PhoneSubInfoController mPhoneSubInfoControllerUT; private AppOpsManager mAppOsMgr; private PackageManager mPm; Loading Loading @@ -92,7 +102,7 @@ public class PhoneSubInfoControllerTest extends TelephonyTest { mPm = mContext.getPackageManager(); replaceInstance(PhoneFactory.class, "sPhones", null, new Phone[]{mPhone, mSecondPhone}); mPhoneSubInfoControllerUT = new PhoneSubInfoController(mContext); mPhoneSubInfoControllerUT = new PhoneSubInfoController(mContext, mFeatureFlags); setupMocksForTelephonyPermissions(); // TelephonyPermissions will query the READ_DEVICE_IDENTIFIERS op from AppOpManager to Loading @@ -105,6 +115,12 @@ public class PhoneSubInfoControllerTest extends TelephonyTest { // Bypass calling package check. doReturn(Binder.getCallingUid()).when(mPm).getPackageUid(eq(TAG), anyInt()); // In order not to affect the existing implementation, define a telephony features // and disabled enforce_telephony_feature_mapping_for_public_apis feature flag doReturn(false).when(mFeatureFlags).enforceTelephonyFeatureMappingForPublicApis(); doReturn(true).when(mPm).hasSystemFeature(anyString()); doReturn(new String[] {TAG}).when(mPm).getPackagesForUid(anyInt()); } @After Loading Loading @@ -211,6 +227,31 @@ public class PhoneSubInfoControllerTest extends TelephonyTest { mPhoneSubInfoControllerUT.getNaiForSubscriber(1, TAG, FEATURE_ID)); } @Test @SmallTest @EnableCompatChanges({TelephonyManager.ENABLE_FEATURE_MAPPING}) public void testGetNai_EnabledEnforceTelephonyFeatureMappingForPublicApis() { // FeatureFlags enabled, System has required feature doReturn(true).when(mFeatureFlags).enforceTelephonyFeatureMappingForPublicApis(); doReturn(true).when(mPm).hasSystemFeature( eq(PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION)); doReturn("bbb@example.com").when(mSecondPhone).getNai(); // Enabled FeatureFlags and ENABLE_FEATURE_MAPPING, telephony features are defined try { assertEquals("bbb@example.com", mPhoneSubInfoControllerUT.getNaiForSubscriber(1, TAG, FEATURE_ID)); } catch (UnsupportedOperationException e) { fail("Not expect exception " + e.getMessage()); } // Telephony features is not defined, expect UnsupportedOperationException. doReturn(false).when(mPm).hasSystemFeature( eq(PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION)); assertThrows(UnsupportedOperationException.class, () -> mPhoneSubInfoControllerUT.getNaiForSubscriber(1, TAG, FEATURE_ID)); } @Test @SmallTest public void testGetNaiWithOutPermission() { Loading Loading @@ -1087,7 +1128,7 @@ public class PhoneSubInfoControllerTest extends TelephonyTest { doReturn(refSst).when(mSimRecords).getSimServiceTable(); String resultSst = mPhoneSubInfoControllerUT.getSimServiceTable(anyInt(), anyInt()); String resultSst = mPhoneSubInfoControllerUT.getSimServiceTable(0, 0); assertEquals(refSst, resultSst); } Loading @@ -1101,7 +1142,7 @@ public class PhoneSubInfoControllerTest extends TelephonyTest { doReturn(refSst).when(mSimRecords).getSimServiceTable(); String resultSst = mPhoneSubInfoControllerUT.getSimServiceTable(anyInt(), anyInt()); String resultSst = mPhoneSubInfoControllerUT.getSimServiceTable(0, 0); assertEquals(refSst, resultSst); } Loading @@ -1115,7 +1156,7 @@ public class PhoneSubInfoControllerTest extends TelephonyTest { doReturn(refSst).when(mSimRecords).getSimServiceTable(); String resultSst = mPhoneSubInfoControllerUT.getSimServiceTable(anyInt(), anyInt()); String resultSst = mPhoneSubInfoControllerUT.getSimServiceTable(0, 0); assertEquals(null, resultSst); } Loading @@ -1129,7 +1170,7 @@ public class PhoneSubInfoControllerTest extends TelephonyTest { doReturn(refSst).when(mSimRecords).getSimServiceTable(); String resultSst = mPhoneSubInfoControllerUT.getSimServiceTable(anyInt(), anyInt()); String resultSst = mPhoneSubInfoControllerUT.getSimServiceTable(0, 0); assertEquals(null, resultSst); } Loading @@ -1143,7 +1184,7 @@ public class PhoneSubInfoControllerTest extends TelephonyTest { doReturn(refSst).when(mSimRecords).getSimServiceTable(); String resultSst = mPhoneSubInfoControllerUT.getSimServiceTable(anyInt(), anyInt()); String resultSst = mPhoneSubInfoControllerUT.getSimServiceTable(0, 0); assertEquals(null, resultSst); } Loading @@ -1159,7 +1200,7 @@ public class PhoneSubInfoControllerTest extends TelephonyTest { mContextFixture.removeCallingOrSelfPermission(ContextFixture.PERMISSION_ENABLE_ALL); try { mPhoneSubInfoControllerUT.getSimServiceTable(anyInt(), anyInt()); mPhoneSubInfoControllerUT.getSimServiceTable(0, 0); Assert.fail("expected Security Exception Thrown"); } catch (Exception ex) { assertTrue(ex instanceof SecurityException); Loading @@ -1167,7 +1208,7 @@ public class PhoneSubInfoControllerTest extends TelephonyTest { } mContextFixture.addCallingOrSelfPermission(READ_PRIVILEGED_PHONE_STATE); assertEquals(refSst, mPhoneSubInfoControllerUT.getSimServiceTable(anyInt(), anyInt())); assertEquals(refSst, mPhoneSubInfoControllerUT.getSimServiceTable(0, 0)); } @Test Loading Loading
src/java/com/android/internal/telephony/PhoneSubInfoController.java +126 −7 Original line number Diff line number Diff line Loading @@ -20,10 +20,12 @@ package com.android.internal.telephony; import static android.Manifest.permission.MODIFY_PHONE_STATE; import static android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE; import static android.telephony.TelephonyManager.ENABLE_FEATURE_MAPPING; import android.annotation.NonNull; import android.annotation.Nullable; import android.app.AppOpsManager; import android.app.compat.CompatChanges; import android.compat.annotation.UnsupportedAppUsage; import android.content.Context; import android.content.pm.PackageManager; Loading @@ -39,6 +41,8 @@ import android.telephony.TelephonyFrameworkInitializer; import android.text.TextUtils; import android.util.EventLog; import com.android.internal.telephony.flags.FeatureFlags; import com.android.internal.telephony.flags.FeatureFlagsImpl; import com.android.internal.telephony.subscription.SubscriptionInfoInternal; import com.android.internal.telephony.subscription.SubscriptionManagerService; import com.android.internal.telephony.uicc.IsimRecords; Loading @@ -58,8 +62,14 @@ public class PhoneSubInfoController extends IPhoneSubInfo.Stub { @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private final Context mContext; private AppOpsManager mAppOps; private FeatureFlags mFeatureFlags; private PackageManager mPackageManager; public PhoneSubInfoController(Context context) { this(context, new FeatureFlagsImpl()); } public PhoneSubInfoController(Context context, FeatureFlags featureFlags) { ServiceRegisterer phoneSubServiceRegisterer = TelephonyFrameworkInitializer .getTelephonyServiceManager() .getPhoneSubServiceRegisterer(); Loading @@ -68,6 +78,8 @@ public class PhoneSubInfoController extends IPhoneSubInfo.Stub { } mAppOps = context.getSystemService(AppOpsManager.class); mContext = context; mPackageManager = context.getPackageManager(); mFeatureFlags = featureFlags; } @Deprecated Loading @@ -89,7 +101,13 @@ public class PhoneSubInfoController extends IPhoneSubInfo.Stub { public String getNaiForSubscriber(int subId, String callingPackage, String callingFeatureId) { return callPhoneMethodForSubIdWithReadSubscriberIdentifiersCheck(subId, callingPackage, callingFeatureId, "getNai", (phone)-> phone.getNai()); callingFeatureId, "getNai", (phone)-> { enforceTelephonyFeatureWithException(callingPackage, PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION, "getNaiForSubscriber"); return phone.getNai(); }); } public String getImeiForSubscriber(int subId, String callingPackage, Loading @@ -102,7 +120,13 @@ public class PhoneSubInfoController extends IPhoneSubInfo.Stub { String callingPackage) { return callPhoneMethodForSubIdWithPrivilegedCheck(subId, "getCarrierInfoForImsiEncryption", (phone)-> phone.getCarrierInfoForImsiEncryption(keyType, true)); (phone)-> { enforceTelephonyFeatureWithException(callingPackage, PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION, "getCarrierInfoForImsiEncryption"); return phone.getCarrierInfoForImsiEncryption(keyType, true); }); } public void setCarrierInfoForImsiEncryption(int subId, String callingPackage, Loading @@ -126,6 +150,10 @@ public class PhoneSubInfoController extends IPhoneSubInfo.Stub { callPhoneMethodForSubIdWithModifyCheck(subId, callingPackage, "resetCarrierKeysForImsiEncryption", (phone)-> { enforceTelephonyFeatureWithException(callingPackage, PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION, "resetCarrierKeysForImsiEncryption"); phone.resetCarrierKeysForImsiEncryption(); return null; }); Loading Loading @@ -166,12 +194,22 @@ public class PhoneSubInfoController extends IPhoneSubInfo.Stub { } if (isActive) { return callPhoneMethodForSubIdWithReadSubscriberIdentifiersCheck(subId, callingPackage, callingFeatureId, message, (phone) -> phone.getSubscriberId()); callingFeatureId, message, (phone) -> { enforceTelephonyFeatureWithException(callingPackage, PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION, "getSubscriberIdForSubscriber"); return phone.getSubscriberId(); }); } else { if (!TelephonyPermissions.checkCallingOrSelfReadSubscriberIdentifiers( mContext, subId, callingPackage, callingFeatureId, message)) { return null; } enforceTelephonyFeatureWithException(callingPackage, PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION, "getSubscriberIdForSubscriber"); identity = Binder.clearCallingIdentity(); try { SubscriptionInfoInternal subInfo = SubscriptionManagerService.getInstance() Loading Loading @@ -202,7 +240,13 @@ public class PhoneSubInfoController extends IPhoneSubInfo.Stub { public String getIccSerialNumberForSubscriber(int subId, String callingPackage, String callingFeatureId) { return callPhoneMethodForSubIdWithReadSubscriberIdentifiersCheck(subId, callingPackage, callingFeatureId, "getIccSerialNumber", (phone) -> phone.getIccSerialNumber()); callingFeatureId, "getIccSerialNumber", (phone) -> { enforceTelephonyFeatureWithException(callingPackage, PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION, "getIccSerialNumberForSubscriber"); return phone.getIccSerialNumber(); }); } public String getLine1Number(String callingPackage, String callingFeatureId) { Loading @@ -216,7 +260,13 @@ public class PhoneSubInfoController extends IPhoneSubInfo.Stub { String callingFeatureId) { return callPhoneMethodForSubIdWithReadPhoneNumberCheck( subId, callingPackage, callingFeatureId, "getLine1Number", (phone)-> phone.getLine1Number()); (phone)-> { enforceTelephonyFeatureWithException(callingPackage, PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION, "getLine1NumberForSubscriber"); return phone.getLine1Number(); }); } public String getLine1AlphaTag(String callingPackage, String callingFeatureId) { Loading Loading @@ -251,6 +301,10 @@ public class PhoneSubInfoController extends IPhoneSubInfo.Stub { String callingFeatureId) { return callPhoneMethodForSubIdWithReadCheck(subId, callingPackage, callingFeatureId, "getVoiceMailNumber", (phone)-> { enforceTelephonyFeatureWithException(callingPackage, PackageManager.FEATURE_TELEPHONY_CALLING, "getVoiceMailNumberForSubscriber"); String number = PhoneNumberUtils.extractNetworkPortion( phone.getVoiceMailNumber()); if (VDBG) log("VM: getVoiceMailNUmber: " + number); Loading @@ -266,7 +320,13 @@ public class PhoneSubInfoController extends IPhoneSubInfo.Stub { public String getVoiceMailAlphaTagForSubscriber(int subId, String callingPackage, String callingFeatureId) { return callPhoneMethodForSubIdWithReadCheck(subId, callingPackage, callingFeatureId, "getVoiceMailAlphaTag", (phone)-> phone.getVoiceMailAlphaTag()); "getVoiceMailAlphaTag", (phone)-> { enforceTelephonyFeatureWithException(callingPackage, PackageManager.FEATURE_TELEPHONY_CALLING, "getVoiceMailAlphaTagForSubscriber"); return phone.getVoiceMailAlphaTag(); }); } /** Loading Loading @@ -381,6 +441,9 @@ public class PhoneSubInfoController extends IPhoneSubInfo.Stub { public String getIsimDomain(int subId) { return callPhoneMethodForSubIdWithPrivilegedCheck(subId, "getIsimDomain", (phone) -> { enforceTelephonyFeatureWithException(getCurrentPackageName(), PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION, "getIsimDomain"); IsimRecords isim = phone.getIsimRecords(); if (isim != null) { return isim.getIsimDomain(); Loading Loading @@ -422,6 +485,10 @@ public class PhoneSubInfoController extends IPhoneSubInfo.Stub { if (TelephonyPermissions. checkCallingOrSelfReadPrivilegedPhoneStatePermissionOrReadPhoneNumber( mContext, subId, callingPackage, callingFeatureId, "getImsPublicUserIdentities")) { enforceTelephonyFeatureWithException(callingPackage, PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION, "getImsPublicUserIdentities"); Phone phone = getPhone(subId); assert phone != null; IsimRecords isimRecords = phone.getIsimRecords(); Loading @@ -447,6 +514,9 @@ public class PhoneSubInfoController extends IPhoneSubInfo.Stub { public String getIsimIst(int subId) throws RemoteException { return callPhoneMethodForSubIdWithPrivilegedCheck(subId, "getIsimIst", (phone) -> { enforceTelephonyFeatureWithException(getCurrentPackageName(), PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION, "getIsimIst"); IsimRecords isim = phone.getIsimRecords(); if (isim != null) { return isim.getIsimIst(); Loading Loading @@ -478,6 +548,9 @@ public class PhoneSubInfoController extends IPhoneSubInfo.Stub { public String getSimServiceTable(int subId, int appType) throws RemoteException { return callPhoneMethodForSubIdWithPrivilegedCheck(subId, "getSimServiceTable", (phone) -> { enforceTelephonyFeatureWithException(getCurrentPackageName(), PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION, "getSimServiceTable"); UiccPort uiccPort = phone.getUiccPort(); if (uiccPort == null || uiccPort.getUiccProfile() == null) { loge("getSimServiceTable(): uiccPort or uiccProfile is null"); Loading @@ -498,6 +571,9 @@ public class PhoneSubInfoController extends IPhoneSubInfo.Stub { public String getIccSimChallengeResponse(int subId, int appType, int authType, String data, String callingPackage, String callingFeatureId) throws RemoteException { CallPhoneMethodHelper<String> toExecute = (phone)-> { enforceTelephonyFeatureWithException(callingPackage, PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION, "getIccSimChallengeResponse"); UiccPort uiccPort = phone.getUiccPort(); if (uiccPort == null) { loge("getIccSimChallengeResponse() uiccPort is null"); Loading Loading @@ -531,7 +607,13 @@ public class PhoneSubInfoController extends IPhoneSubInfo.Stub { public String getGroupIdLevel1ForSubscriber(int subId, String callingPackage, String callingFeatureId) { return callPhoneMethodForSubIdWithReadCheck(subId, callingPackage, callingFeatureId, "getGroupIdLevel1", (phone)-> phone.getGroupIdLevel1()); "getGroupIdLevel1", (phone)-> { enforceTelephonyFeatureWithException(callingPackage, PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION, "getGroupIdLevel1ForSubscriber"); return phone.getGroupIdLevel1(); }); } /** Below are utility methods that abstracts the flow that many public methods use: Loading Loading @@ -667,6 +749,9 @@ public class PhoneSubInfoController extends IPhoneSubInfo.Stub { public Uri getSmscIdentity(int subId, int appType) throws RemoteException { Uri smscIdentityUri = callPhoneMethodForSubIdWithPrivilegedCheck(subId, "getSmscIdentity", (phone) -> { enforceTelephonyFeatureWithException(getCurrentPackageName(), PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION, "getSmscIdentity"); try { String smscIdentity = null; UiccPort uiccPort = phone.getUiccPort(); Loading @@ -690,6 +775,40 @@ public class PhoneSubInfoController extends IPhoneSubInfo.Stub { return smscIdentityUri; } /** * Get the current calling package name. * @return the current calling package name */ @Nullable private String getCurrentPackageName() { if (mPackageManager == null) return null; String[] callingUids = mPackageManager.getPackagesForUid(Binder.getCallingUid()); return (callingUids == null) ? null : callingUids[0]; } /** * Make sure the device has required telephony feature * * @throws UnsupportedOperationException if the device does not have required telephony feature */ private void enforceTelephonyFeatureWithException(@Nullable String callingPackage, @NonNull String telephonyFeature, @NonNull String methodName) { if (callingPackage == null || mPackageManager == null) { return; } if (!mFeatureFlags.enforceTelephonyFeatureMappingForPublicApis() || !CompatChanges.isChangeEnabled(ENABLE_FEATURE_MAPPING, callingPackage, Binder.getCallingUserHandle())) { return; } if (!mPackageManager.hasSystemFeature(telephonyFeature)) { throw new UnsupportedOperationException( methodName + " is unsupported without " + telephonyFeature); } } private void log(String s) { Rlog.d(TAG, s); } Loading
tests/telephonytests/src/com/android/internal/telephony/PhoneSubInfoControllerTest.java +58 −17 Original line number Diff line number Diff line Loading @@ -23,8 +23,10 @@ import static android.telephony.TelephonyManager.APPTYPE_USIM; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertThrows; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import static org.mockito.ArgumentMatchers.anyString; import static org.mockito.ArgumentMatchers.nullable; import static org.mockito.Matchers.anyInt; import static org.mockito.Mockito.doReturn; Loading @@ -33,14 +35,15 @@ import static org.mockito.Mockito.mock; import android.app.AppOpsManager; import android.app.PropertyInvalidatedCache; import android.compat.testing.PlatformCompatChangeRule; import android.content.Context; import android.content.pm.PackageManager; import android.net.Uri; import android.os.Binder; import android.os.Build; import android.os.RemoteException; import androidx.test.filters.SmallTest; import android.telephony.TelephonyManager; import android.test.suitebuilder.annotation.SmallTest; import com.android.internal.telephony.uicc.IsimUiccRecords; import com.android.internal.telephony.uicc.SIMRecords; Loading @@ -48,10 +51,14 @@ import com.android.internal.telephony.uicc.UiccCardApplication; import com.android.internal.telephony.uicc.UiccPort; import com.android.internal.telephony.uicc.UiccProfile; import libcore.junit.util.compat.CoreCompatChangeRule.EnableCompatChanges; import org.junit.After; import org.junit.Assert; import org.junit.Before; import org.junit.Rule; import org.junit.Test; import org.junit.rules.TestRule; import org.mockito.Mockito; import java.util.List; Loading @@ -63,6 +70,9 @@ public class PhoneSubInfoControllerTest extends TelephonyTest { private static final String PSI_SMSC_TEL2 = "tel:+91987654321"; private static final String PSI_SMSC_SIP2 = "sip:+19876543210@dcf.pc.operetor2.com;user=phone"; @Rule public TestRule compatChangeRule = new PlatformCompatChangeRule(); private PhoneSubInfoController mPhoneSubInfoControllerUT; private AppOpsManager mAppOsMgr; private PackageManager mPm; Loading Loading @@ -92,7 +102,7 @@ public class PhoneSubInfoControllerTest extends TelephonyTest { mPm = mContext.getPackageManager(); replaceInstance(PhoneFactory.class, "sPhones", null, new Phone[]{mPhone, mSecondPhone}); mPhoneSubInfoControllerUT = new PhoneSubInfoController(mContext); mPhoneSubInfoControllerUT = new PhoneSubInfoController(mContext, mFeatureFlags); setupMocksForTelephonyPermissions(); // TelephonyPermissions will query the READ_DEVICE_IDENTIFIERS op from AppOpManager to Loading @@ -105,6 +115,12 @@ public class PhoneSubInfoControllerTest extends TelephonyTest { // Bypass calling package check. doReturn(Binder.getCallingUid()).when(mPm).getPackageUid(eq(TAG), anyInt()); // In order not to affect the existing implementation, define a telephony features // and disabled enforce_telephony_feature_mapping_for_public_apis feature flag doReturn(false).when(mFeatureFlags).enforceTelephonyFeatureMappingForPublicApis(); doReturn(true).when(mPm).hasSystemFeature(anyString()); doReturn(new String[] {TAG}).when(mPm).getPackagesForUid(anyInt()); } @After Loading Loading @@ -211,6 +227,31 @@ public class PhoneSubInfoControllerTest extends TelephonyTest { mPhoneSubInfoControllerUT.getNaiForSubscriber(1, TAG, FEATURE_ID)); } @Test @SmallTest @EnableCompatChanges({TelephonyManager.ENABLE_FEATURE_MAPPING}) public void testGetNai_EnabledEnforceTelephonyFeatureMappingForPublicApis() { // FeatureFlags enabled, System has required feature doReturn(true).when(mFeatureFlags).enforceTelephonyFeatureMappingForPublicApis(); doReturn(true).when(mPm).hasSystemFeature( eq(PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION)); doReturn("bbb@example.com").when(mSecondPhone).getNai(); // Enabled FeatureFlags and ENABLE_FEATURE_MAPPING, telephony features are defined try { assertEquals("bbb@example.com", mPhoneSubInfoControllerUT.getNaiForSubscriber(1, TAG, FEATURE_ID)); } catch (UnsupportedOperationException e) { fail("Not expect exception " + e.getMessage()); } // Telephony features is not defined, expect UnsupportedOperationException. doReturn(false).when(mPm).hasSystemFeature( eq(PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION)); assertThrows(UnsupportedOperationException.class, () -> mPhoneSubInfoControllerUT.getNaiForSubscriber(1, TAG, FEATURE_ID)); } @Test @SmallTest public void testGetNaiWithOutPermission() { Loading Loading @@ -1087,7 +1128,7 @@ public class PhoneSubInfoControllerTest extends TelephonyTest { doReturn(refSst).when(mSimRecords).getSimServiceTable(); String resultSst = mPhoneSubInfoControllerUT.getSimServiceTable(anyInt(), anyInt()); String resultSst = mPhoneSubInfoControllerUT.getSimServiceTable(0, 0); assertEquals(refSst, resultSst); } Loading @@ -1101,7 +1142,7 @@ public class PhoneSubInfoControllerTest extends TelephonyTest { doReturn(refSst).when(mSimRecords).getSimServiceTable(); String resultSst = mPhoneSubInfoControllerUT.getSimServiceTable(anyInt(), anyInt()); String resultSst = mPhoneSubInfoControllerUT.getSimServiceTable(0, 0); assertEquals(refSst, resultSst); } Loading @@ -1115,7 +1156,7 @@ public class PhoneSubInfoControllerTest extends TelephonyTest { doReturn(refSst).when(mSimRecords).getSimServiceTable(); String resultSst = mPhoneSubInfoControllerUT.getSimServiceTable(anyInt(), anyInt()); String resultSst = mPhoneSubInfoControllerUT.getSimServiceTable(0, 0); assertEquals(null, resultSst); } Loading @@ -1129,7 +1170,7 @@ public class PhoneSubInfoControllerTest extends TelephonyTest { doReturn(refSst).when(mSimRecords).getSimServiceTable(); String resultSst = mPhoneSubInfoControllerUT.getSimServiceTable(anyInt(), anyInt()); String resultSst = mPhoneSubInfoControllerUT.getSimServiceTable(0, 0); assertEquals(null, resultSst); } Loading @@ -1143,7 +1184,7 @@ public class PhoneSubInfoControllerTest extends TelephonyTest { doReturn(refSst).when(mSimRecords).getSimServiceTable(); String resultSst = mPhoneSubInfoControllerUT.getSimServiceTable(anyInt(), anyInt()); String resultSst = mPhoneSubInfoControllerUT.getSimServiceTable(0, 0); assertEquals(null, resultSst); } Loading @@ -1159,7 +1200,7 @@ public class PhoneSubInfoControllerTest extends TelephonyTest { mContextFixture.removeCallingOrSelfPermission(ContextFixture.PERMISSION_ENABLE_ALL); try { mPhoneSubInfoControllerUT.getSimServiceTable(anyInt(), anyInt()); mPhoneSubInfoControllerUT.getSimServiceTable(0, 0); Assert.fail("expected Security Exception Thrown"); } catch (Exception ex) { assertTrue(ex instanceof SecurityException); Loading @@ -1167,7 +1208,7 @@ public class PhoneSubInfoControllerTest extends TelephonyTest { } mContextFixture.addCallingOrSelfPermission(READ_PRIVILEGED_PHONE_STATE); assertEquals(refSst, mPhoneSubInfoControllerUT.getSimServiceTable(anyInt(), anyInt())); assertEquals(refSst, mPhoneSubInfoControllerUT.getSimServiceTable(0, 0)); } @Test Loading