Loading src/java/com/android/internal/telephony/PhoneSubInfoController.java +214 −262 Original line number Original line 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.app.AppOpsManager; import android.content.Context; import android.content.Context; import android.content.pm.PackageManager; import android.content.pm.PackageManager; import android.os.Binder; import android.os.RemoteException; import android.os.RemoteException; import android.os.ServiceManager; import android.os.ServiceManager; import android.telephony.ImsiEncryptionInfo; import android.telephony.ImsiEncryptionInfo; Loading Loading @@ -60,80 +61,35 @@ public class PhoneSubInfoController extends IPhoneSubInfo.Stub { } } public String getDeviceIdForPhone(int phoneId, String callingPackage) { public String getDeviceIdForPhone(int phoneId, String callingPackage) { if (!SubscriptionManager.isValidPhoneId(phoneId)) { return callPhoneMethodForPhoneIdWithReadCheck(phoneId, callingPackage, phoneId = 0; "getDeviceId", (phone)-> phone.getDeviceId()); } 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; } } } public String getNaiForSubscriber(int subId, String callingPackage) { public String getNaiForSubscriber(int subId, String callingPackage) { Phone phone = getPhone(subId); return callPhoneMethodForSubIdWithReadCheck(subId, callingPackage, "getNai", if (phone != null) { (phone)-> phone.getNai()); if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState( mContext, subId, callingPackage, "getNai")) { return null; } return phone.getNai(); } else { loge("getNai phone is null for Subscription:" + subId); return null; } } } public String getImeiForSubscriber(int subId, String callingPackage) { public String getImeiForSubscriber(int subId, String callingPackage) { Phone phone = getPhone(subId); return callPhoneMethodForSubIdWithReadCheck(subId, callingPackage, "getImei", if (phone != null) { (phone)-> phone.getImei()); if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState( mContext, subId, callingPackage, "getImei")) { return null; } return phone.getImei(); } else { loge("getDeviceId phone is null for Subscription:" + subId); return null; } } } public ImsiEncryptionInfo getCarrierInfoForImsiEncryption(int subId, int keyType, public ImsiEncryptionInfo getCarrierInfoForImsiEncryption(int subId, int keyType, String callingPackage) { String callingPackage) { Phone phone = getPhone(subId); return callPhoneMethodForSubIdWithReadCheck(subId, callingPackage, if (phone != null) { "getCarrierInfoForImsiEncryption", if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState( (phone)-> phone.getCarrierInfoForImsiEncryption(keyType)); mContext, subId, callingPackage, "getCarrierInfoForImsiEncryption")) { return null; } return phone.getCarrierInfoForImsiEncryption(keyType); } else { loge("getCarrierInfoForImsiEncryption phone is null for Subscription:" + subId); return null; } } } public void setCarrierInfoForImsiEncryption(int subId, String callingPackage, public void setCarrierInfoForImsiEncryption(int subId, String callingPackage, ImsiEncryptionInfo imsiEncryptionInfo) { ImsiEncryptionInfo imsiEncryptionInfo) { Phone phone = getPhone(subId); callPhoneMethodForSubIdWithModifyCheck(subId, callingPackage, if (phone != null) { "setCarrierInfoForImsiEncryption", if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState( (phone)-> { mContext, subId, callingPackage, "setCarrierInfoForImsiEncryption")) { return; } enforceModifyPermission(); phone.setCarrierInfoForImsiEncryption(imsiEncryptionInfo); phone.setCarrierInfoForImsiEncryption(imsiEncryptionInfo); } else { return null; loge("setCarrierInfoForImsiEncryption phone is null for Subscription:" + subId); }); return; } } } /** /** Loading @@ -144,15 +100,12 @@ public class PhoneSubInfoController extends IPhoneSubInfo.Stub { * @param callingPackage * @param callingPackage */ */ public void resetCarrierKeysForImsiEncryption(int subId, String callingPackage) { public void resetCarrierKeysForImsiEncryption(int subId, String callingPackage) { Phone phone = getPhone(subId); callPhoneMethodForSubIdWithModifyCheck(subId, callingPackage, if (phone != null) { "setCarrierInfoForImsiEncryption", enforceModifyPermission(); (phone)-> { phone.resetCarrierKeysForImsiEncryption(); phone.resetCarrierKeysForImsiEncryption(); return; return null; } else { }); loge("resetCarrierKeysForImsiEncryption phone is null for Subscription:" + subId); return; } } } Loading @@ -161,17 +114,8 @@ public class PhoneSubInfoController extends IPhoneSubInfo.Stub { } } public String getDeviceSvnUsingSubId(int subId, String callingPackage) { public String getDeviceSvnUsingSubId(int subId, String callingPackage) { Phone phone = getPhone(subId); return callPhoneMethodForSubIdWithReadCheck(subId, callingPackage, "getDeviceSvn", if (phone != null) { (phone)-> phone.getDeviceSvn()); if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState( mContext, subId, callingPackage, "getDeviceSvn")) { return null; } return phone.getDeviceSvn(); } else { loge("getDeviceSvn phone is null"); return null; } } } public String getSubscriberId(String callingPackage) { public String getSubscriberId(String callingPackage) { Loading @@ -179,17 +123,8 @@ public class PhoneSubInfoController extends IPhoneSubInfo.Stub { } } public String getSubscriberIdForSubscriber(int subId, String callingPackage) { public String getSubscriberIdForSubscriber(int subId, String callingPackage) { Phone phone = getPhone(subId); return callPhoneMethodForSubIdWithReadCheck(subId, callingPackage, "getSubscriberId", if (phone != null) { (phone)-> phone.getSubscriberId()); if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState( mContext, subId, callingPackage, "getSubscriberId")) { return null; } return phone.getSubscriberId(); } else { loge("getSubscriberId phone is null for Subscription:" + subId); return null; } } } /** /** Loading @@ -200,17 +135,8 @@ public class PhoneSubInfoController extends IPhoneSubInfo.Stub { } } public String getIccSerialNumberForSubscriber(int subId, String callingPackage) { public String getIccSerialNumberForSubscriber(int subId, String callingPackage) { Phone phone = getPhone(subId); return callPhoneMethodForSubIdWithReadCheck(subId, callingPackage, "getIccSerialNumber", if (phone != null) { (phone)-> phone.getIccSerialNumber()); if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState( mContext, subId, callingPackage, "getIccSerialNumber")) { return null; } return phone.getIccSerialNumber(); } else { loge("getIccSerialNumber phone is null for Subscription:" + subId); return null; } } } public String getLine1Number(String callingPackage) { public String getLine1Number(String callingPackage) { Loading @@ -218,18 +144,9 @@ public class PhoneSubInfoController extends IPhoneSubInfo.Stub { } } public String getLine1NumberForSubscriber(int subId, String callingPackage) { public String getLine1NumberForSubscriber(int subId, String callingPackage) { Phone phone = getPhone(subId); return callPhoneMethodForSubIdWithReadPhoneNumberCheck( if (phone != null) { subId, callingPackage, "getLine1Number", // This is open to apps with WRITE_SMS. (phone)-> phone.getLine1Number()); if (!TelephonyPermissions.checkCallingOrSelfReadPhoneNumber( mContext, subId, callingPackage, "getLine1Number")) { return null; } return phone.getLine1Number(); } else { loge("getLine1Number phone is null for Subscription:" + subId); return null; } } } public String getLine1AlphaTag(String callingPackage) { public String getLine1AlphaTag(String callingPackage) { Loading @@ -237,17 +154,8 @@ public class PhoneSubInfoController extends IPhoneSubInfo.Stub { } } public String getLine1AlphaTagForSubscriber(int subId, String callingPackage) { public String getLine1AlphaTagForSubscriber(int subId, String callingPackage) { Phone phone = getPhone(subId); return callPhoneMethodForSubIdWithReadCheck(subId, callingPackage, "getLine1AlphaTag", if (phone != null) { (phone)-> phone.getLine1AlphaTag()); if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState( mContext, subId, callingPackage, "getLine1AlphaTag")) { return null; } return phone.getLine1AlphaTag(); } else { loge("getLine1AlphaTag phone is null for Subscription:" + subId); return null; } } } public String getMsisdn(String callingPackage) { public String getMsisdn(String callingPackage) { Loading @@ -255,17 +163,8 @@ public class PhoneSubInfoController extends IPhoneSubInfo.Stub { } } public String getMsisdnForSubscriber(int subId, String callingPackage) { public String getMsisdnForSubscriber(int subId, String callingPackage) { Phone phone = getPhone(subId); return callPhoneMethodForSubIdWithReadCheck(subId, callingPackage, "getMsisdn", if (phone != null) { (phone)-> phone.getMsisdn()); if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState( mContext, subId, callingPackage, "getMsisdn")) { return null; } return phone.getMsisdn(); } else { loge("getMsisdn phone is null for Subscription:" + subId); return null; } } } public String getVoiceMailNumber(String callingPackage) { public String getVoiceMailNumber(String callingPackage) { Loading @@ -273,19 +172,13 @@ public class PhoneSubInfoController extends IPhoneSubInfo.Stub { } } public String getVoiceMailNumberForSubscriber(int subId, String callingPackage) { public String getVoiceMailNumberForSubscriber(int subId, String callingPackage) { Phone phone = getPhone(subId); return callPhoneMethodForSubIdWithReadCheck(subId, callingPackage, if (phone != null) { "getVoiceMailNumber", (phone)-> { if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState( String number = PhoneNumberUtils.extractNetworkPortion( mContext, subId, callingPackage, "getVoiceMailNumber")) { phone.getVoiceMailNumber()); return null; } String number = PhoneNumberUtils.extractNetworkPortion(phone.getVoiceMailNumber()); if (VDBG) log("VM: getVoiceMailNUmber: " + number); if (VDBG) log("VM: getVoiceMailNUmber: " + number); return number; return number; } else { }); loge("getVoiceMailNumber phone is null for Subscription:" + subId); return null; } } } // TODO: change getCompleteVoiceMailNumber() to require READ_PRIVILEGED_PHONE_STATE // 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) { public String getVoiceMailAlphaTagForSubscriber(int subId, String callingPackage) { Phone phone = getPhone(subId); return callPhoneMethodForSubIdWithReadCheck(subId, callingPackage, if (phone != null) { "getVoiceMailAlphaTag", (phone)-> phone.getVoiceMailAlphaTag()); if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState( mContext, subId, callingPackage, "getVoiceMailAlphaTag")) { return null; } return phone.getVoiceMailAlphaTag(); } else { loge("getVoiceMailAlphaTag phone is null for Subscription:" + subId); return null; } } } /** /** Loading @@ -341,6 +225,9 @@ public class PhoneSubInfoController extends IPhoneSubInfo.Stub { * @throws SecurityException if the caller does not have the required permission/privilege * @throws SecurityException if the caller does not have the required permission/privilege */ */ private void enforcePrivilegedPermissionOrCarrierPrivilege(int subId, String message) { private void enforcePrivilegedPermissionOrCarrierPrivilege(int subId, String message) { // TODO(b/73660190): Migrate to // TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivileges and delete // this helper method. int permissionResult = mContext.checkCallingOrSelfPermission( int permissionResult = mContext.checkCallingOrSelfPermission( READ_PRIVILEGED_PHONE_STATE); READ_PRIVILEGED_PHONE_STATE); if (permissionResult == PackageManager.PERMISSION_GRANTED) { if (permissionResult == PackageManager.PERMISSION_GRANTED) { Loading @@ -362,114 +249,84 @@ public class PhoneSubInfoController extends IPhoneSubInfo.Stub { return PhoneFactory.getDefaultSubscription(); return PhoneFactory.getDefaultSubscription(); } } /** /** * get the Isim Impi based on subId * get the Isim Impi based on subId */ */ public String getIsimImpi(int subId) { public String getIsimImpi(int subId) { Phone phone = getPhone(subId); return callPhoneMethodForSubIdWithPrivilegedCheck(subId, "getIsimImpi", if (phone != null) { (phone) -> { mContext.enforceCallingOrSelfPermission(READ_PRIVILEGED_PHONE_STATE, "Requires READ_PRIVILEGED_PHONE_STATE"); IsimRecords isim = phone.getIsimRecords(); IsimRecords isim = phone.getIsimRecords(); if (isim != null) { if (isim != null) { return isim.getIsimImpi(); return isim.getIsimImpi(); } else { } else { return null; return null; } } } else { }); loge("getIsimImpi phone is null for Subscription:" + subId); return null; } } } /** /** * get the Isim Domain based on subId * get the Isim Domain based on subId */ */ public String getIsimDomain(int subId) { public String getIsimDomain(int subId) { Phone phone = getPhone(subId); return callPhoneMethodForSubIdWithPrivilegedCheck(subId, "getIsimDomain", if (phone != null) { (phone) -> { mContext.enforceCallingOrSelfPermission(READ_PRIVILEGED_PHONE_STATE, "Requires READ_PRIVILEGED_PHONE_STATE"); IsimRecords isim = phone.getIsimRecords(); IsimRecords isim = phone.getIsimRecords(); if (isim != null) { if (isim != null) { return isim.getIsimDomain(); return isim.getIsimDomain(); } else { } else { return null; return null; } } } else { }); loge("getIsimDomain phone is null for Subscription:" + subId); return null; } } } /** /** * get the Isim Impu based on subId * get the Isim Impu based on subId */ */ public String[] getIsimImpu(int subId) { public String[] getIsimImpu(int subId) { Phone phone = getPhone(subId); return callPhoneMethodForSubIdWithPrivilegedCheck(subId, "getIsimImpu", if (phone != null) { (phone) -> { mContext.enforceCallingOrSelfPermission(READ_PRIVILEGED_PHONE_STATE, "Requires READ_PRIVILEGED_PHONE_STATE"); IsimRecords isim = phone.getIsimRecords(); IsimRecords isim = phone.getIsimRecords(); if (isim != null) { if (isim != null) { return isim.getIsimImpu(); return isim.getIsimImpu(); } else { } else { return null; return null; } } } else { }); loge("getIsimImpu phone is null for Subscription:" + subId); return null; } } } /** /** * get the Isim Ist based on subId * get the Isim Ist based on subId */ */ public String getIsimIst(int subId) throws RemoteException { public String getIsimIst(int subId) throws RemoteException { Phone phone = getPhone(subId); return callPhoneMethodForSubIdWithPrivilegedCheck(subId, "getIsimIst", if (phone != null) { (phone) -> { mContext.enforceCallingOrSelfPermission(READ_PRIVILEGED_PHONE_STATE, "Requires READ_PRIVILEGED_PHONE_STATE"); IsimRecords isim = phone.getIsimRecords(); IsimRecords isim = phone.getIsimRecords(); if (isim != null) { if (isim != null) { return isim.getIsimIst(); return isim.getIsimIst(); } else { } else { return null; return null; } } } else { }); loge("getIsimIst phone is null for Subscription:" + subId); return null; } } } /** /** * get the Isim Pcscf based on subId * get the Isim Pcscf based on subId */ */ public String[] getIsimPcscf(int subId) throws RemoteException { public String[] getIsimPcscf(int subId) throws RemoteException { Phone phone = getPhone(subId); return callPhoneMethodForSubIdWithPrivilegedCheck(subId, "getIsimPcscf", if (phone != null) { (phone) -> { mContext.enforceCallingOrSelfPermission(READ_PRIVILEGED_PHONE_STATE, "Requires READ_PRIVILEGED_PHONE_STATE"); IsimRecords isim = phone.getIsimRecords(); IsimRecords isim = phone.getIsimRecords(); if (isim != null) { if (isim != null) { return isim.getIsimPcscf(); return isim.getIsimPcscf(); } else { } else { return null; return null; } } } else { }); loge("getIsimPcscf phone is null for Subscription:" + subId); return null; } } } public String getIccSimChallengeResponse(int subId, int appType, int authType, String data) public String getIccSimChallengeResponse(int subId, int appType, int authType, String data) throws RemoteException { throws RemoteException { // TODO(b/73660190): Migrate to CallPhoneMethodHelper<String> toExecute = (phone)-> { // TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivileges and delete // this helper method. enforcePrivilegedPermissionOrCarrierPrivilege(subId, "getIccSimChallengeResponse"); Phone phone = getPhone(subId); UiccCard uiccCard = phone.getUiccCard(); UiccCard uiccCard = phone.getUiccCard(); if (uiccCard == null) { if (uiccCard == null) { loge("getIccSimChallengeResponse() UiccCard is null"); loge("getIccSimChallengeResponse() UiccCard is null"); Loading @@ -478,35 +335,130 @@ public class PhoneSubInfoController extends IPhoneSubInfo.Stub { UiccCardApplication uiccApp = uiccCard.getApplicationByType(appType); UiccCardApplication uiccApp = uiccCard.getApplicationByType(appType); if (uiccApp == null) { if (uiccApp == null) { loge("getIccSimChallengeResponse() no app with specified type -- " + loge("getIccSimChallengeResponse() no app with specified type -- " + appType); appType); return null; return null; } else { } else { loge("getIccSimChallengeResponse() found app " + uiccApp.getAid() loge("getIccSimChallengeResponse() found app " + uiccApp.getAid() + " specified type -- " + appType); + " specified type -- " + appType); } } if(authType != UiccCardApplication.AUTH_CONTEXT_EAP_SIM && if (authType != UiccCardApplication.AUTH_CONTEXT_EAP_SIM authType != UiccCardApplication.AUTH_CONTEXT_EAP_AKA) { && authType != UiccCardApplication.AUTH_CONTEXT_EAP_AKA) { loge("getIccSimChallengeResponse() unsupported authType: " + authType); loge("getIccSimChallengeResponse() unsupported authType: " + authType); return null; return null; } } return uiccApp.getIccRecords().getIccSimChallengeResponse(authType, data); 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) { 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); Phone phone = getPhone(subId); if (phone != null) { if (phone != null) { if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState( return callMethodHelper.callMethod(phone); mContext, subId, callingPackage, "getGroupIdLevel1")) { } else { loge(message + " phone is null for Subscription:" + subId); return null; return null; } } return phone.getGroupIdLevel1(); } finally { } else { Binder.restoreCallingIdentity(identity); loge("getGroupIdLevel1 phone is null for Subscription:" + subId); } } 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; 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) { private void log(String s) { Loading Loading
src/java/com/android/internal/telephony/PhoneSubInfoController.java +214 −262 Original line number Original line 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.app.AppOpsManager; import android.content.Context; import android.content.Context; import android.content.pm.PackageManager; import android.content.pm.PackageManager; import android.os.Binder; import android.os.RemoteException; import android.os.RemoteException; import android.os.ServiceManager; import android.os.ServiceManager; import android.telephony.ImsiEncryptionInfo; import android.telephony.ImsiEncryptionInfo; Loading Loading @@ -60,80 +61,35 @@ public class PhoneSubInfoController extends IPhoneSubInfo.Stub { } } public String getDeviceIdForPhone(int phoneId, String callingPackage) { public String getDeviceIdForPhone(int phoneId, String callingPackage) { if (!SubscriptionManager.isValidPhoneId(phoneId)) { return callPhoneMethodForPhoneIdWithReadCheck(phoneId, callingPackage, phoneId = 0; "getDeviceId", (phone)-> phone.getDeviceId()); } 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; } } } public String getNaiForSubscriber(int subId, String callingPackage) { public String getNaiForSubscriber(int subId, String callingPackage) { Phone phone = getPhone(subId); return callPhoneMethodForSubIdWithReadCheck(subId, callingPackage, "getNai", if (phone != null) { (phone)-> phone.getNai()); if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState( mContext, subId, callingPackage, "getNai")) { return null; } return phone.getNai(); } else { loge("getNai phone is null for Subscription:" + subId); return null; } } } public String getImeiForSubscriber(int subId, String callingPackage) { public String getImeiForSubscriber(int subId, String callingPackage) { Phone phone = getPhone(subId); return callPhoneMethodForSubIdWithReadCheck(subId, callingPackage, "getImei", if (phone != null) { (phone)-> phone.getImei()); if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState( mContext, subId, callingPackage, "getImei")) { return null; } return phone.getImei(); } else { loge("getDeviceId phone is null for Subscription:" + subId); return null; } } } public ImsiEncryptionInfo getCarrierInfoForImsiEncryption(int subId, int keyType, public ImsiEncryptionInfo getCarrierInfoForImsiEncryption(int subId, int keyType, String callingPackage) { String callingPackage) { Phone phone = getPhone(subId); return callPhoneMethodForSubIdWithReadCheck(subId, callingPackage, if (phone != null) { "getCarrierInfoForImsiEncryption", if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState( (phone)-> phone.getCarrierInfoForImsiEncryption(keyType)); mContext, subId, callingPackage, "getCarrierInfoForImsiEncryption")) { return null; } return phone.getCarrierInfoForImsiEncryption(keyType); } else { loge("getCarrierInfoForImsiEncryption phone is null for Subscription:" + subId); return null; } } } public void setCarrierInfoForImsiEncryption(int subId, String callingPackage, public void setCarrierInfoForImsiEncryption(int subId, String callingPackage, ImsiEncryptionInfo imsiEncryptionInfo) { ImsiEncryptionInfo imsiEncryptionInfo) { Phone phone = getPhone(subId); callPhoneMethodForSubIdWithModifyCheck(subId, callingPackage, if (phone != null) { "setCarrierInfoForImsiEncryption", if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState( (phone)-> { mContext, subId, callingPackage, "setCarrierInfoForImsiEncryption")) { return; } enforceModifyPermission(); phone.setCarrierInfoForImsiEncryption(imsiEncryptionInfo); phone.setCarrierInfoForImsiEncryption(imsiEncryptionInfo); } else { return null; loge("setCarrierInfoForImsiEncryption phone is null for Subscription:" + subId); }); return; } } } /** /** Loading @@ -144,15 +100,12 @@ public class PhoneSubInfoController extends IPhoneSubInfo.Stub { * @param callingPackage * @param callingPackage */ */ public void resetCarrierKeysForImsiEncryption(int subId, String callingPackage) { public void resetCarrierKeysForImsiEncryption(int subId, String callingPackage) { Phone phone = getPhone(subId); callPhoneMethodForSubIdWithModifyCheck(subId, callingPackage, if (phone != null) { "setCarrierInfoForImsiEncryption", enforceModifyPermission(); (phone)-> { phone.resetCarrierKeysForImsiEncryption(); phone.resetCarrierKeysForImsiEncryption(); return; return null; } else { }); loge("resetCarrierKeysForImsiEncryption phone is null for Subscription:" + subId); return; } } } Loading @@ -161,17 +114,8 @@ public class PhoneSubInfoController extends IPhoneSubInfo.Stub { } } public String getDeviceSvnUsingSubId(int subId, String callingPackage) { public String getDeviceSvnUsingSubId(int subId, String callingPackage) { Phone phone = getPhone(subId); return callPhoneMethodForSubIdWithReadCheck(subId, callingPackage, "getDeviceSvn", if (phone != null) { (phone)-> phone.getDeviceSvn()); if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState( mContext, subId, callingPackage, "getDeviceSvn")) { return null; } return phone.getDeviceSvn(); } else { loge("getDeviceSvn phone is null"); return null; } } } public String getSubscriberId(String callingPackage) { public String getSubscriberId(String callingPackage) { Loading @@ -179,17 +123,8 @@ public class PhoneSubInfoController extends IPhoneSubInfo.Stub { } } public String getSubscriberIdForSubscriber(int subId, String callingPackage) { public String getSubscriberIdForSubscriber(int subId, String callingPackage) { Phone phone = getPhone(subId); return callPhoneMethodForSubIdWithReadCheck(subId, callingPackage, "getSubscriberId", if (phone != null) { (phone)-> phone.getSubscriberId()); if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState( mContext, subId, callingPackage, "getSubscriberId")) { return null; } return phone.getSubscriberId(); } else { loge("getSubscriberId phone is null for Subscription:" + subId); return null; } } } /** /** Loading @@ -200,17 +135,8 @@ public class PhoneSubInfoController extends IPhoneSubInfo.Stub { } } public String getIccSerialNumberForSubscriber(int subId, String callingPackage) { public String getIccSerialNumberForSubscriber(int subId, String callingPackage) { Phone phone = getPhone(subId); return callPhoneMethodForSubIdWithReadCheck(subId, callingPackage, "getIccSerialNumber", if (phone != null) { (phone)-> phone.getIccSerialNumber()); if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState( mContext, subId, callingPackage, "getIccSerialNumber")) { return null; } return phone.getIccSerialNumber(); } else { loge("getIccSerialNumber phone is null for Subscription:" + subId); return null; } } } public String getLine1Number(String callingPackage) { public String getLine1Number(String callingPackage) { Loading @@ -218,18 +144,9 @@ public class PhoneSubInfoController extends IPhoneSubInfo.Stub { } } public String getLine1NumberForSubscriber(int subId, String callingPackage) { public String getLine1NumberForSubscriber(int subId, String callingPackage) { Phone phone = getPhone(subId); return callPhoneMethodForSubIdWithReadPhoneNumberCheck( if (phone != null) { subId, callingPackage, "getLine1Number", // This is open to apps with WRITE_SMS. (phone)-> phone.getLine1Number()); if (!TelephonyPermissions.checkCallingOrSelfReadPhoneNumber( mContext, subId, callingPackage, "getLine1Number")) { return null; } return phone.getLine1Number(); } else { loge("getLine1Number phone is null for Subscription:" + subId); return null; } } } public String getLine1AlphaTag(String callingPackage) { public String getLine1AlphaTag(String callingPackage) { Loading @@ -237,17 +154,8 @@ public class PhoneSubInfoController extends IPhoneSubInfo.Stub { } } public String getLine1AlphaTagForSubscriber(int subId, String callingPackage) { public String getLine1AlphaTagForSubscriber(int subId, String callingPackage) { Phone phone = getPhone(subId); return callPhoneMethodForSubIdWithReadCheck(subId, callingPackage, "getLine1AlphaTag", if (phone != null) { (phone)-> phone.getLine1AlphaTag()); if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState( mContext, subId, callingPackage, "getLine1AlphaTag")) { return null; } return phone.getLine1AlphaTag(); } else { loge("getLine1AlphaTag phone is null for Subscription:" + subId); return null; } } } public String getMsisdn(String callingPackage) { public String getMsisdn(String callingPackage) { Loading @@ -255,17 +163,8 @@ public class PhoneSubInfoController extends IPhoneSubInfo.Stub { } } public String getMsisdnForSubscriber(int subId, String callingPackage) { public String getMsisdnForSubscriber(int subId, String callingPackage) { Phone phone = getPhone(subId); return callPhoneMethodForSubIdWithReadCheck(subId, callingPackage, "getMsisdn", if (phone != null) { (phone)-> phone.getMsisdn()); if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState( mContext, subId, callingPackage, "getMsisdn")) { return null; } return phone.getMsisdn(); } else { loge("getMsisdn phone is null for Subscription:" + subId); return null; } } } public String getVoiceMailNumber(String callingPackage) { public String getVoiceMailNumber(String callingPackage) { Loading @@ -273,19 +172,13 @@ public class PhoneSubInfoController extends IPhoneSubInfo.Stub { } } public String getVoiceMailNumberForSubscriber(int subId, String callingPackage) { public String getVoiceMailNumberForSubscriber(int subId, String callingPackage) { Phone phone = getPhone(subId); return callPhoneMethodForSubIdWithReadCheck(subId, callingPackage, if (phone != null) { "getVoiceMailNumber", (phone)-> { if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState( String number = PhoneNumberUtils.extractNetworkPortion( mContext, subId, callingPackage, "getVoiceMailNumber")) { phone.getVoiceMailNumber()); return null; } String number = PhoneNumberUtils.extractNetworkPortion(phone.getVoiceMailNumber()); if (VDBG) log("VM: getVoiceMailNUmber: " + number); if (VDBG) log("VM: getVoiceMailNUmber: " + number); return number; return number; } else { }); loge("getVoiceMailNumber phone is null for Subscription:" + subId); return null; } } } // TODO: change getCompleteVoiceMailNumber() to require READ_PRIVILEGED_PHONE_STATE // 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) { public String getVoiceMailAlphaTagForSubscriber(int subId, String callingPackage) { Phone phone = getPhone(subId); return callPhoneMethodForSubIdWithReadCheck(subId, callingPackage, if (phone != null) { "getVoiceMailAlphaTag", (phone)-> phone.getVoiceMailAlphaTag()); if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState( mContext, subId, callingPackage, "getVoiceMailAlphaTag")) { return null; } return phone.getVoiceMailAlphaTag(); } else { loge("getVoiceMailAlphaTag phone is null for Subscription:" + subId); return null; } } } /** /** Loading @@ -341,6 +225,9 @@ public class PhoneSubInfoController extends IPhoneSubInfo.Stub { * @throws SecurityException if the caller does not have the required permission/privilege * @throws SecurityException if the caller does not have the required permission/privilege */ */ private void enforcePrivilegedPermissionOrCarrierPrivilege(int subId, String message) { private void enforcePrivilegedPermissionOrCarrierPrivilege(int subId, String message) { // TODO(b/73660190): Migrate to // TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivileges and delete // this helper method. int permissionResult = mContext.checkCallingOrSelfPermission( int permissionResult = mContext.checkCallingOrSelfPermission( READ_PRIVILEGED_PHONE_STATE); READ_PRIVILEGED_PHONE_STATE); if (permissionResult == PackageManager.PERMISSION_GRANTED) { if (permissionResult == PackageManager.PERMISSION_GRANTED) { Loading @@ -362,114 +249,84 @@ public class PhoneSubInfoController extends IPhoneSubInfo.Stub { return PhoneFactory.getDefaultSubscription(); return PhoneFactory.getDefaultSubscription(); } } /** /** * get the Isim Impi based on subId * get the Isim Impi based on subId */ */ public String getIsimImpi(int subId) { public String getIsimImpi(int subId) { Phone phone = getPhone(subId); return callPhoneMethodForSubIdWithPrivilegedCheck(subId, "getIsimImpi", if (phone != null) { (phone) -> { mContext.enforceCallingOrSelfPermission(READ_PRIVILEGED_PHONE_STATE, "Requires READ_PRIVILEGED_PHONE_STATE"); IsimRecords isim = phone.getIsimRecords(); IsimRecords isim = phone.getIsimRecords(); if (isim != null) { if (isim != null) { return isim.getIsimImpi(); return isim.getIsimImpi(); } else { } else { return null; return null; } } } else { }); loge("getIsimImpi phone is null for Subscription:" + subId); return null; } } } /** /** * get the Isim Domain based on subId * get the Isim Domain based on subId */ */ public String getIsimDomain(int subId) { public String getIsimDomain(int subId) { Phone phone = getPhone(subId); return callPhoneMethodForSubIdWithPrivilegedCheck(subId, "getIsimDomain", if (phone != null) { (phone) -> { mContext.enforceCallingOrSelfPermission(READ_PRIVILEGED_PHONE_STATE, "Requires READ_PRIVILEGED_PHONE_STATE"); IsimRecords isim = phone.getIsimRecords(); IsimRecords isim = phone.getIsimRecords(); if (isim != null) { if (isim != null) { return isim.getIsimDomain(); return isim.getIsimDomain(); } else { } else { return null; return null; } } } else { }); loge("getIsimDomain phone is null for Subscription:" + subId); return null; } } } /** /** * get the Isim Impu based on subId * get the Isim Impu based on subId */ */ public String[] getIsimImpu(int subId) { public String[] getIsimImpu(int subId) { Phone phone = getPhone(subId); return callPhoneMethodForSubIdWithPrivilegedCheck(subId, "getIsimImpu", if (phone != null) { (phone) -> { mContext.enforceCallingOrSelfPermission(READ_PRIVILEGED_PHONE_STATE, "Requires READ_PRIVILEGED_PHONE_STATE"); IsimRecords isim = phone.getIsimRecords(); IsimRecords isim = phone.getIsimRecords(); if (isim != null) { if (isim != null) { return isim.getIsimImpu(); return isim.getIsimImpu(); } else { } else { return null; return null; } } } else { }); loge("getIsimImpu phone is null for Subscription:" + subId); return null; } } } /** /** * get the Isim Ist based on subId * get the Isim Ist based on subId */ */ public String getIsimIst(int subId) throws RemoteException { public String getIsimIst(int subId) throws RemoteException { Phone phone = getPhone(subId); return callPhoneMethodForSubIdWithPrivilegedCheck(subId, "getIsimIst", if (phone != null) { (phone) -> { mContext.enforceCallingOrSelfPermission(READ_PRIVILEGED_PHONE_STATE, "Requires READ_PRIVILEGED_PHONE_STATE"); IsimRecords isim = phone.getIsimRecords(); IsimRecords isim = phone.getIsimRecords(); if (isim != null) { if (isim != null) { return isim.getIsimIst(); return isim.getIsimIst(); } else { } else { return null; return null; } } } else { }); loge("getIsimIst phone is null for Subscription:" + subId); return null; } } } /** /** * get the Isim Pcscf based on subId * get the Isim Pcscf based on subId */ */ public String[] getIsimPcscf(int subId) throws RemoteException { public String[] getIsimPcscf(int subId) throws RemoteException { Phone phone = getPhone(subId); return callPhoneMethodForSubIdWithPrivilegedCheck(subId, "getIsimPcscf", if (phone != null) { (phone) -> { mContext.enforceCallingOrSelfPermission(READ_PRIVILEGED_PHONE_STATE, "Requires READ_PRIVILEGED_PHONE_STATE"); IsimRecords isim = phone.getIsimRecords(); IsimRecords isim = phone.getIsimRecords(); if (isim != null) { if (isim != null) { return isim.getIsimPcscf(); return isim.getIsimPcscf(); } else { } else { return null; return null; } } } else { }); loge("getIsimPcscf phone is null for Subscription:" + subId); return null; } } } public String getIccSimChallengeResponse(int subId, int appType, int authType, String data) public String getIccSimChallengeResponse(int subId, int appType, int authType, String data) throws RemoteException { throws RemoteException { // TODO(b/73660190): Migrate to CallPhoneMethodHelper<String> toExecute = (phone)-> { // TelephonyPermissions.enforceCallingOrSelfModifyPermissionOrCarrierPrivileges and delete // this helper method. enforcePrivilegedPermissionOrCarrierPrivilege(subId, "getIccSimChallengeResponse"); Phone phone = getPhone(subId); UiccCard uiccCard = phone.getUiccCard(); UiccCard uiccCard = phone.getUiccCard(); if (uiccCard == null) { if (uiccCard == null) { loge("getIccSimChallengeResponse() UiccCard is null"); loge("getIccSimChallengeResponse() UiccCard is null"); Loading @@ -478,35 +335,130 @@ public class PhoneSubInfoController extends IPhoneSubInfo.Stub { UiccCardApplication uiccApp = uiccCard.getApplicationByType(appType); UiccCardApplication uiccApp = uiccCard.getApplicationByType(appType); if (uiccApp == null) { if (uiccApp == null) { loge("getIccSimChallengeResponse() no app with specified type -- " + loge("getIccSimChallengeResponse() no app with specified type -- " + appType); appType); return null; return null; } else { } else { loge("getIccSimChallengeResponse() found app " + uiccApp.getAid() loge("getIccSimChallengeResponse() found app " + uiccApp.getAid() + " specified type -- " + appType); + " specified type -- " + appType); } } if(authType != UiccCardApplication.AUTH_CONTEXT_EAP_SIM && if (authType != UiccCardApplication.AUTH_CONTEXT_EAP_SIM authType != UiccCardApplication.AUTH_CONTEXT_EAP_AKA) { && authType != UiccCardApplication.AUTH_CONTEXT_EAP_AKA) { loge("getIccSimChallengeResponse() unsupported authType: " + authType); loge("getIccSimChallengeResponse() unsupported authType: " + authType); return null; return null; } } return uiccApp.getIccRecords().getIccSimChallengeResponse(authType, data); 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) { 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); Phone phone = getPhone(subId); if (phone != null) { if (phone != null) { if (!TelephonyPermissions.checkCallingOrSelfReadPhoneState( return callMethodHelper.callMethod(phone); mContext, subId, callingPackage, "getGroupIdLevel1")) { } else { loge(message + " phone is null for Subscription:" + subId); return null; return null; } } return phone.getGroupIdLevel1(); } finally { } else { Binder.restoreCallingIdentity(identity); loge("getGroupIdLevel1 phone is null for Subscription:" + subId); } } 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; 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) { private void log(String s) { Loading