Synchronize onMultiSimConfigChanged with callback registrations.

TelephonyRegistry is susceptible to race conditions around
MULTI_SIM_CONFIG_CHANGED broadcast. When broadcast received, we'll
executing onMultiSimConfigChanged which may cause mNumPhones changed.
However, callback registrations at the same times might try to access
an already non-exist phoneId. Synchronize the whole
onMultiSimConfigChanged with callback registrations to avoid potential
race conditions.

Bug: 221080521
Test: TelephonyRegistryTest
Change-Id: I36a3d2a3d153cd68dd3ec18774d457dc32b00c82
This commit is contained in:
Grace Jia
2022-02-23 14:40:48 -08:00
parent 12dd1d6747
commit 869dc9cb1c

View File

@@ -651,100 +651,102 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub {
}
private void onMultiSimConfigChanged() {
int oldNumPhones = mNumPhones;
mNumPhones = getTelephonyManager().getActiveModemCount();
if (oldNumPhones == mNumPhones) return;
synchronized (mRecords) {
int oldNumPhones = mNumPhones;
mNumPhones = getTelephonyManager().getActiveModemCount();
if (oldNumPhones == mNumPhones) return;
if (DBG) {
log("TelephonyRegistry: activeModemCount changed from " + oldNumPhones
+ " to " + mNumPhones);
}
mCallState = copyOf(mCallState, mNumPhones);
mDataActivity = copyOf(mCallState, mNumPhones);
mDataConnectionState = copyOf(mCallState, mNumPhones);
mDataConnectionNetworkType = copyOf(mCallState, mNumPhones);
mCallIncomingNumber = copyOf(mCallIncomingNumber, mNumPhones);
mServiceState = copyOf(mServiceState, mNumPhones);
mVoiceActivationState = copyOf(mVoiceActivationState, mNumPhones);
mDataActivationState = copyOf(mDataActivationState, mNumPhones);
mUserMobileDataState = copyOf(mUserMobileDataState, mNumPhones);
if (mSignalStrength != null) {
mSignalStrength = copyOf(mSignalStrength, mNumPhones);
} else {
mSignalStrength = new SignalStrength[mNumPhones];
}
mMessageWaiting = copyOf(mMessageWaiting, mNumPhones);
mCallForwarding = copyOf(mCallForwarding, mNumPhones);
mCellIdentity = copyOf(mCellIdentity, mNumPhones);
mSrvccState = copyOf(mSrvccState, mNumPhones);
mPreciseCallState = copyOf(mPreciseCallState, mNumPhones);
mForegroundCallState = copyOf(mForegroundCallState, mNumPhones);
mBackgroundCallState = copyOf(mBackgroundCallState, mNumPhones);
mRingingCallState = copyOf(mRingingCallState, mNumPhones);
mCallDisconnectCause = copyOf(mCallDisconnectCause, mNumPhones);
mCallPreciseDisconnectCause = copyOf(mCallPreciseDisconnectCause, mNumPhones);
mCallQuality = copyOf(mCallQuality, mNumPhones);
mCallNetworkType = copyOf(mCallNetworkType, mNumPhones);
mCallAttributes = copyOf(mCallAttributes, mNumPhones);
mOutgoingCallEmergencyNumber = copyOf(mOutgoingCallEmergencyNumber, mNumPhones);
mOutgoingSmsEmergencyNumber = copyOf(mOutgoingSmsEmergencyNumber, mNumPhones);
mTelephonyDisplayInfos = copyOf(mTelephonyDisplayInfos, mNumPhones);
mCarrierNetworkChangeState = copyOf(mCarrierNetworkChangeState, mNumPhones);
mIsDataEnabled= copyOf(mIsDataEnabled, mNumPhones);
mDataEnabledReason = copyOf(mDataEnabledReason, mNumPhones);
mAllowedNetworkTypeReason = copyOf(mAllowedNetworkTypeReason, mNumPhones);
mAllowedNetworkTypeValue = copyOf(mAllowedNetworkTypeValue, mNumPhones);
if (DBG) {
log("TelephonyRegistry: activeModemCount changed from " + oldNumPhones
+ " to " + mNumPhones);
}
mCallState = copyOf(mCallState, mNumPhones);
mDataActivity = copyOf(mCallState, mNumPhones);
mDataConnectionState = copyOf(mCallState, mNumPhones);
mDataConnectionNetworkType = copyOf(mCallState, mNumPhones);
mCallIncomingNumber = copyOf(mCallIncomingNumber, mNumPhones);
mServiceState = copyOf(mServiceState, mNumPhones);
mVoiceActivationState = copyOf(mVoiceActivationState, mNumPhones);
mDataActivationState = copyOf(mDataActivationState, mNumPhones);
mUserMobileDataState = copyOf(mUserMobileDataState, mNumPhones);
if (mSignalStrength != null) {
mSignalStrength = copyOf(mSignalStrength, mNumPhones);
} else {
mSignalStrength = new SignalStrength[mNumPhones];
}
mMessageWaiting = copyOf(mMessageWaiting, mNumPhones);
mCallForwarding = copyOf(mCallForwarding, mNumPhones);
mCellIdentity = copyOf(mCellIdentity, mNumPhones);
mSrvccState = copyOf(mSrvccState, mNumPhones);
mPreciseCallState = copyOf(mPreciseCallState, mNumPhones);
mForegroundCallState = copyOf(mForegroundCallState, mNumPhones);
mBackgroundCallState = copyOf(mBackgroundCallState, mNumPhones);
mRingingCallState = copyOf(mRingingCallState, mNumPhones);
mCallDisconnectCause = copyOf(mCallDisconnectCause, mNumPhones);
mCallPreciseDisconnectCause = copyOf(mCallPreciseDisconnectCause, mNumPhones);
mCallQuality = copyOf(mCallQuality, mNumPhones);
mCallNetworkType = copyOf(mCallNetworkType, mNumPhones);
mCallAttributes = copyOf(mCallAttributes, mNumPhones);
mOutgoingCallEmergencyNumber = copyOf(mOutgoingCallEmergencyNumber, mNumPhones);
mOutgoingSmsEmergencyNumber = copyOf(mOutgoingSmsEmergencyNumber, mNumPhones);
mTelephonyDisplayInfos = copyOf(mTelephonyDisplayInfos, mNumPhones);
mCarrierNetworkChangeState = copyOf(mCarrierNetworkChangeState, mNumPhones);
mIsDataEnabled = copyOf(mIsDataEnabled, mNumPhones);
mDataEnabledReason = copyOf(mDataEnabledReason, mNumPhones);
mAllowedNetworkTypeReason = copyOf(mAllowedNetworkTypeReason, mNumPhones);
mAllowedNetworkTypeValue = copyOf(mAllowedNetworkTypeValue, mNumPhones);
// ds -> ss switch.
if (mNumPhones < oldNumPhones) {
cutListToSize(mCellInfo, mNumPhones);
cutListToSize(mImsReasonInfo, mNumPhones);
cutListToSize(mPreciseDataConnectionStates, mNumPhones);
cutListToSize(mBarringInfo, mNumPhones);
cutListToSize(mPhysicalChannelConfigs, mNumPhones);
cutListToSize(mLinkCapacityEstimateLists, mNumPhones);
cutListToSize(mCarrierPrivilegeStates, mNumPhones);
return;
}
// ds -> ss switch.
if (mNumPhones < oldNumPhones) {
cutListToSize(mCellInfo, mNumPhones);
cutListToSize(mImsReasonInfo, mNumPhones);
cutListToSize(mPreciseDataConnectionStates, mNumPhones);
cutListToSize(mBarringInfo, mNumPhones);
cutListToSize(mPhysicalChannelConfigs, mNumPhones);
cutListToSize(mLinkCapacityEstimateLists, mNumPhones);
cutListToSize(mCarrierPrivilegeStates, mNumPhones);
return;
}
// mNumPhones > oldNumPhones: ss -> ds switch
for (int i = oldNumPhones; i < mNumPhones; i++) {
mCallState[i] = TelephonyManager.CALL_STATE_IDLE;
mDataActivity[i] = TelephonyManager.DATA_ACTIVITY_NONE;
mDataConnectionState[i] = TelephonyManager.DATA_UNKNOWN;
mVoiceActivationState[i] = TelephonyManager.SIM_ACTIVATION_STATE_UNKNOWN;
mDataActivationState[i] = TelephonyManager.SIM_ACTIVATION_STATE_UNKNOWN;
mCallIncomingNumber[i] = "";
mServiceState[i] = new ServiceState();
mSignalStrength[i] = null;
mUserMobileDataState[i] = false;
mMessageWaiting[i] = false;
mCallForwarding[i] = false;
mCellIdentity[i] = null;
mCellInfo.add(i, null);
mImsReasonInfo.add(i, null);
mSrvccState[i] = TelephonyManager.SRVCC_STATE_HANDOVER_NONE;
mCallDisconnectCause[i] = DisconnectCause.NOT_VALID;
mCallPreciseDisconnectCause[i] = PreciseDisconnectCause.NOT_VALID;
mCallQuality[i] = createCallQuality();
mCallAttributes[i] = new CallAttributes(createPreciseCallState(),
TelephonyManager.NETWORK_TYPE_UNKNOWN, createCallQuality());
mCallNetworkType[i] = TelephonyManager.NETWORK_TYPE_UNKNOWN;
mPreciseCallState[i] = createPreciseCallState();
mRingingCallState[i] = PreciseCallState.PRECISE_CALL_STATE_IDLE;
mForegroundCallState[i] = PreciseCallState.PRECISE_CALL_STATE_IDLE;
mBackgroundCallState[i] = PreciseCallState.PRECISE_CALL_STATE_IDLE;
mPreciseDataConnectionStates.add(new ArrayMap<>());
mBarringInfo.add(i, new BarringInfo());
mCarrierNetworkChangeState[i] = false;
mTelephonyDisplayInfos[i] = null;
mIsDataEnabled[i] = false;
mDataEnabledReason[i] = TelephonyManager.DATA_ENABLED_REASON_USER;
mPhysicalChannelConfigs.add(i, new ArrayList<>());
mAllowedNetworkTypeReason[i] = -1;
mAllowedNetworkTypeValue[i] = -1;
mLinkCapacityEstimateLists.add(i, INVALID_LCE_LIST);
mCarrierPrivilegeStates.add(i, new Pair<>(Collections.emptyList(), new int[0]));
// mNumPhones > oldNumPhones: ss -> ds switch
for (int i = oldNumPhones; i < mNumPhones; i++) {
mCallState[i] = TelephonyManager.CALL_STATE_IDLE;
mDataActivity[i] = TelephonyManager.DATA_ACTIVITY_NONE;
mDataConnectionState[i] = TelephonyManager.DATA_UNKNOWN;
mVoiceActivationState[i] = TelephonyManager.SIM_ACTIVATION_STATE_UNKNOWN;
mDataActivationState[i] = TelephonyManager.SIM_ACTIVATION_STATE_UNKNOWN;
mCallIncomingNumber[i] = "";
mServiceState[i] = new ServiceState();
mSignalStrength[i] = null;
mUserMobileDataState[i] = false;
mMessageWaiting[i] = false;
mCallForwarding[i] = false;
mCellIdentity[i] = null;
mCellInfo.add(i, null);
mImsReasonInfo.add(i, null);
mSrvccState[i] = TelephonyManager.SRVCC_STATE_HANDOVER_NONE;
mCallDisconnectCause[i] = DisconnectCause.NOT_VALID;
mCallPreciseDisconnectCause[i] = PreciseDisconnectCause.NOT_VALID;
mCallQuality[i] = createCallQuality();
mCallAttributes[i] = new CallAttributes(createPreciseCallState(),
TelephonyManager.NETWORK_TYPE_UNKNOWN, createCallQuality());
mCallNetworkType[i] = TelephonyManager.NETWORK_TYPE_UNKNOWN;
mPreciseCallState[i] = createPreciseCallState();
mRingingCallState[i] = PreciseCallState.PRECISE_CALL_STATE_IDLE;
mForegroundCallState[i] = PreciseCallState.PRECISE_CALL_STATE_IDLE;
mBackgroundCallState[i] = PreciseCallState.PRECISE_CALL_STATE_IDLE;
mPreciseDataConnectionStates.add(new ArrayMap<>());
mBarringInfo.add(i, new BarringInfo());
mCarrierNetworkChangeState[i] = false;
mTelephonyDisplayInfos[i] = null;
mIsDataEnabled[i] = false;
mDataEnabledReason[i] = TelephonyManager.DATA_ENABLED_REASON_USER;
mPhysicalChannelConfigs.add(i, new ArrayList<>());
mAllowedNetworkTypeReason[i] = -1;
mAllowedNetworkTypeValue[i] = -1;
mLinkCapacityEstimateLists.add(i, INVALID_LCE_LIST);
mCarrierPrivilegeStates.add(i, new Pair<>(Collections.emptyList(), new int[0]));
}
}
}
@@ -2802,11 +2804,11 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub {
+ " callback=" + callback
+ " callback.asBinder=" + callback.asBinder());
}
if (!validatePhoneId(phoneId)) {
throw new IllegalArgumentException("Invalid slot index: " + phoneId);
}
synchronized (mRecords) {
if (!validatePhoneId(phoneId)) {
throw new IllegalArgumentException("Invalid slot index: " + phoneId);
}
Record r = add(
callback.asBinder(), Binder.getCallingUid(), Binder.getCallingPid(), false);
@@ -2851,7 +2853,6 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub {
if (!checkNotifyPermission("notifyCarrierPrivilegesChanged")) {
return;
}
if (!validatePhoneId(phoneId)) return;
if (VDBG) {
log(
"notifyCarrierPrivilegesChanged: phoneId=" + phoneId
@@ -2859,6 +2860,9 @@ public class TelephonyRegistry extends ITelephonyRegistry.Stub {
+ ", uids=" + Arrays.toString(privilegedUids) + ">");
}
synchronized (mRecords) {
if (!validatePhoneId(phoneId)) {
throw new IllegalArgumentException("Invalid slot index: " + phoneId);
}
mCarrierPrivilegeStates.set(
phoneId, new Pair<>(privilegedPackageNames, privilegedUids));
for (Record r : mRecords) {