Loading src/java/com/android/internal/telephony/PhoneSubInfoController.java +214 −262 Original line number Diff line number Diff line Loading @@ -25,6 +25,7 @@ import static android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE; import android.app.AppOpsManager; import android.content.Context; import android.content.pm.PackageManager; import android.os.Binder; import android.os.RemoteException; import android.os.ServiceManager; import android.telephony.ImsiEncryptionInfo; Loading Loading @@ -60,80 +61,35 @@ public class PhoneSubInfoController extends IPhoneSubInfo.Stub { } public String getDeviceIdForPhone(int phoneId, String callingPackage) { if (!SubscriptionManager.isValidPhoneId(phoneId)) { phoneId = 0; } final Phone phone = mPhone[phoneId]; if (phone != null) { if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState( mContext, phone.getSubId(), callingPackage, "getDeviceId")) { return null; } return phone.getDeviceId(); } else { loge("getDeviceIdForPhone phone " + phoneId + " is null"); return null; } return callPhoneMethodForPhoneIdWithReadCheck(phoneId, callingPackage, "getDeviceId", (phone)-> phone.getDeviceId()); } public String getNaiForSubscriber(int subId, String callingPackage) { Phone phone = getPhone(subId); if (phone != null) { if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState( mContext, subId, callingPackage, "getNai")) { return null; } return phone.getNai(); } else { loge("getNai phone is null for Subscription:" + subId); return null; } return callPhoneMethodForSubIdWithReadCheck(subId, callingPackage, "getNai", (phone)-> phone.getNai()); } public String getImeiForSubscriber(int subId, String callingPackage) { Phone phone = getPhone(subId); if (phone != null) { if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState( mContext, subId, callingPackage, "getImei")) { return null; } return phone.getImei(); } else { loge("getDeviceId phone is null for Subscription:" + subId); return null; } return callPhoneMethodForSubIdWithReadCheck(subId, callingPackage, "getImei", (phone)-> phone.getImei()); } public ImsiEncryptionInfo getCarrierInfoForImsiEncryption(int subId, int keyType, String callingPackage) { Phone phone = getPhone(subId); if (phone != null) { if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState( mContext, subId, callingPackage, "getCarrierInfoForImsiEncryption")) { return null; } return phone.getCarrierInfoForImsiEncryption(keyType); } else { loge("getCarrierInfoForImsiEncryption phone is null for Subscription:" + subId); return null; } return callPhoneMethodForSubIdWithReadCheck(subId, callingPackage, "getCarrierInfoForImsiEncryption", (phone)-> phone.getCarrierInfoForImsiEncryption(keyType)); } public void setCarrierInfoForImsiEncryption(int subId, String callingPackage, ImsiEncryptionInfo imsiEncryptionInfo) { Phone phone = getPhone(subId); if (phone != null) { if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState( mContext, subId, callingPackage, "setCarrierInfoForImsiEncryption")) { return; } enforceModifyPermission(); callPhoneMethodForSubIdWithModifyCheck(subId, callingPackage, "setCarrierInfoForImsiEncryption", (phone)-> { phone.setCarrierInfoForImsiEncryption(imsiEncryptionInfo); } else { loge("setCarrierInfoForImsiEncryption phone is null for Subscription:" + subId); return; } return null; }); } /** Loading @@ -144,15 +100,12 @@ public class PhoneSubInfoController extends IPhoneSubInfo.Stub { * @param callingPackage */ public void resetCarrierKeysForImsiEncryption(int subId, String callingPackage) { Phone phone = getPhone(subId); if (phone != null) { enforceModifyPermission(); callPhoneMethodForSubIdWithModifyCheck(subId, callingPackage, "setCarrierInfoForImsiEncryption", (phone)-> { phone.resetCarrierKeysForImsiEncryption(); return; } else { loge("resetCarrierKeysForImsiEncryption phone is null for Subscription:" + subId); return; } return null; }); } Loading @@ -161,17 +114,8 @@ public class PhoneSubInfoController extends IPhoneSubInfo.Stub { } public String getDeviceSvnUsingSubId(int subId, String callingPackage) { Phone phone = getPhone(subId); if (phone != null) { if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState( mContext, subId, callingPackage, "getDeviceSvn")) { return null; } return phone.getDeviceSvn(); } else { loge("getDeviceSvn phone is null"); return null; } return callPhoneMethodForSubIdWithReadCheck(subId, callingPackage, "getDeviceSvn", (phone)-> phone.getDeviceSvn()); } public String getSubscriberId(String callingPackage) { Loading @@ -179,17 +123,8 @@ public class PhoneSubInfoController extends IPhoneSubInfo.Stub { } public String getSubscriberIdForSubscriber(int subId, String callingPackage) { Phone phone = getPhone(subId); if (phone != null) { if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState( mContext, subId, callingPackage, "getSubscriberId")) { return null; } return phone.getSubscriberId(); } else { loge("getSubscriberId phone is null for Subscription:" + subId); return null; } return callPhoneMethodForSubIdWithReadCheck(subId, callingPackage, "getSubscriberId", (phone)-> phone.getSubscriberId()); } /** Loading @@ -200,17 +135,8 @@ public class PhoneSubInfoController extends IPhoneSubInfo.Stub { } public String getIccSerialNumberForSubscriber(int subId, String callingPackage) { Phone phone = getPhone(subId); if (phone != null) { if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState( mContext, subId, callingPackage, "getIccSerialNumber")) { return null; } return phone.getIccSerialNumber(); } else { loge("getIccSerialNumber phone is null for Subscription:" + subId); return null; } return callPhoneMethodForSubIdWithReadCheck(subId, callingPackage, "getIccSerialNumber", (phone)-> phone.getIccSerialNumber()); } public String getLine1Number(String callingPackage) { Loading @@ -218,18 +144,9 @@ public class PhoneSubInfoController extends IPhoneSubInfo.Stub { } public String getLine1NumberForSubscriber(int subId, String callingPackage) { Phone phone = getPhone(subId); if (phone != null) { // This is open to apps with WRITE_SMS. if (!TelephonyPermissions.checkCallingOrSelfReadPhoneNumber( mContext, subId, callingPackage, "getLine1Number")) { return null; } return phone.getLine1Number(); } else { loge("getLine1Number phone is null for Subscription:" + subId); return null; } return callPhoneMethodForSubIdWithReadPhoneNumberCheck( subId, callingPackage, "getLine1Number", (phone)-> phone.getLine1Number()); } public String getLine1AlphaTag(String callingPackage) { Loading @@ -237,17 +154,8 @@ public class PhoneSubInfoController extends IPhoneSubInfo.Stub { } public String getLine1AlphaTagForSubscriber(int subId, String callingPackage) { Phone phone = getPhone(subId); if (phone != null) { if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState( mContext, subId, callingPackage, "getLine1AlphaTag")) { return null; } return phone.getLine1AlphaTag(); } else { loge("getLine1AlphaTag phone is null for Subscription:" + subId); return null; } return callPhoneMethodForSubIdWithReadCheck(subId, callingPackage, "getLine1AlphaTag", (phone)-> phone.getLine1AlphaTag()); } public String getMsisdn(String callingPackage) { Loading @@ -255,17 +163,8 @@ public class PhoneSubInfoController extends IPhoneSubInfo.Stub { } public String getMsisdnForSubscriber(int subId, String callingPackage) { Phone phone = getPhone(subId); if (phone != null) { if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState( mContext, subId, callingPackage, "getMsisdn")) { return null; } return phone.getMsisdn(); } else { loge("getMsisdn phone is null for Subscription:" + subId); return null; } return callPhoneMethodForSubIdWithReadCheck(subId, callingPackage, "getMsisdn", (phone)-> phone.getMsisdn()); } public String getVoiceMailNumber(String callingPackage) { Loading @@ -273,19 +172,13 @@ public class PhoneSubInfoController extends IPhoneSubInfo.Stub { } public String getVoiceMailNumberForSubscriber(int subId, String callingPackage) { Phone phone = getPhone(subId); if (phone != null) { if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState( mContext, subId, callingPackage, "getVoiceMailNumber")) { return null; } String number = PhoneNumberUtils.extractNetworkPortion(phone.getVoiceMailNumber()); return callPhoneMethodForSubIdWithReadCheck(subId, callingPackage, "getVoiceMailNumber", (phone)-> { String number = PhoneNumberUtils.extractNetworkPortion( phone.getVoiceMailNumber()); if (VDBG) log("VM: getVoiceMailNUmber: " + number); return number; } else { loge("getVoiceMailNumber phone is null for Subscription:" + subId); return null; } }); } // TODO: change getCompleteVoiceMailNumber() to require READ_PRIVILEGED_PHONE_STATE Loading @@ -311,17 +204,8 @@ public class PhoneSubInfoController extends IPhoneSubInfo.Stub { } public String getVoiceMailAlphaTagForSubscriber(int subId, String callingPackage) { Phone phone = getPhone(subId); if (phone != null) { if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState( mContext, subId, callingPackage, "getVoiceMailAlphaTag")) { return null; } return phone.getVoiceMailAlphaTag(); } else { loge("getVoiceMailAlphaTag phone is null for Subscription:" + subId); return null; } return callPhoneMethodForSubIdWithReadCheck(subId, callingPackage, "getVoiceMailAlphaTag", (phone)-> phone.getVoiceMailAlphaTag()); } /** Loading @@ -341,6 +225,9 @@ public class PhoneSubInfoController extends IPhoneSubInfo.Stub { * @throws SecurityException if the caller does not have the required permission/privilege */ private void enforcePrivilegedPermissionOrCarrierPrivilege(int subId, String message) { // TODO(b/73660190): Migrate to // TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivileges and delete // this helper method. int permissionResult = mContext.checkCallingOrSelfPermission( READ_PRIVILEGED_PHONE_STATE); if (permissionResult == PackageManager.PERMISSION_GRANTED) { Loading @@ -362,114 +249,84 @@ public class PhoneSubInfoController extends IPhoneSubInfo.Stub { return PhoneFactory.getDefaultSubscription(); } /** * get the Isim Impi based on subId */ public String getIsimImpi(int subId) { Phone phone = getPhone(subId); if (phone != null) { mContext.enforceCallingOrSelfPermission(READ_PRIVILEGED_PHONE_STATE, "Requires READ_PRIVILEGED_PHONE_STATE"); return callPhoneMethodForSubIdWithPrivilegedCheck(subId, "getIsimImpi", (phone) -> { IsimRecords isim = phone.getIsimRecords(); if (isim != null) { return isim.getIsimImpi(); } else { return null; } } else { loge("getIsimImpi phone is null for Subscription:" + subId); return null; } }); } /** * get the Isim Domain based on subId */ public String getIsimDomain(int subId) { Phone phone = getPhone(subId); if (phone != null) { mContext.enforceCallingOrSelfPermission(READ_PRIVILEGED_PHONE_STATE, "Requires READ_PRIVILEGED_PHONE_STATE"); return callPhoneMethodForSubIdWithPrivilegedCheck(subId, "getIsimDomain", (phone) -> { IsimRecords isim = phone.getIsimRecords(); if (isim != null) { return isim.getIsimDomain(); } else { return null; } } else { loge("getIsimDomain phone is null for Subscription:" + subId); return null; } }); } /** * get the Isim Impu based on subId */ public String[] getIsimImpu(int subId) { Phone phone = getPhone(subId); if (phone != null) { mContext.enforceCallingOrSelfPermission(READ_PRIVILEGED_PHONE_STATE, "Requires READ_PRIVILEGED_PHONE_STATE"); return callPhoneMethodForSubIdWithPrivilegedCheck(subId, "getIsimImpu", (phone) -> { IsimRecords isim = phone.getIsimRecords(); if (isim != null) { return isim.getIsimImpu(); } else { return null; } } else { loge("getIsimImpu phone is null for Subscription:" + subId); return null; } }); } /** * get the Isim Ist based on subId */ public String getIsimIst(int subId) throws RemoteException { Phone phone = getPhone(subId); if (phone != null) { mContext.enforceCallingOrSelfPermission(READ_PRIVILEGED_PHONE_STATE, "Requires READ_PRIVILEGED_PHONE_STATE"); return callPhoneMethodForSubIdWithPrivilegedCheck(subId, "getIsimIst", (phone) -> { IsimRecords isim = phone.getIsimRecords(); if (isim != null) { return isim.getIsimIst(); } else { return null; } } else { loge("getIsimIst phone is null for Subscription:" + subId); return null; } }); } /** * get the Isim Pcscf based on subId */ public String[] getIsimPcscf(int subId) throws RemoteException { Phone phone = getPhone(subId); if (phone != null) { mContext.enforceCallingOrSelfPermission(READ_PRIVILEGED_PHONE_STATE, "Requires READ_PRIVILEGED_PHONE_STATE"); return callPhoneMethodForSubIdWithPrivilegedCheck(subId, "getIsimPcscf", (phone) -> { IsimRecords isim = phone.getIsimRecords(); if (isim != null) { return isim.getIsimPcscf(); } else { return null; } } else { loge("getIsimPcscf phone is null for Subscription:" + subId); return null; } }); } public String getIccSimChallengeResponse(int subId, int appType, int authType, String data) throws RemoteException { // TODO(b/73660190): Migrate to // TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivileges and delete // this helper method. enforcePrivilegedPermissionOrCarrierPrivilege(subId, "getIccSimChallengeResponse"); Phone phone = getPhone(subId); CallPhoneMethodHelper<String> toExecute = (phone)-> { UiccCard uiccCard = phone.getUiccCard(); if (uiccCard == null) { loge("getIccSimChallengeResponse() UiccCard is null"); Loading @@ -478,35 +335,130 @@ public class PhoneSubInfoController extends IPhoneSubInfo.Stub { UiccCardApplication uiccApp = uiccCard.getApplicationByType(appType); if (uiccApp == null) { loge("getIccSimChallengeResponse() no app with specified type -- " + appType); loge("getIccSimChallengeResponse() no app with specified type -- " + appType); return null; } else { loge("getIccSimChallengeResponse() found app " + uiccApp.getAid() + " specified type -- " + appType); } if(authType != UiccCardApplication.AUTH_CONTEXT_EAP_SIM && authType != UiccCardApplication.AUTH_CONTEXT_EAP_AKA) { if (authType != UiccCardApplication.AUTH_CONTEXT_EAP_SIM && authType != UiccCardApplication.AUTH_CONTEXT_EAP_AKA) { loge("getIccSimChallengeResponse() unsupported authType: " + authType); return null; } return uiccApp.getIccRecords().getIccSimChallengeResponse(authType, data); }; return callPhoneMethodWithPermissionCheck( subId, null, "getIccSimChallengeResponse", toExecute, (aContext, aSubId, aCallingPackage, aMessage)-> { enforcePrivilegedPermissionOrCarrierPrivilege(aSubId, aMessage); return true; }); } public String getGroupIdLevel1ForSubscriber(int subId, String callingPackage) { return callPhoneMethodForSubIdWithReadCheck(subId, callingPackage, "getGroupIdLevel1", (phone)-> phone.getGroupIdLevel1()); } /** Below are utility methods that abstracts the flow that many public methods use: * 1. Check permission: pass, throw exception, or fails (returns false). * 2. clearCallingIdentity. * 3. Call a specified phone method and get return value. * 4. restoreCallingIdentity and return. */ private interface CallPhoneMethodHelper<T> { T callMethod(Phone phone); } private interface PermissionCheckHelper { // Implemented to do whatever permission check it wants. // If passes, it should return true. // If permission is not granted, throws SecurityException. // If permission is revoked by AppOps, return false. boolean checkPermission(Context context, int subId, String callingPackage, String message); } // Base utility method that others use. private <T> T callPhoneMethodWithPermissionCheck(int subId, String callingPackage, String message, CallPhoneMethodHelper<T> callMethodHelper, PermissionCheckHelper permissionCheckHelper) { if (!permissionCheckHelper.checkPermission(mContext, subId, callingPackage, message)) { return null; } final long identity = Binder.clearCallingIdentity(); try { Phone phone = getPhone(subId); if (phone != null) { if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState( mContext, subId, callingPackage, "getGroupIdLevel1")) { return callMethodHelper.callMethod(phone); } else { loge(message + " phone is null for Subscription:" + subId); return null; } return phone.getGroupIdLevel1(); } else { loge("getGroupIdLevel1 phone is null for Subscription:" + subId); } finally { Binder.restoreCallingIdentity(identity); } } private <T> T callPhoneMethodForSubIdWithReadCheck(int subId, String callingPackage, String message, CallPhoneMethodHelper<T> callMethodHelper) { return callPhoneMethodWithPermissionCheck(subId, callingPackage, message, callMethodHelper, (aContext, aSubId, aCallingPackage, aMessage)-> TelephonyPermissions.checkCallingOrSelfReadPhoneState( aContext, aSubId, aCallingPackage, aMessage)); } private <T> T callPhoneMethodForSubIdWithPrivilegedCheck( int subId, String message, CallPhoneMethodHelper<T> callMethodHelper) { return callPhoneMethodWithPermissionCheck(subId, null, message, callMethodHelper, (aContext, aSubId, aCallingPackage, aMessage)-> { mContext.enforceCallingOrSelfPermission(READ_PRIVILEGED_PHONE_STATE, message); return true; }); } private <T> T callPhoneMethodForSubIdWithModifyCheck(int subId, String callingPackage, String message, CallPhoneMethodHelper<T> callMethodHelper) { return callPhoneMethodWithPermissionCheck(subId, null, message, callMethodHelper, (aContext, aSubId, aCallingPackage, aMessage)-> { enforceModifyPermission(); return true; }); } private <T> T callPhoneMethodForSubIdWithReadPhoneNumberCheck(int subId, String callingPackage, String message, CallPhoneMethodHelper<T> callMethodHelper) { return callPhoneMethodWithPermissionCheck(subId, callingPackage, message, callMethodHelper, (aContext, aSubId, aCallingPackage, aMessage)-> TelephonyPermissions.checkCallingOrSelfReadPhoneNumber( aContext, aSubId, aCallingPackage, aMessage)); } private <T> T callPhoneMethodForPhoneIdWithReadCheck(int phoneId, String callingPackage, String message, CallPhoneMethodHelper<T> callMethodHelper) { // Getting subId before doing permission check. if (!SubscriptionManager.isValidPhoneId(phoneId)) { phoneId = 0; } final Phone phone = mPhone[phoneId]; if (phone == null) { return null; } if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState( mContext, phone.getSubId(), callingPackage, message)) { return null; } final long identity = Binder.clearCallingIdentity(); try { return callMethodHelper.callMethod(phone); } finally { Binder.restoreCallingIdentity(identity); } } private void log(String s) { Loading Loading
src/java/com/android/internal/telephony/PhoneSubInfoController.java +214 −262 Original line number Diff line number Diff line Loading @@ -25,6 +25,7 @@ import static android.Manifest.permission.READ_PRIVILEGED_PHONE_STATE; import android.app.AppOpsManager; import android.content.Context; import android.content.pm.PackageManager; import android.os.Binder; import android.os.RemoteException; import android.os.ServiceManager; import android.telephony.ImsiEncryptionInfo; Loading Loading @@ -60,80 +61,35 @@ public class PhoneSubInfoController extends IPhoneSubInfo.Stub { } public String getDeviceIdForPhone(int phoneId, String callingPackage) { if (!SubscriptionManager.isValidPhoneId(phoneId)) { phoneId = 0; } final Phone phone = mPhone[phoneId]; if (phone != null) { if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState( mContext, phone.getSubId(), callingPackage, "getDeviceId")) { return null; } return phone.getDeviceId(); } else { loge("getDeviceIdForPhone phone " + phoneId + " is null"); return null; } return callPhoneMethodForPhoneIdWithReadCheck(phoneId, callingPackage, "getDeviceId", (phone)-> phone.getDeviceId()); } public String getNaiForSubscriber(int subId, String callingPackage) { Phone phone = getPhone(subId); if (phone != null) { if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState( mContext, subId, callingPackage, "getNai")) { return null; } return phone.getNai(); } else { loge("getNai phone is null for Subscription:" + subId); return null; } return callPhoneMethodForSubIdWithReadCheck(subId, callingPackage, "getNai", (phone)-> phone.getNai()); } public String getImeiForSubscriber(int subId, String callingPackage) { Phone phone = getPhone(subId); if (phone != null) { if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState( mContext, subId, callingPackage, "getImei")) { return null; } return phone.getImei(); } else { loge("getDeviceId phone is null for Subscription:" + subId); return null; } return callPhoneMethodForSubIdWithReadCheck(subId, callingPackage, "getImei", (phone)-> phone.getImei()); } public ImsiEncryptionInfo getCarrierInfoForImsiEncryption(int subId, int keyType, String callingPackage) { Phone phone = getPhone(subId); if (phone != null) { if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState( mContext, subId, callingPackage, "getCarrierInfoForImsiEncryption")) { return null; } return phone.getCarrierInfoForImsiEncryption(keyType); } else { loge("getCarrierInfoForImsiEncryption phone is null for Subscription:" + subId); return null; } return callPhoneMethodForSubIdWithReadCheck(subId, callingPackage, "getCarrierInfoForImsiEncryption", (phone)-> phone.getCarrierInfoForImsiEncryption(keyType)); } public void setCarrierInfoForImsiEncryption(int subId, String callingPackage, ImsiEncryptionInfo imsiEncryptionInfo) { Phone phone = getPhone(subId); if (phone != null) { if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState( mContext, subId, callingPackage, "setCarrierInfoForImsiEncryption")) { return; } enforceModifyPermission(); callPhoneMethodForSubIdWithModifyCheck(subId, callingPackage, "setCarrierInfoForImsiEncryption", (phone)-> { phone.setCarrierInfoForImsiEncryption(imsiEncryptionInfo); } else { loge("setCarrierInfoForImsiEncryption phone is null for Subscription:" + subId); return; } return null; }); } /** Loading @@ -144,15 +100,12 @@ public class PhoneSubInfoController extends IPhoneSubInfo.Stub { * @param callingPackage */ public void resetCarrierKeysForImsiEncryption(int subId, String callingPackage) { Phone phone = getPhone(subId); if (phone != null) { enforceModifyPermission(); callPhoneMethodForSubIdWithModifyCheck(subId, callingPackage, "setCarrierInfoForImsiEncryption", (phone)-> { phone.resetCarrierKeysForImsiEncryption(); return; } else { loge("resetCarrierKeysForImsiEncryption phone is null for Subscription:" + subId); return; } return null; }); } Loading @@ -161,17 +114,8 @@ public class PhoneSubInfoController extends IPhoneSubInfo.Stub { } public String getDeviceSvnUsingSubId(int subId, String callingPackage) { Phone phone = getPhone(subId); if (phone != null) { if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState( mContext, subId, callingPackage, "getDeviceSvn")) { return null; } return phone.getDeviceSvn(); } else { loge("getDeviceSvn phone is null"); return null; } return callPhoneMethodForSubIdWithReadCheck(subId, callingPackage, "getDeviceSvn", (phone)-> phone.getDeviceSvn()); } public String getSubscriberId(String callingPackage) { Loading @@ -179,17 +123,8 @@ public class PhoneSubInfoController extends IPhoneSubInfo.Stub { } public String getSubscriberIdForSubscriber(int subId, String callingPackage) { Phone phone = getPhone(subId); if (phone != null) { if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState( mContext, subId, callingPackage, "getSubscriberId")) { return null; } return phone.getSubscriberId(); } else { loge("getSubscriberId phone is null for Subscription:" + subId); return null; } return callPhoneMethodForSubIdWithReadCheck(subId, callingPackage, "getSubscriberId", (phone)-> phone.getSubscriberId()); } /** Loading @@ -200,17 +135,8 @@ public class PhoneSubInfoController extends IPhoneSubInfo.Stub { } public String getIccSerialNumberForSubscriber(int subId, String callingPackage) { Phone phone = getPhone(subId); if (phone != null) { if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState( mContext, subId, callingPackage, "getIccSerialNumber")) { return null; } return phone.getIccSerialNumber(); } else { loge("getIccSerialNumber phone is null for Subscription:" + subId); return null; } return callPhoneMethodForSubIdWithReadCheck(subId, callingPackage, "getIccSerialNumber", (phone)-> phone.getIccSerialNumber()); } public String getLine1Number(String callingPackage) { Loading @@ -218,18 +144,9 @@ public class PhoneSubInfoController extends IPhoneSubInfo.Stub { } public String getLine1NumberForSubscriber(int subId, String callingPackage) { Phone phone = getPhone(subId); if (phone != null) { // This is open to apps with WRITE_SMS. if (!TelephonyPermissions.checkCallingOrSelfReadPhoneNumber( mContext, subId, callingPackage, "getLine1Number")) { return null; } return phone.getLine1Number(); } else { loge("getLine1Number phone is null for Subscription:" + subId); return null; } return callPhoneMethodForSubIdWithReadPhoneNumberCheck( subId, callingPackage, "getLine1Number", (phone)-> phone.getLine1Number()); } public String getLine1AlphaTag(String callingPackage) { Loading @@ -237,17 +154,8 @@ public class PhoneSubInfoController extends IPhoneSubInfo.Stub { } public String getLine1AlphaTagForSubscriber(int subId, String callingPackage) { Phone phone = getPhone(subId); if (phone != null) { if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState( mContext, subId, callingPackage, "getLine1AlphaTag")) { return null; } return phone.getLine1AlphaTag(); } else { loge("getLine1AlphaTag phone is null for Subscription:" + subId); return null; } return callPhoneMethodForSubIdWithReadCheck(subId, callingPackage, "getLine1AlphaTag", (phone)-> phone.getLine1AlphaTag()); } public String getMsisdn(String callingPackage) { Loading @@ -255,17 +163,8 @@ public class PhoneSubInfoController extends IPhoneSubInfo.Stub { } public String getMsisdnForSubscriber(int subId, String callingPackage) { Phone phone = getPhone(subId); if (phone != null) { if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState( mContext, subId, callingPackage, "getMsisdn")) { return null; } return phone.getMsisdn(); } else { loge("getMsisdn phone is null for Subscription:" + subId); return null; } return callPhoneMethodForSubIdWithReadCheck(subId, callingPackage, "getMsisdn", (phone)-> phone.getMsisdn()); } public String getVoiceMailNumber(String callingPackage) { Loading @@ -273,19 +172,13 @@ public class PhoneSubInfoController extends IPhoneSubInfo.Stub { } public String getVoiceMailNumberForSubscriber(int subId, String callingPackage) { Phone phone = getPhone(subId); if (phone != null) { if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState( mContext, subId, callingPackage, "getVoiceMailNumber")) { return null; } String number = PhoneNumberUtils.extractNetworkPortion(phone.getVoiceMailNumber()); return callPhoneMethodForSubIdWithReadCheck(subId, callingPackage, "getVoiceMailNumber", (phone)-> { String number = PhoneNumberUtils.extractNetworkPortion( phone.getVoiceMailNumber()); if (VDBG) log("VM: getVoiceMailNUmber: " + number); return number; } else { loge("getVoiceMailNumber phone is null for Subscription:" + subId); return null; } }); } // TODO: change getCompleteVoiceMailNumber() to require READ_PRIVILEGED_PHONE_STATE Loading @@ -311,17 +204,8 @@ public class PhoneSubInfoController extends IPhoneSubInfo.Stub { } public String getVoiceMailAlphaTagForSubscriber(int subId, String callingPackage) { Phone phone = getPhone(subId); if (phone != null) { if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState( mContext, subId, callingPackage, "getVoiceMailAlphaTag")) { return null; } return phone.getVoiceMailAlphaTag(); } else { loge("getVoiceMailAlphaTag phone is null for Subscription:" + subId); return null; } return callPhoneMethodForSubIdWithReadCheck(subId, callingPackage, "getVoiceMailAlphaTag", (phone)-> phone.getVoiceMailAlphaTag()); } /** Loading @@ -341,6 +225,9 @@ public class PhoneSubInfoController extends IPhoneSubInfo.Stub { * @throws SecurityException if the caller does not have the required permission/privilege */ private void enforcePrivilegedPermissionOrCarrierPrivilege(int subId, String message) { // TODO(b/73660190): Migrate to // TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivileges and delete // this helper method. int permissionResult = mContext.checkCallingOrSelfPermission( READ_PRIVILEGED_PHONE_STATE); if (permissionResult == PackageManager.PERMISSION_GRANTED) { Loading @@ -362,114 +249,84 @@ public class PhoneSubInfoController extends IPhoneSubInfo.Stub { return PhoneFactory.getDefaultSubscription(); } /** * get the Isim Impi based on subId */ public String getIsimImpi(int subId) { Phone phone = getPhone(subId); if (phone != null) { mContext.enforceCallingOrSelfPermission(READ_PRIVILEGED_PHONE_STATE, "Requires READ_PRIVILEGED_PHONE_STATE"); return callPhoneMethodForSubIdWithPrivilegedCheck(subId, "getIsimImpi", (phone) -> { IsimRecords isim = phone.getIsimRecords(); if (isim != null) { return isim.getIsimImpi(); } else { return null; } } else { loge("getIsimImpi phone is null for Subscription:" + subId); return null; } }); } /** * get the Isim Domain based on subId */ public String getIsimDomain(int subId) { Phone phone = getPhone(subId); if (phone != null) { mContext.enforceCallingOrSelfPermission(READ_PRIVILEGED_PHONE_STATE, "Requires READ_PRIVILEGED_PHONE_STATE"); return callPhoneMethodForSubIdWithPrivilegedCheck(subId, "getIsimDomain", (phone) -> { IsimRecords isim = phone.getIsimRecords(); if (isim != null) { return isim.getIsimDomain(); } else { return null; } } else { loge("getIsimDomain phone is null for Subscription:" + subId); return null; } }); } /** * get the Isim Impu based on subId */ public String[] getIsimImpu(int subId) { Phone phone = getPhone(subId); if (phone != null) { mContext.enforceCallingOrSelfPermission(READ_PRIVILEGED_PHONE_STATE, "Requires READ_PRIVILEGED_PHONE_STATE"); return callPhoneMethodForSubIdWithPrivilegedCheck(subId, "getIsimImpu", (phone) -> { IsimRecords isim = phone.getIsimRecords(); if (isim != null) { return isim.getIsimImpu(); } else { return null; } } else { loge("getIsimImpu phone is null for Subscription:" + subId); return null; } }); } /** * get the Isim Ist based on subId */ public String getIsimIst(int subId) throws RemoteException { Phone phone = getPhone(subId); if (phone != null) { mContext.enforceCallingOrSelfPermission(READ_PRIVILEGED_PHONE_STATE, "Requires READ_PRIVILEGED_PHONE_STATE"); return callPhoneMethodForSubIdWithPrivilegedCheck(subId, "getIsimIst", (phone) -> { IsimRecords isim = phone.getIsimRecords(); if (isim != null) { return isim.getIsimIst(); } else { return null; } } else { loge("getIsimIst phone is null for Subscription:" + subId); return null; } }); } /** * get the Isim Pcscf based on subId */ public String[] getIsimPcscf(int subId) throws RemoteException { Phone phone = getPhone(subId); if (phone != null) { mContext.enforceCallingOrSelfPermission(READ_PRIVILEGED_PHONE_STATE, "Requires READ_PRIVILEGED_PHONE_STATE"); return callPhoneMethodForSubIdWithPrivilegedCheck(subId, "getIsimPcscf", (phone) -> { IsimRecords isim = phone.getIsimRecords(); if (isim != null) { return isim.getIsimPcscf(); } else { return null; } } else { loge("getIsimPcscf phone is null for Subscription:" + subId); return null; } }); } public String getIccSimChallengeResponse(int subId, int appType, int authType, String data) throws RemoteException { // TODO(b/73660190): Migrate to // TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivileges and delete // this helper method. enforcePrivilegedPermissionOrCarrierPrivilege(subId, "getIccSimChallengeResponse"); Phone phone = getPhone(subId); CallPhoneMethodHelper<String> toExecute = (phone)-> { UiccCard uiccCard = phone.getUiccCard(); if (uiccCard == null) { loge("getIccSimChallengeResponse() UiccCard is null"); Loading @@ -478,35 +335,130 @@ public class PhoneSubInfoController extends IPhoneSubInfo.Stub { UiccCardApplication uiccApp = uiccCard.getApplicationByType(appType); if (uiccApp == null) { loge("getIccSimChallengeResponse() no app with specified type -- " + appType); loge("getIccSimChallengeResponse() no app with specified type -- " + appType); return null; } else { loge("getIccSimChallengeResponse() found app " + uiccApp.getAid() + " specified type -- " + appType); } if(authType != UiccCardApplication.AUTH_CONTEXT_EAP_SIM && authType != UiccCardApplication.AUTH_CONTEXT_EAP_AKA) { if (authType != UiccCardApplication.AUTH_CONTEXT_EAP_SIM && authType != UiccCardApplication.AUTH_CONTEXT_EAP_AKA) { loge("getIccSimChallengeResponse() unsupported authType: " + authType); return null; } return uiccApp.getIccRecords().getIccSimChallengeResponse(authType, data); }; return callPhoneMethodWithPermissionCheck( subId, null, "getIccSimChallengeResponse", toExecute, (aContext, aSubId, aCallingPackage, aMessage)-> { enforcePrivilegedPermissionOrCarrierPrivilege(aSubId, aMessage); return true; }); } public String getGroupIdLevel1ForSubscriber(int subId, String callingPackage) { return callPhoneMethodForSubIdWithReadCheck(subId, callingPackage, "getGroupIdLevel1", (phone)-> phone.getGroupIdLevel1()); } /** Below are utility methods that abstracts the flow that many public methods use: * 1. Check permission: pass, throw exception, or fails (returns false). * 2. clearCallingIdentity. * 3. Call a specified phone method and get return value. * 4. restoreCallingIdentity and return. */ private interface CallPhoneMethodHelper<T> { T callMethod(Phone phone); } private interface PermissionCheckHelper { // Implemented to do whatever permission check it wants. // If passes, it should return true. // If permission is not granted, throws SecurityException. // If permission is revoked by AppOps, return false. boolean checkPermission(Context context, int subId, String callingPackage, String message); } // Base utility method that others use. private <T> T callPhoneMethodWithPermissionCheck(int subId, String callingPackage, String message, CallPhoneMethodHelper<T> callMethodHelper, PermissionCheckHelper permissionCheckHelper) { if (!permissionCheckHelper.checkPermission(mContext, subId, callingPackage, message)) { return null; } final long identity = Binder.clearCallingIdentity(); try { Phone phone = getPhone(subId); if (phone != null) { if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState( mContext, subId, callingPackage, "getGroupIdLevel1")) { return callMethodHelper.callMethod(phone); } else { loge(message + " phone is null for Subscription:" + subId); return null; } return phone.getGroupIdLevel1(); } else { loge("getGroupIdLevel1 phone is null for Subscription:" + subId); } finally { Binder.restoreCallingIdentity(identity); } } private <T> T callPhoneMethodForSubIdWithReadCheck(int subId, String callingPackage, String message, CallPhoneMethodHelper<T> callMethodHelper) { return callPhoneMethodWithPermissionCheck(subId, callingPackage, message, callMethodHelper, (aContext, aSubId, aCallingPackage, aMessage)-> TelephonyPermissions.checkCallingOrSelfReadPhoneState( aContext, aSubId, aCallingPackage, aMessage)); } private <T> T callPhoneMethodForSubIdWithPrivilegedCheck( int subId, String message, CallPhoneMethodHelper<T> callMethodHelper) { return callPhoneMethodWithPermissionCheck(subId, null, message, callMethodHelper, (aContext, aSubId, aCallingPackage, aMessage)-> { mContext.enforceCallingOrSelfPermission(READ_PRIVILEGED_PHONE_STATE, message); return true; }); } private <T> T callPhoneMethodForSubIdWithModifyCheck(int subId, String callingPackage, String message, CallPhoneMethodHelper<T> callMethodHelper) { return callPhoneMethodWithPermissionCheck(subId, null, message, callMethodHelper, (aContext, aSubId, aCallingPackage, aMessage)-> { enforceModifyPermission(); return true; }); } private <T> T callPhoneMethodForSubIdWithReadPhoneNumberCheck(int subId, String callingPackage, String message, CallPhoneMethodHelper<T> callMethodHelper) { return callPhoneMethodWithPermissionCheck(subId, callingPackage, message, callMethodHelper, (aContext, aSubId, aCallingPackage, aMessage)-> TelephonyPermissions.checkCallingOrSelfReadPhoneNumber( aContext, aSubId, aCallingPackage, aMessage)); } private <T> T callPhoneMethodForPhoneIdWithReadCheck(int phoneId, String callingPackage, String message, CallPhoneMethodHelper<T> callMethodHelper) { // Getting subId before doing permission check. if (!SubscriptionManager.isValidPhoneId(phoneId)) { phoneId = 0; } final Phone phone = mPhone[phoneId]; if (phone == null) { return null; } if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState( mContext, phone.getSubId(), callingPackage, message)) { return null; } final long identity = Binder.clearCallingIdentity(); try { return callMethodHelper.callMethod(phone); } finally { Binder.restoreCallingIdentity(identity); } } private void log(String s) { Loading