Loading src/java/com/android/internal/telephony/MultiSimSettingController.java +9 −5 Original line number Diff line number Diff line Loading @@ -144,14 +144,18 @@ public class MultiSimSettingController { * When a subscription group is created or new subscriptions are added in the group, make * sure the settings among them are synced. */ public synchronized void onSubscriptionGroupCreated(int[] subGroup) { if (DBG) log("onSubscriptionGroupCreated"); if (subGroup == null || subGroup.length == 0) return; public synchronized void onSubscriptionGroupChanged(ParcelUuid groupUuid) { if (DBG) log("onSubscriptionGroupChanged"); List<SubscriptionInfo> infoList = mSubController.getSubscriptionsInGroup( groupUuid, mContext.getOpPackageName()); if (infoList == null || infoList.isEmpty()) return; // Get a reference subscription to copy settings from. // TODO: the reference sub should be passed in from external caller. int refSubId = subGroup[0]; for (int subId : subGroup) { int refSubId = infoList.get(0).getSubscriptionId(); for (SubscriptionInfo info : infoList) { int subId = info.getSubscriptionId(); if (mSubController.isActiveSubId(subId) && !mSubController.isOpportunistic(subId)) { refSubId = subId; break; Loading src/java/com/android/internal/telephony/PhoneFactory.java +8 −5 Original line number Diff line number Diff line Loading @@ -307,13 +307,16 @@ public class PhoneFactory { throw new IllegalStateException("Default phones haven't been made yet!"); // CAF_MSIM FIXME need to introduce default phone id ? } else if (phoneId == SubscriptionManager.DEFAULT_PHONE_INDEX) { if (DBG) dbgInfo = "phoneId == DEFAULT_PHONE_ID return sPhone"; if (DBG) { dbgInfo = "phoneId == DEFAULT_PHONE_ID return sPhone"; } phone = sPhone; } else { if (DBG) dbgInfo = "phoneId != DEFAULT_PHONE_ID return sPhones[phoneId]"; phone = (((phoneId >= 0) && (phoneId < TelephonyManager.getDefault().getPhoneCount())) ? sPhones[phoneId] : null); if (DBG) { dbgInfo = "phoneId != DEFAULT_PHONE_ID return sPhones[phoneId]"; } phone = (phoneId >= 0 && phoneId < sPhones.length) ? sPhones[phoneId] : null; } if (DBG) { Rlog.d(LOG_TAG, "getPhone:- " + dbgInfo + " phoneId=" + phoneId + Loading src/java/com/android/internal/telephony/PhoneSwitcher.java +30 −6 Original line number Diff line number Diff line Loading @@ -147,6 +147,7 @@ public class PhoneSwitcher extends Handler { private static final int EVENT_REMOVE_DEFAULT_NETWORK_CHANGE_CALLBACK = 111; private static final int EVENT_MODEM_COMMAND_DONE = 112; private static final int EVENT_MODEM_COMMAND_RETRY = 113; private static final int EVENT_DATA_ENABLED_CHANGED = 114; // Depending on version of IRadioConfig, we need to send either RIL_REQUEST_ALLOW_DATA if it's // 1.0, or RIL_REQUEST_SET_PREFERRED_DATA if it's 1.1 or later. So internally mHalCommandToUse Loading Loading @@ -264,6 +265,21 @@ public class PhoneSwitcher extends Handler { if (mPhoneIdInVoiceCall != oldPhoneIdInVoiceCall) { log("mPhoneIdInVoiceCall changed from" + oldPhoneIdInVoiceCall + " to " + mPhoneIdInVoiceCall); // Switches and listens to the updated voice phone. Phone dataPhone = findPhoneById(mPhoneIdInVoiceCall); if (dataPhone != null && dataPhone.getDataEnabledSettings() != null) { dataPhone.getDataEnabledSettings() .registerForDataEnabledChanged(getInstance(), EVENT_DATA_ENABLED_CHANGED, null); } Phone oldDataPhone = findPhoneById(oldPhoneIdInVoiceCall); if (oldDataPhone != null && oldDataPhone.getDataEnabledSettings() != null) { oldDataPhone.getDataEnabledSettings() .unregisterForDataEnabledChanged(getInstance()); } Message msg = PhoneSwitcher.this.obtainMessage(EVENT_PHONE_IN_CALL_CHANGED); msg.sendToTarget(); } Loading Loading @@ -397,7 +413,9 @@ public class PhoneSwitcher extends Handler { onEvaluate(REQUESTS_UNCHANGED, "EVENT_RADIO_AVAILABLE"); break; } case EVENT_PHONE_IN_CALL_CHANGED: { // fall through case EVENT_DATA_ENABLED_CHANGED: case EVENT_PHONE_IN_CALL_CHANGED: if (onEvaluate(REQUESTS_UNCHANGED, "EVENT_PHONE_IN_CALL_CHANGED")) { logDataSwitchEvent(mOpptDataSubId, TelephonyEvent.EventState.EVENT_STATE_START, Loading @@ -405,7 +423,6 @@ public class PhoneSwitcher extends Handler { registerDefaultNetworkChangeCallback(); } break; } case EVENT_NETWORK_VALIDATION_DONE: { int subId = msg.arg1; boolean passed = (msg.arg2 == 1); Loading Loading @@ -770,15 +787,15 @@ public class PhoneSwitcher extends Handler { } } // This updates mPreferredDataPhoneId which decides which phone should // handle default network requests. // This updates mPreferredDataPhoneId which decides which phone should handle default network // requests. private void updatePreferredDataPhoneId() { if (SubscriptionManager.isValidPhoneId(mPhoneIdInVoiceCall)) { Phone voicePhone = findPhoneById(mPhoneIdInVoiceCall); if (voicePhone != null && voicePhone.isUserDataEnabled()) { // If a phone is in call and user enabled its mobile data, we // should switch internet connection to it. Because the other modem // will lose data connection anyway. // TODO: validate network first. mPreferredDataPhoneId = mPhoneIdInVoiceCall; } else { int subId = getSubIdForDefaultNetworkRequests(); Loading @@ -799,6 +816,13 @@ public class PhoneSwitcher extends Handler { mPreferredDataSubId = mSubscriptionController.getSubIdUsingPhoneId(mPreferredDataPhoneId); } private Phone findPhoneById(final int phoneId) { if (phoneId < 0 || phoneId >= mNumPhones) { return null; } return mPhones[phoneId]; } public boolean shouldApplyNetworkRequest(NetworkRequest networkRequest, int phoneId) { validatePhoneId(phoneId); Loading src/java/com/android/internal/telephony/SubscriptionController.java +96 −17 Original line number Diff line number Diff line Loading @@ -39,6 +39,7 @@ import android.os.UserHandle; import android.provider.Settings; import android.telecom.PhoneAccountHandle; import android.telecom.TelecomManager; import android.telephony.CarrierConfigManager; import android.telephony.RadioAccessFamily; import android.telephony.Rlog; import android.telephony.SubscriptionInfo; Loading Loading @@ -100,6 +101,8 @@ public class SubscriptionController extends ISub.Stub { static final boolean DBG_CACHE = false; static final int MAX_LOCAL_LOG_LINES = 500; // TODO: Reduce to 100 when 17678050 is fixed private static final int DEPRECATED_SETTING = -1; private static final ParcelUuid INVALID_GROUP_UUID = ParcelUuid.fromString(CarrierConfigManager.REMOVE_GROUP_UUID_STRING); private ScLocalLog mLocalLog = new ScLocalLog(MAX_LOCAL_LOG_LINES); // Lock that both mCacheActiveSubInfoList and mCacheOpportunisticSubInfoList use. Loading Loading @@ -2793,6 +2796,8 @@ public class SubscriptionController extends ISub.Stub { * * @throws SecurityException if the caller doesn't meet the requirements * outlined above. * @throws IllegalArgumentException if the some subscriptions in the list doesn't exist. * @throws IllegalStateException if Telephony service is in bad state. * * @param subIdList list of subId that will be in the same group * @return groupUUID a UUID assigned to the subscription group. It returns Loading @@ -2802,15 +2807,15 @@ public class SubscriptionController extends ISub.Stub { @Override public ParcelUuid createSubscriptionGroup(int[] subIdList, String callingPackage) { if (subIdList == null || subIdList.length == 0) { return null; throw new IllegalArgumentException("Invalid subIdList " + subIdList); } // If it doesn't have modify phone state permission, or carrier privilege permission, // a SecurityException will be thrown. If it's due to invalid parameter or internal state, // it will return null. // a SecurityException will be thrown. if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.MODIFY_PHONE_STATE) != PERMISSION_GRANTED && !checkCarrierPrivilegeOnSubList( subIdList, callingPackage)) { return null; throw new SecurityException("CreateSubscriptionGroup needs MODIFY_PHONE_STATE or" + " carrier privilege permission on all specified subscriptions"); } long identity = Binder.clearCallingIdentity(); Loading @@ -2830,7 +2835,7 @@ public class SubscriptionController extends ISub.Stub { notifySubscriptionInfoChanged(); MultiSimSettingController.getInstance().onSubscriptionGroupCreated(subIdList); MultiSimSettingController.getInstance().onSubscriptionGroupChanged(groupUUID); return groupUUID; } finally { Loading @@ -2838,10 +2843,78 @@ public class SubscriptionController extends ISub.Stub { } } // TODO: when having a group owner or packageName for subscription, use that to check. // Currently for this method to return false, all subscriptions in the group needs to have // carrier privilege rules loaded, which means active or available. private boolean canPackageManageGroup(ParcelUuid groupUuid, String callingPackage) { if (groupUuid == null) { throw new IllegalArgumentException("Invalid groupUuid"); } List<SubscriptionInfo> infoList; // Getting all subscriptions in the group. long identity = Binder.clearCallingIdentity(); try { infoList = getSubInfo(SubscriptionManager.GROUP_UUID + "=\'" + groupUuid.toString() + "\'", null); } finally { Binder.restoreCallingIdentity(identity); } if (infoList == null || infoList.isEmpty()) { throw new IllegalArgumentException("No subscription in group " + groupUuid); } // Check carrier privilege for all subscriptions in the group. int[] subIdArray = infoList.stream().mapToInt(info -> info.getSubscriptionId()).toArray(); return checkCarrierPrivilegeOnSubList(subIdArray, callingPackage); } @Override public void addSubscriptionsIntoGroup(int[] subIdList, ParcelUuid groupUuid, String callingPackage) { // TODO: implement it. if (subIdList == null || subIdList.length == 0) { throw new IllegalArgumentException("Invalid subId list"); } if (groupUuid == null || groupUuid.equals(INVALID_GROUP_UUID)) { throw new IllegalArgumentException("Invalid groupUuid"); } // If it doesn't have modify phone state permission, or carrier privilege permission, // a SecurityException will be thrown. if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.MODIFY_PHONE_STATE) != PERMISSION_GRANTED && !(checkCarrierPrivilegeOnSubList(subIdList, callingPackage) && canPackageManageGroup(groupUuid, callingPackage))) { throw new SecurityException("Requires MODIFY_PHONE_STATE or carrier privilege" + " permissions on subscriptions and the group."); } long identity = Binder.clearCallingIdentity(); try { if (DBG) { logdl("addSubscriptionsIntoGroup sub list " + Arrays.toString(subIdList) + " into group " + groupUuid); } ContentValues value = new ContentValues(); value.put(SubscriptionManager.GROUP_UUID, groupUuid.toString()); int result = mContext.getContentResolver().update(SubscriptionManager.CONTENT_URI, value, getSelectionForSubIdList(subIdList), null); if (DBG) logdl("addSubscriptionsIntoGroup update DB result: " + result); if (result > 0) { refreshCachedActiveSubscriptionInfoList(); notifySubscriptionInfoChanged(); MultiSimSettingController.getInstance().onSubscriptionGroupChanged(groupUuid); } } finally { Binder.restoreCallingIdentity(identity); } } /** Loading Loading @@ -2872,7 +2945,8 @@ public class SubscriptionController extends ISub.Stub { if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.MODIFY_PHONE_STATE) != PERMISSION_GRANTED && !checkCarrierPrivilegeOnSubList( subIdList, callingPackage)) { return; throw new SecurityException("removeSubscriptionsFromGroup needs MODIFY_PHONE_STATE or" + " carrier privilege permission on all specified subscriptions"); } long identity = Binder.clearCallingIdentity(); Loading Loading @@ -2906,10 +2980,10 @@ public class SubscriptionController extends ISub.Stub { * The check can either be processed against access rules on currently active SIM cards, or * the access rules we keep in our database for currently inactive eSIMs. * * Throws {@link SecurityException} if it fails. * @throws IllegalArgumentException if the some subId is invalid or doesn't exist. * @throws IllegalStateException if Telephony is in bad state. * * @return true if checking passes on all subId. false if subId is invalid or doesn't exist, * or sub controller is not ready yet. * @return true if checking passes on all subId, false otherwise. */ private boolean checkCarrierPrivilegeOnSubList(int[] subIdList, String callingPackage) { mAppOps.checkPackage(Binder.getCallingUid(), callingPackage); Loading @@ -2920,7 +2994,7 @@ public class SubscriptionController extends ISub.Stub { for (int subId : subIdList) { if (isActiveSubId(subId)) { if (!mTelephonyManager.hasCarrierPrivileges(subId)) { throw new SecurityException("Need carrier privilege on subId " + subId); return false; } } else { checkSubList.add(subId); Loading @@ -2935,22 +3009,27 @@ public class SubscriptionController extends ISub.Stub { try { if (!isSubInfoReady()) { if (DBG) logdl("[getSubscriptionInfoList] Sub Controller not ready"); return false; throw new IllegalStateException("Sub Controller not ready"); } // Check access rules for each sub info. SubscriptionManager subscriptionManager = (SubscriptionManager) mContext.getSystemService(Context.TELEPHONY_SUBSCRIPTION_SERVICE); List<SubscriptionInfo> subList = getSubInfo(getSelectionForSubIdList(subIdList), null); for (SubscriptionInfo subInfo : subList) { List<SubscriptionInfo> subInfoList = getSubInfo( getSelectionForSubIdList(subIdList), null); // Didn't find all the subscriptions specified in subIdList. if (subInfoList == null || subInfoList.size() != subIdList.length) { throw new IllegalArgumentException("Invalid subInfoList."); } for (SubscriptionInfo subInfo : subInfoList) { if (checkSubList.contains(subInfo.getSubscriptionId())) { if (subInfo.isEmbedded() && subscriptionManager.canManageSubscription( subInfo, callingPackage)) { checkSubList.remove(subInfo.getSubscriptionId()); } else { throw new SecurityException("Need carrier privilege on subId " + subInfo.getSubscriptionId()); return false; } } } Loading src/java/com/android/internal/telephony/SubscriptionInfoUpdater.java +1 −0 Original line number Diff line number Diff line Loading @@ -860,6 +860,7 @@ public class SubscriptionInfoUpdater extends Handler { .getUriForSubscriptionId(currentSubId), cv, null, null) > 0) { sc.refreshCachedActiveSubscriptionInfoList(); sc.notifySubscriptionInfoChanged(); MultiSimSettingController.getInstance().onSubscriptionGroupChanged(groupId); } } Loading Loading
src/java/com/android/internal/telephony/MultiSimSettingController.java +9 −5 Original line number Diff line number Diff line Loading @@ -144,14 +144,18 @@ public class MultiSimSettingController { * When a subscription group is created or new subscriptions are added in the group, make * sure the settings among them are synced. */ public synchronized void onSubscriptionGroupCreated(int[] subGroup) { if (DBG) log("onSubscriptionGroupCreated"); if (subGroup == null || subGroup.length == 0) return; public synchronized void onSubscriptionGroupChanged(ParcelUuid groupUuid) { if (DBG) log("onSubscriptionGroupChanged"); List<SubscriptionInfo> infoList = mSubController.getSubscriptionsInGroup( groupUuid, mContext.getOpPackageName()); if (infoList == null || infoList.isEmpty()) return; // Get a reference subscription to copy settings from. // TODO: the reference sub should be passed in from external caller. int refSubId = subGroup[0]; for (int subId : subGroup) { int refSubId = infoList.get(0).getSubscriptionId(); for (SubscriptionInfo info : infoList) { int subId = info.getSubscriptionId(); if (mSubController.isActiveSubId(subId) && !mSubController.isOpportunistic(subId)) { refSubId = subId; break; Loading
src/java/com/android/internal/telephony/PhoneFactory.java +8 −5 Original line number Diff line number Diff line Loading @@ -307,13 +307,16 @@ public class PhoneFactory { throw new IllegalStateException("Default phones haven't been made yet!"); // CAF_MSIM FIXME need to introduce default phone id ? } else if (phoneId == SubscriptionManager.DEFAULT_PHONE_INDEX) { if (DBG) dbgInfo = "phoneId == DEFAULT_PHONE_ID return sPhone"; if (DBG) { dbgInfo = "phoneId == DEFAULT_PHONE_ID return sPhone"; } phone = sPhone; } else { if (DBG) dbgInfo = "phoneId != DEFAULT_PHONE_ID return sPhones[phoneId]"; phone = (((phoneId >= 0) && (phoneId < TelephonyManager.getDefault().getPhoneCount())) ? sPhones[phoneId] : null); if (DBG) { dbgInfo = "phoneId != DEFAULT_PHONE_ID return sPhones[phoneId]"; } phone = (phoneId >= 0 && phoneId < sPhones.length) ? sPhones[phoneId] : null; } if (DBG) { Rlog.d(LOG_TAG, "getPhone:- " + dbgInfo + " phoneId=" + phoneId + Loading
src/java/com/android/internal/telephony/PhoneSwitcher.java +30 −6 Original line number Diff line number Diff line Loading @@ -147,6 +147,7 @@ public class PhoneSwitcher extends Handler { private static final int EVENT_REMOVE_DEFAULT_NETWORK_CHANGE_CALLBACK = 111; private static final int EVENT_MODEM_COMMAND_DONE = 112; private static final int EVENT_MODEM_COMMAND_RETRY = 113; private static final int EVENT_DATA_ENABLED_CHANGED = 114; // Depending on version of IRadioConfig, we need to send either RIL_REQUEST_ALLOW_DATA if it's // 1.0, or RIL_REQUEST_SET_PREFERRED_DATA if it's 1.1 or later. So internally mHalCommandToUse Loading Loading @@ -264,6 +265,21 @@ public class PhoneSwitcher extends Handler { if (mPhoneIdInVoiceCall != oldPhoneIdInVoiceCall) { log("mPhoneIdInVoiceCall changed from" + oldPhoneIdInVoiceCall + " to " + mPhoneIdInVoiceCall); // Switches and listens to the updated voice phone. Phone dataPhone = findPhoneById(mPhoneIdInVoiceCall); if (dataPhone != null && dataPhone.getDataEnabledSettings() != null) { dataPhone.getDataEnabledSettings() .registerForDataEnabledChanged(getInstance(), EVENT_DATA_ENABLED_CHANGED, null); } Phone oldDataPhone = findPhoneById(oldPhoneIdInVoiceCall); if (oldDataPhone != null && oldDataPhone.getDataEnabledSettings() != null) { oldDataPhone.getDataEnabledSettings() .unregisterForDataEnabledChanged(getInstance()); } Message msg = PhoneSwitcher.this.obtainMessage(EVENT_PHONE_IN_CALL_CHANGED); msg.sendToTarget(); } Loading Loading @@ -397,7 +413,9 @@ public class PhoneSwitcher extends Handler { onEvaluate(REQUESTS_UNCHANGED, "EVENT_RADIO_AVAILABLE"); break; } case EVENT_PHONE_IN_CALL_CHANGED: { // fall through case EVENT_DATA_ENABLED_CHANGED: case EVENT_PHONE_IN_CALL_CHANGED: if (onEvaluate(REQUESTS_UNCHANGED, "EVENT_PHONE_IN_CALL_CHANGED")) { logDataSwitchEvent(mOpptDataSubId, TelephonyEvent.EventState.EVENT_STATE_START, Loading @@ -405,7 +423,6 @@ public class PhoneSwitcher extends Handler { registerDefaultNetworkChangeCallback(); } break; } case EVENT_NETWORK_VALIDATION_DONE: { int subId = msg.arg1; boolean passed = (msg.arg2 == 1); Loading Loading @@ -770,15 +787,15 @@ public class PhoneSwitcher extends Handler { } } // This updates mPreferredDataPhoneId which decides which phone should // handle default network requests. // This updates mPreferredDataPhoneId which decides which phone should handle default network // requests. private void updatePreferredDataPhoneId() { if (SubscriptionManager.isValidPhoneId(mPhoneIdInVoiceCall)) { Phone voicePhone = findPhoneById(mPhoneIdInVoiceCall); if (voicePhone != null && voicePhone.isUserDataEnabled()) { // If a phone is in call and user enabled its mobile data, we // should switch internet connection to it. Because the other modem // will lose data connection anyway. // TODO: validate network first. mPreferredDataPhoneId = mPhoneIdInVoiceCall; } else { int subId = getSubIdForDefaultNetworkRequests(); Loading @@ -799,6 +816,13 @@ public class PhoneSwitcher extends Handler { mPreferredDataSubId = mSubscriptionController.getSubIdUsingPhoneId(mPreferredDataPhoneId); } private Phone findPhoneById(final int phoneId) { if (phoneId < 0 || phoneId >= mNumPhones) { return null; } return mPhones[phoneId]; } public boolean shouldApplyNetworkRequest(NetworkRequest networkRequest, int phoneId) { validatePhoneId(phoneId); Loading
src/java/com/android/internal/telephony/SubscriptionController.java +96 −17 Original line number Diff line number Diff line Loading @@ -39,6 +39,7 @@ import android.os.UserHandle; import android.provider.Settings; import android.telecom.PhoneAccountHandle; import android.telecom.TelecomManager; import android.telephony.CarrierConfigManager; import android.telephony.RadioAccessFamily; import android.telephony.Rlog; import android.telephony.SubscriptionInfo; Loading Loading @@ -100,6 +101,8 @@ public class SubscriptionController extends ISub.Stub { static final boolean DBG_CACHE = false; static final int MAX_LOCAL_LOG_LINES = 500; // TODO: Reduce to 100 when 17678050 is fixed private static final int DEPRECATED_SETTING = -1; private static final ParcelUuid INVALID_GROUP_UUID = ParcelUuid.fromString(CarrierConfigManager.REMOVE_GROUP_UUID_STRING); private ScLocalLog mLocalLog = new ScLocalLog(MAX_LOCAL_LOG_LINES); // Lock that both mCacheActiveSubInfoList and mCacheOpportunisticSubInfoList use. Loading Loading @@ -2793,6 +2796,8 @@ public class SubscriptionController extends ISub.Stub { * * @throws SecurityException if the caller doesn't meet the requirements * outlined above. * @throws IllegalArgumentException if the some subscriptions in the list doesn't exist. * @throws IllegalStateException if Telephony service is in bad state. * * @param subIdList list of subId that will be in the same group * @return groupUUID a UUID assigned to the subscription group. It returns Loading @@ -2802,15 +2807,15 @@ public class SubscriptionController extends ISub.Stub { @Override public ParcelUuid createSubscriptionGroup(int[] subIdList, String callingPackage) { if (subIdList == null || subIdList.length == 0) { return null; throw new IllegalArgumentException("Invalid subIdList " + subIdList); } // If it doesn't have modify phone state permission, or carrier privilege permission, // a SecurityException will be thrown. If it's due to invalid parameter or internal state, // it will return null. // a SecurityException will be thrown. if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.MODIFY_PHONE_STATE) != PERMISSION_GRANTED && !checkCarrierPrivilegeOnSubList( subIdList, callingPackage)) { return null; throw new SecurityException("CreateSubscriptionGroup needs MODIFY_PHONE_STATE or" + " carrier privilege permission on all specified subscriptions"); } long identity = Binder.clearCallingIdentity(); Loading @@ -2830,7 +2835,7 @@ public class SubscriptionController extends ISub.Stub { notifySubscriptionInfoChanged(); MultiSimSettingController.getInstance().onSubscriptionGroupCreated(subIdList); MultiSimSettingController.getInstance().onSubscriptionGroupChanged(groupUUID); return groupUUID; } finally { Loading @@ -2838,10 +2843,78 @@ public class SubscriptionController extends ISub.Stub { } } // TODO: when having a group owner or packageName for subscription, use that to check. // Currently for this method to return false, all subscriptions in the group needs to have // carrier privilege rules loaded, which means active or available. private boolean canPackageManageGroup(ParcelUuid groupUuid, String callingPackage) { if (groupUuid == null) { throw new IllegalArgumentException("Invalid groupUuid"); } List<SubscriptionInfo> infoList; // Getting all subscriptions in the group. long identity = Binder.clearCallingIdentity(); try { infoList = getSubInfo(SubscriptionManager.GROUP_UUID + "=\'" + groupUuid.toString() + "\'", null); } finally { Binder.restoreCallingIdentity(identity); } if (infoList == null || infoList.isEmpty()) { throw new IllegalArgumentException("No subscription in group " + groupUuid); } // Check carrier privilege for all subscriptions in the group. int[] subIdArray = infoList.stream().mapToInt(info -> info.getSubscriptionId()).toArray(); return checkCarrierPrivilegeOnSubList(subIdArray, callingPackage); } @Override public void addSubscriptionsIntoGroup(int[] subIdList, ParcelUuid groupUuid, String callingPackage) { // TODO: implement it. if (subIdList == null || subIdList.length == 0) { throw new IllegalArgumentException("Invalid subId list"); } if (groupUuid == null || groupUuid.equals(INVALID_GROUP_UUID)) { throw new IllegalArgumentException("Invalid groupUuid"); } // If it doesn't have modify phone state permission, or carrier privilege permission, // a SecurityException will be thrown. if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.MODIFY_PHONE_STATE) != PERMISSION_GRANTED && !(checkCarrierPrivilegeOnSubList(subIdList, callingPackage) && canPackageManageGroup(groupUuid, callingPackage))) { throw new SecurityException("Requires MODIFY_PHONE_STATE or carrier privilege" + " permissions on subscriptions and the group."); } long identity = Binder.clearCallingIdentity(); try { if (DBG) { logdl("addSubscriptionsIntoGroup sub list " + Arrays.toString(subIdList) + " into group " + groupUuid); } ContentValues value = new ContentValues(); value.put(SubscriptionManager.GROUP_UUID, groupUuid.toString()); int result = mContext.getContentResolver().update(SubscriptionManager.CONTENT_URI, value, getSelectionForSubIdList(subIdList), null); if (DBG) logdl("addSubscriptionsIntoGroup update DB result: " + result); if (result > 0) { refreshCachedActiveSubscriptionInfoList(); notifySubscriptionInfoChanged(); MultiSimSettingController.getInstance().onSubscriptionGroupChanged(groupUuid); } } finally { Binder.restoreCallingIdentity(identity); } } /** Loading Loading @@ -2872,7 +2945,8 @@ public class SubscriptionController extends ISub.Stub { if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.MODIFY_PHONE_STATE) != PERMISSION_GRANTED && !checkCarrierPrivilegeOnSubList( subIdList, callingPackage)) { return; throw new SecurityException("removeSubscriptionsFromGroup needs MODIFY_PHONE_STATE or" + " carrier privilege permission on all specified subscriptions"); } long identity = Binder.clearCallingIdentity(); Loading Loading @@ -2906,10 +2980,10 @@ public class SubscriptionController extends ISub.Stub { * The check can either be processed against access rules on currently active SIM cards, or * the access rules we keep in our database for currently inactive eSIMs. * * Throws {@link SecurityException} if it fails. * @throws IllegalArgumentException if the some subId is invalid or doesn't exist. * @throws IllegalStateException if Telephony is in bad state. * * @return true if checking passes on all subId. false if subId is invalid or doesn't exist, * or sub controller is not ready yet. * @return true if checking passes on all subId, false otherwise. */ private boolean checkCarrierPrivilegeOnSubList(int[] subIdList, String callingPackage) { mAppOps.checkPackage(Binder.getCallingUid(), callingPackage); Loading @@ -2920,7 +2994,7 @@ public class SubscriptionController extends ISub.Stub { for (int subId : subIdList) { if (isActiveSubId(subId)) { if (!mTelephonyManager.hasCarrierPrivileges(subId)) { throw new SecurityException("Need carrier privilege on subId " + subId); return false; } } else { checkSubList.add(subId); Loading @@ -2935,22 +3009,27 @@ public class SubscriptionController extends ISub.Stub { try { if (!isSubInfoReady()) { if (DBG) logdl("[getSubscriptionInfoList] Sub Controller not ready"); return false; throw new IllegalStateException("Sub Controller not ready"); } // Check access rules for each sub info. SubscriptionManager subscriptionManager = (SubscriptionManager) mContext.getSystemService(Context.TELEPHONY_SUBSCRIPTION_SERVICE); List<SubscriptionInfo> subList = getSubInfo(getSelectionForSubIdList(subIdList), null); for (SubscriptionInfo subInfo : subList) { List<SubscriptionInfo> subInfoList = getSubInfo( getSelectionForSubIdList(subIdList), null); // Didn't find all the subscriptions specified in subIdList. if (subInfoList == null || subInfoList.size() != subIdList.length) { throw new IllegalArgumentException("Invalid subInfoList."); } for (SubscriptionInfo subInfo : subInfoList) { if (checkSubList.contains(subInfo.getSubscriptionId())) { if (subInfo.isEmbedded() && subscriptionManager.canManageSubscription( subInfo, callingPackage)) { checkSubList.remove(subInfo.getSubscriptionId()); } else { throw new SecurityException("Need carrier privilege on subId " + subInfo.getSubscriptionId()); return false; } } } Loading
src/java/com/android/internal/telephony/SubscriptionInfoUpdater.java +1 −0 Original line number Diff line number Diff line Loading @@ -860,6 +860,7 @@ public class SubscriptionInfoUpdater extends Handler { .getUriForSubscriptionId(currentSubId), cv, null, null) > 0) { sc.refreshCachedActiveSubscriptionInfoList(); sc.notifySubscriptionInfoChanged(); MultiSimSettingController.getInstance().onSubscriptionGroupChanged(groupId); } } Loading