Loading flags/telephony.aconfig +15 −1 Original line number Diff line number Diff line Loading @@ -27,3 +27,17 @@ flag { description: "This flag prevents repeat invocation of call related APIs in RIL when the device is not voice capable" bug: "290833783" } flag { name: "minimal_telephony_cdm_check" namespace: "telephony" description: "This flag disables Calling/Data/Messaging features if their respective feature is missing" bug: "310710841" } flag { name: "minimal_telephony_managers_conditional_on_features" namespace: "telephony" description: "This flag enables checking for telephony features before initializing corresponding managers" bug: "310710841" } src/java/com/android/internal/telephony/GsmCdmaCallTracker.java +8 −1 Original line number Diff line number Diff line Loading @@ -21,6 +21,7 @@ import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.content.pm.PackageManager; import android.os.AsyncResult; import android.os.Build; import android.os.Bundle; Loading Loading @@ -159,6 +160,12 @@ public class GsmCdmaCallTracker extends CallTracker { public GsmCdmaCallTracker(GsmCdmaPhone phone, FeatureFlags featureFlags) { super(featureFlags); if (mFeatureFlags.minimalTelephonyCdmCheck() && !phone.getContext().getPackageManager().hasSystemFeature( PackageManager.FEATURE_TELEPHONY_CALLING)) { throw new UnsupportedOperationException("GsmCdmaCallTracker requires calling"); } this.mPhone = phone; mCi = phone.mCi; mCi.registerForCallStateChanged(this, EVENT_CALL_STATE_CHANGE, null); Loading Loading @@ -1492,7 +1499,7 @@ public class GsmCdmaCallTracker extends CallTracker { switch (msg.what) { case EVENT_POLL_CALLS_RESULT: Rlog.d(LOG_TAG, "Event EVENT_POLL_CALLS_RESULT Received"); if (DBG_POLL) Rlog.d(LOG_TAG, "Event EVENT_POLL_CALLS_RESULT Received"); if (msg == mLastRelevantPoll) { if (DBG_POLL) log( Loading src/java/com/android/internal/telephony/GsmCdmaPhone.java +51 −17 Original line number Diff line number Diff line Loading @@ -42,6 +42,7 @@ import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.content.SharedPreferences; import android.content.pm.PackageManager; import android.database.SQLException; import android.hardware.radio.modem.ImeiInfo; import android.net.Uri; Loading Loading @@ -370,9 +371,11 @@ public class GsmCdmaPhone extends Phone { SignalStrengthController.class.getName()).makeSignalStrengthController(this); mSST = mTelephonyComponentFactory.inject(ServiceStateTracker.class.getName()) .makeServiceStateTracker(this, this.mCi, featureFlags); if (hasCalling()) { mEmergencyNumberTracker = mTelephonyComponentFactory .inject(EmergencyNumberTracker.class.getName()).makeEmergencyNumberTracker( this, this.mCi); this, this.mCi, mFeatureFlags); } mDeviceStateMonitor = mTelephonyComponentFactory.inject(DeviceStateMonitor.class.getName()) .makeDeviceStateMonitor(this, mFeatureFlags); Loading Loading @@ -412,9 +415,11 @@ public class GsmCdmaPhone extends Phone { mCallWaitingController = new CallWaitingController(this); if (hasCalling()) { loadTtyMode(); CallManager.getInstance().registerPhone(this); } mSubscriptionsChangedListener = new SubscriptionManager.OnSubscriptionsChangedListener() { Loading Loading @@ -464,13 +469,21 @@ public class GsmCdmaPhone extends Phone { } }; private boolean hasCalling() { if (!mFeatureFlags.minimalTelephonyCdmCheck()) return true; return mContext.getPackageManager().hasSystemFeature( PackageManager.FEATURE_TELEPHONY_CALLING); } private void initOnce(CommandsInterface ci) { if (ci instanceof SimulatedRadioControl) { mSimulatedRadioControl = (SimulatedRadioControl) ci; } if (hasCalling()) { mCT = mTelephonyComponentFactory.inject(GsmCdmaCallTracker.class.getName()) .makeGsmCdmaCallTracker(this, mFeatureFlags); } mIccPhoneBookIntManager = mTelephonyComponentFactory .inject(IccPhoneBookInterfaceManager.class.getName()) .makeIccPhoneBookInterfaceManager(this); Loading Loading @@ -693,7 +706,7 @@ public class GsmCdmaPhone extends Phone { unregisterForIccRecordEvents(); registerForIccRecordEvents(); mCT.updatePhoneType(); if (mCT != null) mCT.updatePhoneType(); int radioState = mCi.getRadioState(); if (radioState != TelephonyManager.RADIO_POWER_UNAVAILABLE) { Loading Loading @@ -753,6 +766,8 @@ public class GsmCdmaPhone extends Phone { @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) @Override public PhoneConstants.State getState() { if (!hasCalling()) return PhoneConstants.State.IDLE; if (mImsPhone != null) { PhoneConstants.State imsState = mImsPhone.getState(); if (imsState != PhoneConstants.State.IDLE) { Loading Loading @@ -837,6 +852,7 @@ public class GsmCdmaPhone extends Phone { @Override public boolean isDataSuspended() { if (mCT == null) return false; return mCT.mState != PhoneConstants.State.IDLE && !mSST.isConcurrentVoiceAndDataAllowed(); } Loading Loading @@ -884,7 +900,7 @@ public class GsmCdmaPhone extends Phone { @Override public boolean isInEmergencyCall() { if (isPhoneTypeGsm()) { if (!hasCalling() || isPhoneTypeGsm()) { return false; } else { return mCT.isInEmergencyCall(); Loading @@ -893,7 +909,7 @@ public class GsmCdmaPhone extends Phone { @Override protected void setIsInEmergencyCall() { if (!isPhoneTypeGsm()) { if (!hasCalling() && !isPhoneTypeGsm()) { mCT.setIsInEmergencyCall(); } } Loading Loading @@ -985,6 +1001,7 @@ public class GsmCdmaPhone extends Phone { @Override public void acceptCall(int videoState) throws CallStateException { if (!hasCalling()) throw new CallStateException(); Phone imsPhone = mImsPhone; if ( imsPhone != null && imsPhone.getRingingCall().isRinging() ) { imsPhone.acceptCall(videoState); Loading @@ -995,6 +1012,7 @@ public class GsmCdmaPhone extends Phone { @Override public void rejectCall() throws CallStateException { if (!hasCalling()) throw new CallStateException(); mCT.rejectCall(); } Loading Loading @@ -1025,6 +1043,7 @@ public class GsmCdmaPhone extends Phone { @Override public boolean canConference() { if (!hasCalling()) return false; if (mImsPhone != null && mImsPhone.canConference()) { return true; } Loading Loading @@ -1075,12 +1094,13 @@ public class GsmCdmaPhone extends Phone { @Override public void clearDisconnected() { if (!hasCalling()) return; mCT.clearDisconnected(); } @Override public boolean canTransfer() { if (isPhoneTypeGsm()) { if (hasCalling() && isPhoneTypeGsm()) { return mCT.canTransfer(); } else { loge("canTransfer: not possible in CDMA"); Loading @@ -1090,7 +1110,7 @@ public class GsmCdmaPhone extends Phone { @Override public void explicitCallTransfer() { if (isPhoneTypeGsm()) { if (hasCalling() && isPhoneTypeGsm()) { mCT.explicitCallTransfer(); } else { loge("explicitCallTransfer: not possible in CDMA"); Loading @@ -1104,11 +1124,13 @@ public class GsmCdmaPhone extends Phone { @Override public GsmCdmaCall getBackgroundCall() { if (!hasCalling()) return null; return mCT.mBackgroundCall; } @Override public Call getRingingCall() { if (!hasCalling()) return null; Phone imsPhone = mImsPhone; // It returns the ringing call of ImsPhone if the ringing call of GSMPhone isn't ringing. // In CallManager.registerPhone(), it always registers ringing call of ImsPhone, because Loading Loading @@ -1184,7 +1206,7 @@ public class GsmCdmaPhone extends Phone { private boolean handleCallDeflectionIncallSupplementaryService( String dialString) { if (dialString.length() > 1) { if (!hasCalling() || dialString.length() > 1) { return false; } Loading @@ -1209,7 +1231,7 @@ public class GsmCdmaPhone extends Phone { private boolean handleCallWaitingIncallSupplementaryService(String dialString) { int len = dialString.length(); if (len > 2) { if (!hasCalling() || len > 2) { return false; } Loading Loading @@ -1429,6 +1451,9 @@ public class GsmCdmaPhone extends Phone { @Override public Connection dial(String dialString, @NonNull DialArgs dialArgs, Consumer<Phone> chosenPhoneConsumer) throws CallStateException { if (!hasCalling()) { throw new CallStateException("Calling feature is not supported!"); } if (!isPhoneTypeGsm() && dialArgs.uusInfo != null) { throw new CallStateException("Sending UUS information NOT supported in CDMA!"); } Loading Loading @@ -2148,7 +2173,9 @@ public class GsmCdmaPhone extends Phone { @Override public int getEmergencyNumberDbVersion() { return getEmergencyNumberTracker().getEmergencyNumberDbVersion(); EmergencyNumberTracker tracker = getEmergencyNumberTracker(); if (tracker == null) return -1; return tracker.getEmergencyNumberDbVersion(); } @Override Loading Loading @@ -3134,6 +3161,8 @@ public class GsmCdmaPhone extends Phone { */ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private void syncClirSetting() { if (!hasCalling()) return; SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getContext()); migrateClirSettingIfNeeded(sp); Loading Loading @@ -3339,8 +3368,10 @@ public class GsmCdmaPhone extends Phone { if (b != null) { updateBroadcastEmergencyCallStateChangesAfterCarrierConfigChanged(b); updateCdmaRoamingSettingsAfterCarrierConfigChanged(b); if (hasCalling()) { updateNrSettingsAfterCarrierConfigChanged(b); updateVoNrSettings(b); } updateSsOverCdmaSupported(b); updateCarrierN1ModeSupported(b); } else { Loading Loading @@ -4912,6 +4943,7 @@ public class GsmCdmaPhone extends Phone { * Handler of RIL Voice Radio Technology changed event. */ private void onVoiceRegStateOrRatChanged(int vrs, int vrat) { if (!hasCalling()) return; logd("onVoiceRegStateOrRatChanged"); mCT.dispatchCsCallRadioTech(getCsCallRadioTech(vrs, vrat)); } Loading Loading @@ -5113,6 +5145,8 @@ public class GsmCdmaPhone extends Phone { * Load the current TTY mode in GsmCdmaPhone based on Telecom and UI settings. */ private void loadTtyMode() { if (!hasCalling()) return; int ttyMode = TelecomManager.TTY_MODE_OFF; TelecomManager telecomManager = mContext.getSystemService(TelecomManager.class); if (telecomManager != null) { Loading src/java/com/android/internal/telephony/MultiSimSettingController.java +65 −32 Original line number Diff line number Diff line Loading @@ -35,6 +35,7 @@ import android.annotation.NonNull; import android.app.PendingIntent; import android.content.Context; import android.content.Intent; import android.content.pm.PackageManager; import android.os.AsyncResult; import android.os.Handler; import android.os.Looper; Loading @@ -52,6 +53,7 @@ import android.util.Log; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.telephony.data.DataSettingsManager.DataSettingsManagerCallback; import com.android.internal.telephony.flags.FeatureFlags; import com.android.internal.telephony.subscription.SubscriptionInfoInternal; import com.android.internal.telephony.subscription.SubscriptionManagerService; import com.android.internal.telephony.util.ArrayUtils; Loading Loading @@ -122,6 +124,7 @@ public class MultiSimSettingController extends Handler { protected final Context mContext; private final SubscriptionManagerService mSubscriptionManagerService; private final @NonNull FeatureFlags mFeatureFlags; // Keep a record of active primary (non-opportunistic) subscription list. @NonNull private List<Integer> mPrimarySubList = new ArrayList<>(); Loading Loading @@ -201,10 +204,11 @@ public class MultiSimSettingController extends Handler { /** * Init instance of MultiSimSettingController. */ public static MultiSimSettingController init(Context context) { public static MultiSimSettingController init(Context context, @NonNull FeatureFlags featureFlags) { synchronized (MultiSimSettingController.class) { if (sInstance == null) { sInstance = new MultiSimSettingController(context); sInstance = new MultiSimSettingController(context, featureFlags); } else { Log.wtf(LOG_TAG, "init() called multiple times! sInstance = " + sInstance); } Loading @@ -213,9 +217,10 @@ public class MultiSimSettingController extends Handler { } @VisibleForTesting public MultiSimSettingController(Context context) { public MultiSimSettingController(Context context, @NonNull FeatureFlags featureFlags) { mContext = context; mSubscriptionManagerService = SubscriptionManagerService.getInstance(); mFeatureFlags = featureFlags; // Initialize mCarrierConfigLoadedSubIds and register to listen to carrier config change. TelephonyManager telephonyManager = ((TelephonyManager) mContext.getSystemService( Loading @@ -239,6 +244,24 @@ public class MultiSimSettingController extends Handler { onCarrierConfigChanged(slotIndex, subId)); } private boolean hasCalling() { if (!mFeatureFlags.minimalTelephonyCdmCheck()) return true; return mContext.getPackageManager().hasSystemFeature( PackageManager.FEATURE_TELEPHONY_CALLING); } private boolean hasData() { if (!mFeatureFlags.minimalTelephonyCdmCheck()) return true; return mContext.getPackageManager().hasSystemFeature( PackageManager.FEATURE_TELEPHONY_DATA); } private boolean hasMessaging() { if (!mFeatureFlags.minimalTelephonyCdmCheck()) return true; return mContext.getPackageManager().hasSystemFeature( PackageManager.FEATURE_TELEPHONY_MESSAGING); } /** * Notify MOBILE_DATA of a subscription is changed. */ Loading Loading @@ -606,35 +629,43 @@ public class MultiSimSettingController extends Handler { || mActiveModemCount == 1)) { int subId = mPrimarySubList.get(0); if (DBG) log("updateDefaultValues: to only primary sub " + subId); mSubscriptionManagerService.setDefaultDataSubId(subId); mSubscriptionManagerService.setDefaultVoiceSubId(subId); mSubscriptionManagerService.setDefaultSmsSubId(subId); if (hasData()) mSubscriptionManagerService.setDefaultDataSubId(subId); if (hasCalling()) mSubscriptionManagerService.setDefaultVoiceSubId(subId); if (hasMessaging()) mSubscriptionManagerService.setDefaultSmsSubId(subId); sendDefaultSubConfirmedNotification(subId); return; } if (DBG) log("updateDefaultValues: records: " + mPrimarySubList); boolean dataSelected, voiceSelected, smsSelected; boolean dataSelected = false; boolean voiceSelected = false; boolean smsSelected = false; if (hasData()) { // Update default data subscription. if (DBG) log("updateDefaultValues: Update default data subscription"); dataSelected = updateDefaultValue(mPrimarySubList, mSubscriptionManagerService.getDefaultDataSubId(), mSubscriptionManagerService::setDefaultDataSubId); } if (hasCalling()) { // Update default voice subscription. if (DBG) log("updateDefaultValues: Update default voice subscription"); voiceSelected = updateDefaultValue(mPrimarySubList, mSubscriptionManagerService.getDefaultVoiceSubId(), mSubscriptionManagerService::setDefaultVoiceSubId); } if (hasMessaging()) { // Update default sms subscription. if (DBG) log("updateDefaultValues: Update default sms subscription"); smsSelected = updateDefaultValue(mPrimarySubList, mSubscriptionManagerService.getDefaultSmsSubId(), mSubscriptionManagerService::setDefaultSmsSubId, mIsAskEverytimeSupportedForSms); } boolean autoFallbackEnabled = mContext.getResources().getBoolean( com.android.internal.R.bool.config_voice_data_sms_auto_fallback); Loading Loading @@ -1023,11 +1054,11 @@ public class MultiSimSettingController extends Handler { int autoDefaultSubId = primarySubList.get(0); if ((primarySubList.size() == 1) && !smsSelected) { if (hasMessaging() && (primarySubList.size() == 1) && !smsSelected) { mSubscriptionManagerService.setDefaultSmsSubId(autoDefaultSubId); } if ((primarySubList.size() == 1) && !voiceSelected) { if (hasCalling() && (primarySubList.size() == 1) && !voiceSelected) { mSubscriptionManagerService.setDefaultVoiceSubId(autoDefaultSubId); } Loading @@ -1036,6 +1067,7 @@ public class MultiSimSettingController extends Handler { log("User pref subId = " + userPrefDataSubId + " current dds " + defaultDataSubId + " next active subId " + autoDefaultSubId); if (hasData()) { // If earlier user selected DDS is now available, set that as DDS subId. if (primarySubList.contains(userPrefDataSubId) && SubscriptionManager.isValidSubscriptionId(userPrefDataSubId) Loading @@ -1044,6 +1076,7 @@ public class MultiSimSettingController extends Handler { } else if (!dataSelected) { mSubscriptionManagerService.setDefaultDataSubId(autoDefaultSubId); } } if (DBG) { log("updateUserPreferences: after dds = " Loading src/java/com/android/internal/telephony/NetworkTypeController.java +33 −1 Original line number Diff line number Diff line Loading @@ -26,6 +26,7 @@ import android.os.AsyncResult; import android.os.Message; import android.os.PersistableBundle; import android.os.PowerManager; import android.os.SystemClock; import android.telephony.AccessNetworkConstants; import android.telephony.Annotation; import android.telephony.CarrierConfigManager; Loading Loading @@ -194,6 +195,7 @@ public class NetworkTypeController extends StateMachine { private boolean mIsPhysicalChannelConfigOn; private boolean mIsPrimaryTimerActive; private boolean mIsSecondaryTimerActive; private long mSecondaryTimerExpireTimestamp; private boolean mIsTimerResetEnabledForLegacyStateRrcIdle; /** Carrier config to reset timers when mccmnc changes */ private boolean mIsTimerResetEnabledOnPlmnChanges; Loading @@ -220,6 +222,7 @@ public class NetworkTypeController extends StateMachine { // Cached copies below to prevent race conditions @NonNull private ServiceState mServiceState; /** Used to track link status to be DORMANT or ACTIVE */ @Nullable private List<PhysicalChannelConfig> mPhysicalChannelConfigs; // Ratchet physical channel config fields to prevent 5G/5G+ flickering Loading Loading @@ -666,6 +669,7 @@ public class NetworkTypeController extends StateMachine { case EVENT_SECONDARY_TIMER_EXPIRED: if (DBG) log("Secondary timer expired for state: " + mSecondaryTimerState); mIsSecondaryTimerActive = false; mSecondaryTimerExpireTimestamp = 0; mSecondaryTimerState = ""; updateTimers(); mLastShownNrDueToAdvancedBand = false; Loading Loading @@ -1251,6 +1255,8 @@ public class NetworkTypeController extends StateMachine { private void updatePhysicalChannelConfigs(List<PhysicalChannelConfig> physicalChannelConfigs) { boolean isPccListEmpty = physicalChannelConfigs == null || physicalChannelConfigs.isEmpty(); if (isPccListEmpty && isUsingPhysicalChannelConfigForRrcDetection()) { // Clear mPrimaryCellChangedWhileIdle to allow later potential one-off PCI change. // Update link status to be DORMANT, but keep ratcheted bands. log("Physical channel configs updated: not updating PCC fields for empty PCC list " + "indicating RRC idle."); mPrimaryCellChangedWhileIdle = false; Loading Loading @@ -1310,6 +1316,7 @@ public class NetworkTypeController extends StateMachine { + mLastAnchorNrCellId + " -> " + anchorNrCellId); mPrimaryCellChangedWhileIdle = true; mLastAnchorNrCellId = anchorNrCellId; reduceSecondaryTimerIfNeeded(); return; } if (mRatchetPccFieldsForSameAnchorNrCell) { Loading @@ -1330,6 +1337,27 @@ public class NetworkTypeController extends StateMachine { } } /** * Called when PCI change, specifically during idle state. */ private void reduceSecondaryTimerIfNeeded() { if (!mIsSecondaryTimerActive || mNrAdvancedBandsSecondaryTimer <= 0) return; // Secondary timer is active, so we must have a valid secondary rule right now. OverrideTimerRule secondaryRule = mOverrideTimerRules.get(mPrimaryTimerState); if (secondaryRule != null) { int secondaryDuration = secondaryRule.getSecondaryTimer(mSecondaryTimerState); long durationMillis = secondaryDuration * 1000L; if ((mSecondaryTimerExpireTimestamp - SystemClock.uptimeMillis()) > durationMillis) { if (DBG) log("Due to PCI change, reduce the secondary timer to " + durationMillis); removeMessages(EVENT_SECONDARY_TIMER_EXPIRED); sendMessageDelayed(EVENT_SECONDARY_TIMER_EXPIRED, mSecondaryTimerState, durationMillis); } } else { loge("!! Secondary timer is active, but found no rule for " + mPrimaryTimerState); } } private void transitionWithTimerTo(IState destState) { String destName = destState.getName(); if (mIsPrimaryTimerActive) { Loading Loading @@ -1369,7 +1397,9 @@ public class NetworkTypeController extends StateMachine { mSecondaryTimerState = currentName; mPreviousState = currentName; mIsSecondaryTimerActive = true; sendMessageDelayed(EVENT_SECONDARY_TIMER_EXPIRED, destState, duration * 1000L); long durationMillis = duration * 1000L; mSecondaryTimerExpireTimestamp = SystemClock.uptimeMillis() + durationMillis; sendMessageDelayed(EVENT_SECONDARY_TIMER_EXPIRED, destState, durationMillis); } mIsPrimaryTimerActive = false; transitionTo(getCurrentState()); Loading Loading @@ -1434,6 +1464,7 @@ public class NetworkTypeController extends StateMachine { } removeMessages(EVENT_SECONDARY_TIMER_EXPIRED); mIsSecondaryTimerActive = false; mSecondaryTimerExpireTimestamp = 0; mSecondaryTimerState = ""; transitionToCurrentState(); return; Loading Loading @@ -1464,6 +1495,7 @@ public class NetworkTypeController extends StateMachine { removeMessages(EVENT_SECONDARY_TIMER_EXPIRED); mIsPrimaryTimerActive = false; mIsSecondaryTimerActive = false; mSecondaryTimerExpireTimestamp = 0; mPrimaryTimerState = ""; mSecondaryTimerState = ""; Loading Loading
flags/telephony.aconfig +15 −1 Original line number Diff line number Diff line Loading @@ -27,3 +27,17 @@ flag { description: "This flag prevents repeat invocation of call related APIs in RIL when the device is not voice capable" bug: "290833783" } flag { name: "minimal_telephony_cdm_check" namespace: "telephony" description: "This flag disables Calling/Data/Messaging features if their respective feature is missing" bug: "310710841" } flag { name: "minimal_telephony_managers_conditional_on_features" namespace: "telephony" description: "This flag enables checking for telephony features before initializing corresponding managers" bug: "310710841" }
src/java/com/android/internal/telephony/GsmCdmaCallTracker.java +8 −1 Original line number Diff line number Diff line Loading @@ -21,6 +21,7 @@ import android.content.BroadcastReceiver; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.content.pm.PackageManager; import android.os.AsyncResult; import android.os.Build; import android.os.Bundle; Loading Loading @@ -159,6 +160,12 @@ public class GsmCdmaCallTracker extends CallTracker { public GsmCdmaCallTracker(GsmCdmaPhone phone, FeatureFlags featureFlags) { super(featureFlags); if (mFeatureFlags.minimalTelephonyCdmCheck() && !phone.getContext().getPackageManager().hasSystemFeature( PackageManager.FEATURE_TELEPHONY_CALLING)) { throw new UnsupportedOperationException("GsmCdmaCallTracker requires calling"); } this.mPhone = phone; mCi = phone.mCi; mCi.registerForCallStateChanged(this, EVENT_CALL_STATE_CHANGE, null); Loading Loading @@ -1492,7 +1499,7 @@ public class GsmCdmaCallTracker extends CallTracker { switch (msg.what) { case EVENT_POLL_CALLS_RESULT: Rlog.d(LOG_TAG, "Event EVENT_POLL_CALLS_RESULT Received"); if (DBG_POLL) Rlog.d(LOG_TAG, "Event EVENT_POLL_CALLS_RESULT Received"); if (msg == mLastRelevantPoll) { if (DBG_POLL) log( Loading
src/java/com/android/internal/telephony/GsmCdmaPhone.java +51 −17 Original line number Diff line number Diff line Loading @@ -42,6 +42,7 @@ import android.content.Context; import android.content.Intent; import android.content.IntentFilter; import android.content.SharedPreferences; import android.content.pm.PackageManager; import android.database.SQLException; import android.hardware.radio.modem.ImeiInfo; import android.net.Uri; Loading Loading @@ -370,9 +371,11 @@ public class GsmCdmaPhone extends Phone { SignalStrengthController.class.getName()).makeSignalStrengthController(this); mSST = mTelephonyComponentFactory.inject(ServiceStateTracker.class.getName()) .makeServiceStateTracker(this, this.mCi, featureFlags); if (hasCalling()) { mEmergencyNumberTracker = mTelephonyComponentFactory .inject(EmergencyNumberTracker.class.getName()).makeEmergencyNumberTracker( this, this.mCi); this, this.mCi, mFeatureFlags); } mDeviceStateMonitor = mTelephonyComponentFactory.inject(DeviceStateMonitor.class.getName()) .makeDeviceStateMonitor(this, mFeatureFlags); Loading Loading @@ -412,9 +415,11 @@ public class GsmCdmaPhone extends Phone { mCallWaitingController = new CallWaitingController(this); if (hasCalling()) { loadTtyMode(); CallManager.getInstance().registerPhone(this); } mSubscriptionsChangedListener = new SubscriptionManager.OnSubscriptionsChangedListener() { Loading Loading @@ -464,13 +469,21 @@ public class GsmCdmaPhone extends Phone { } }; private boolean hasCalling() { if (!mFeatureFlags.minimalTelephonyCdmCheck()) return true; return mContext.getPackageManager().hasSystemFeature( PackageManager.FEATURE_TELEPHONY_CALLING); } private void initOnce(CommandsInterface ci) { if (ci instanceof SimulatedRadioControl) { mSimulatedRadioControl = (SimulatedRadioControl) ci; } if (hasCalling()) { mCT = mTelephonyComponentFactory.inject(GsmCdmaCallTracker.class.getName()) .makeGsmCdmaCallTracker(this, mFeatureFlags); } mIccPhoneBookIntManager = mTelephonyComponentFactory .inject(IccPhoneBookInterfaceManager.class.getName()) .makeIccPhoneBookInterfaceManager(this); Loading Loading @@ -693,7 +706,7 @@ public class GsmCdmaPhone extends Phone { unregisterForIccRecordEvents(); registerForIccRecordEvents(); mCT.updatePhoneType(); if (mCT != null) mCT.updatePhoneType(); int radioState = mCi.getRadioState(); if (radioState != TelephonyManager.RADIO_POWER_UNAVAILABLE) { Loading Loading @@ -753,6 +766,8 @@ public class GsmCdmaPhone extends Phone { @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) @Override public PhoneConstants.State getState() { if (!hasCalling()) return PhoneConstants.State.IDLE; if (mImsPhone != null) { PhoneConstants.State imsState = mImsPhone.getState(); if (imsState != PhoneConstants.State.IDLE) { Loading Loading @@ -837,6 +852,7 @@ public class GsmCdmaPhone extends Phone { @Override public boolean isDataSuspended() { if (mCT == null) return false; return mCT.mState != PhoneConstants.State.IDLE && !mSST.isConcurrentVoiceAndDataAllowed(); } Loading Loading @@ -884,7 +900,7 @@ public class GsmCdmaPhone extends Phone { @Override public boolean isInEmergencyCall() { if (isPhoneTypeGsm()) { if (!hasCalling() || isPhoneTypeGsm()) { return false; } else { return mCT.isInEmergencyCall(); Loading @@ -893,7 +909,7 @@ public class GsmCdmaPhone extends Phone { @Override protected void setIsInEmergencyCall() { if (!isPhoneTypeGsm()) { if (!hasCalling() && !isPhoneTypeGsm()) { mCT.setIsInEmergencyCall(); } } Loading Loading @@ -985,6 +1001,7 @@ public class GsmCdmaPhone extends Phone { @Override public void acceptCall(int videoState) throws CallStateException { if (!hasCalling()) throw new CallStateException(); Phone imsPhone = mImsPhone; if ( imsPhone != null && imsPhone.getRingingCall().isRinging() ) { imsPhone.acceptCall(videoState); Loading @@ -995,6 +1012,7 @@ public class GsmCdmaPhone extends Phone { @Override public void rejectCall() throws CallStateException { if (!hasCalling()) throw new CallStateException(); mCT.rejectCall(); } Loading Loading @@ -1025,6 +1043,7 @@ public class GsmCdmaPhone extends Phone { @Override public boolean canConference() { if (!hasCalling()) return false; if (mImsPhone != null && mImsPhone.canConference()) { return true; } Loading Loading @@ -1075,12 +1094,13 @@ public class GsmCdmaPhone extends Phone { @Override public void clearDisconnected() { if (!hasCalling()) return; mCT.clearDisconnected(); } @Override public boolean canTransfer() { if (isPhoneTypeGsm()) { if (hasCalling() && isPhoneTypeGsm()) { return mCT.canTransfer(); } else { loge("canTransfer: not possible in CDMA"); Loading @@ -1090,7 +1110,7 @@ public class GsmCdmaPhone extends Phone { @Override public void explicitCallTransfer() { if (isPhoneTypeGsm()) { if (hasCalling() && isPhoneTypeGsm()) { mCT.explicitCallTransfer(); } else { loge("explicitCallTransfer: not possible in CDMA"); Loading @@ -1104,11 +1124,13 @@ public class GsmCdmaPhone extends Phone { @Override public GsmCdmaCall getBackgroundCall() { if (!hasCalling()) return null; return mCT.mBackgroundCall; } @Override public Call getRingingCall() { if (!hasCalling()) return null; Phone imsPhone = mImsPhone; // It returns the ringing call of ImsPhone if the ringing call of GSMPhone isn't ringing. // In CallManager.registerPhone(), it always registers ringing call of ImsPhone, because Loading Loading @@ -1184,7 +1206,7 @@ public class GsmCdmaPhone extends Phone { private boolean handleCallDeflectionIncallSupplementaryService( String dialString) { if (dialString.length() > 1) { if (!hasCalling() || dialString.length() > 1) { return false; } Loading @@ -1209,7 +1231,7 @@ public class GsmCdmaPhone extends Phone { private boolean handleCallWaitingIncallSupplementaryService(String dialString) { int len = dialString.length(); if (len > 2) { if (!hasCalling() || len > 2) { return false; } Loading Loading @@ -1429,6 +1451,9 @@ public class GsmCdmaPhone extends Phone { @Override public Connection dial(String dialString, @NonNull DialArgs dialArgs, Consumer<Phone> chosenPhoneConsumer) throws CallStateException { if (!hasCalling()) { throw new CallStateException("Calling feature is not supported!"); } if (!isPhoneTypeGsm() && dialArgs.uusInfo != null) { throw new CallStateException("Sending UUS information NOT supported in CDMA!"); } Loading Loading @@ -2148,7 +2173,9 @@ public class GsmCdmaPhone extends Phone { @Override public int getEmergencyNumberDbVersion() { return getEmergencyNumberTracker().getEmergencyNumberDbVersion(); EmergencyNumberTracker tracker = getEmergencyNumberTracker(); if (tracker == null) return -1; return tracker.getEmergencyNumberDbVersion(); } @Override Loading Loading @@ -3134,6 +3161,8 @@ public class GsmCdmaPhone extends Phone { */ @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) private void syncClirSetting() { if (!hasCalling()) return; SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(getContext()); migrateClirSettingIfNeeded(sp); Loading Loading @@ -3339,8 +3368,10 @@ public class GsmCdmaPhone extends Phone { if (b != null) { updateBroadcastEmergencyCallStateChangesAfterCarrierConfigChanged(b); updateCdmaRoamingSettingsAfterCarrierConfigChanged(b); if (hasCalling()) { updateNrSettingsAfterCarrierConfigChanged(b); updateVoNrSettings(b); } updateSsOverCdmaSupported(b); updateCarrierN1ModeSupported(b); } else { Loading Loading @@ -4912,6 +4943,7 @@ public class GsmCdmaPhone extends Phone { * Handler of RIL Voice Radio Technology changed event. */ private void onVoiceRegStateOrRatChanged(int vrs, int vrat) { if (!hasCalling()) return; logd("onVoiceRegStateOrRatChanged"); mCT.dispatchCsCallRadioTech(getCsCallRadioTech(vrs, vrat)); } Loading Loading @@ -5113,6 +5145,8 @@ public class GsmCdmaPhone extends Phone { * Load the current TTY mode in GsmCdmaPhone based on Telecom and UI settings. */ private void loadTtyMode() { if (!hasCalling()) return; int ttyMode = TelecomManager.TTY_MODE_OFF; TelecomManager telecomManager = mContext.getSystemService(TelecomManager.class); if (telecomManager != null) { Loading
src/java/com/android/internal/telephony/MultiSimSettingController.java +65 −32 Original line number Diff line number Diff line Loading @@ -35,6 +35,7 @@ import android.annotation.NonNull; import android.app.PendingIntent; import android.content.Context; import android.content.Intent; import android.content.pm.PackageManager; import android.os.AsyncResult; import android.os.Handler; import android.os.Looper; Loading @@ -52,6 +53,7 @@ import android.util.Log; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.telephony.data.DataSettingsManager.DataSettingsManagerCallback; import com.android.internal.telephony.flags.FeatureFlags; import com.android.internal.telephony.subscription.SubscriptionInfoInternal; import com.android.internal.telephony.subscription.SubscriptionManagerService; import com.android.internal.telephony.util.ArrayUtils; Loading Loading @@ -122,6 +124,7 @@ public class MultiSimSettingController extends Handler { protected final Context mContext; private final SubscriptionManagerService mSubscriptionManagerService; private final @NonNull FeatureFlags mFeatureFlags; // Keep a record of active primary (non-opportunistic) subscription list. @NonNull private List<Integer> mPrimarySubList = new ArrayList<>(); Loading Loading @@ -201,10 +204,11 @@ public class MultiSimSettingController extends Handler { /** * Init instance of MultiSimSettingController. */ public static MultiSimSettingController init(Context context) { public static MultiSimSettingController init(Context context, @NonNull FeatureFlags featureFlags) { synchronized (MultiSimSettingController.class) { if (sInstance == null) { sInstance = new MultiSimSettingController(context); sInstance = new MultiSimSettingController(context, featureFlags); } else { Log.wtf(LOG_TAG, "init() called multiple times! sInstance = " + sInstance); } Loading @@ -213,9 +217,10 @@ public class MultiSimSettingController extends Handler { } @VisibleForTesting public MultiSimSettingController(Context context) { public MultiSimSettingController(Context context, @NonNull FeatureFlags featureFlags) { mContext = context; mSubscriptionManagerService = SubscriptionManagerService.getInstance(); mFeatureFlags = featureFlags; // Initialize mCarrierConfigLoadedSubIds and register to listen to carrier config change. TelephonyManager telephonyManager = ((TelephonyManager) mContext.getSystemService( Loading @@ -239,6 +244,24 @@ public class MultiSimSettingController extends Handler { onCarrierConfigChanged(slotIndex, subId)); } private boolean hasCalling() { if (!mFeatureFlags.minimalTelephonyCdmCheck()) return true; return mContext.getPackageManager().hasSystemFeature( PackageManager.FEATURE_TELEPHONY_CALLING); } private boolean hasData() { if (!mFeatureFlags.minimalTelephonyCdmCheck()) return true; return mContext.getPackageManager().hasSystemFeature( PackageManager.FEATURE_TELEPHONY_DATA); } private boolean hasMessaging() { if (!mFeatureFlags.minimalTelephonyCdmCheck()) return true; return mContext.getPackageManager().hasSystemFeature( PackageManager.FEATURE_TELEPHONY_MESSAGING); } /** * Notify MOBILE_DATA of a subscription is changed. */ Loading Loading @@ -606,35 +629,43 @@ public class MultiSimSettingController extends Handler { || mActiveModemCount == 1)) { int subId = mPrimarySubList.get(0); if (DBG) log("updateDefaultValues: to only primary sub " + subId); mSubscriptionManagerService.setDefaultDataSubId(subId); mSubscriptionManagerService.setDefaultVoiceSubId(subId); mSubscriptionManagerService.setDefaultSmsSubId(subId); if (hasData()) mSubscriptionManagerService.setDefaultDataSubId(subId); if (hasCalling()) mSubscriptionManagerService.setDefaultVoiceSubId(subId); if (hasMessaging()) mSubscriptionManagerService.setDefaultSmsSubId(subId); sendDefaultSubConfirmedNotification(subId); return; } if (DBG) log("updateDefaultValues: records: " + mPrimarySubList); boolean dataSelected, voiceSelected, smsSelected; boolean dataSelected = false; boolean voiceSelected = false; boolean smsSelected = false; if (hasData()) { // Update default data subscription. if (DBG) log("updateDefaultValues: Update default data subscription"); dataSelected = updateDefaultValue(mPrimarySubList, mSubscriptionManagerService.getDefaultDataSubId(), mSubscriptionManagerService::setDefaultDataSubId); } if (hasCalling()) { // Update default voice subscription. if (DBG) log("updateDefaultValues: Update default voice subscription"); voiceSelected = updateDefaultValue(mPrimarySubList, mSubscriptionManagerService.getDefaultVoiceSubId(), mSubscriptionManagerService::setDefaultVoiceSubId); } if (hasMessaging()) { // Update default sms subscription. if (DBG) log("updateDefaultValues: Update default sms subscription"); smsSelected = updateDefaultValue(mPrimarySubList, mSubscriptionManagerService.getDefaultSmsSubId(), mSubscriptionManagerService::setDefaultSmsSubId, mIsAskEverytimeSupportedForSms); } boolean autoFallbackEnabled = mContext.getResources().getBoolean( com.android.internal.R.bool.config_voice_data_sms_auto_fallback); Loading Loading @@ -1023,11 +1054,11 @@ public class MultiSimSettingController extends Handler { int autoDefaultSubId = primarySubList.get(0); if ((primarySubList.size() == 1) && !smsSelected) { if (hasMessaging() && (primarySubList.size() == 1) && !smsSelected) { mSubscriptionManagerService.setDefaultSmsSubId(autoDefaultSubId); } if ((primarySubList.size() == 1) && !voiceSelected) { if (hasCalling() && (primarySubList.size() == 1) && !voiceSelected) { mSubscriptionManagerService.setDefaultVoiceSubId(autoDefaultSubId); } Loading @@ -1036,6 +1067,7 @@ public class MultiSimSettingController extends Handler { log("User pref subId = " + userPrefDataSubId + " current dds " + defaultDataSubId + " next active subId " + autoDefaultSubId); if (hasData()) { // If earlier user selected DDS is now available, set that as DDS subId. if (primarySubList.contains(userPrefDataSubId) && SubscriptionManager.isValidSubscriptionId(userPrefDataSubId) Loading @@ -1044,6 +1076,7 @@ public class MultiSimSettingController extends Handler { } else if (!dataSelected) { mSubscriptionManagerService.setDefaultDataSubId(autoDefaultSubId); } } if (DBG) { log("updateUserPreferences: after dds = " Loading
src/java/com/android/internal/telephony/NetworkTypeController.java +33 −1 Original line number Diff line number Diff line Loading @@ -26,6 +26,7 @@ import android.os.AsyncResult; import android.os.Message; import android.os.PersistableBundle; import android.os.PowerManager; import android.os.SystemClock; import android.telephony.AccessNetworkConstants; import android.telephony.Annotation; import android.telephony.CarrierConfigManager; Loading Loading @@ -194,6 +195,7 @@ public class NetworkTypeController extends StateMachine { private boolean mIsPhysicalChannelConfigOn; private boolean mIsPrimaryTimerActive; private boolean mIsSecondaryTimerActive; private long mSecondaryTimerExpireTimestamp; private boolean mIsTimerResetEnabledForLegacyStateRrcIdle; /** Carrier config to reset timers when mccmnc changes */ private boolean mIsTimerResetEnabledOnPlmnChanges; Loading @@ -220,6 +222,7 @@ public class NetworkTypeController extends StateMachine { // Cached copies below to prevent race conditions @NonNull private ServiceState mServiceState; /** Used to track link status to be DORMANT or ACTIVE */ @Nullable private List<PhysicalChannelConfig> mPhysicalChannelConfigs; // Ratchet physical channel config fields to prevent 5G/5G+ flickering Loading Loading @@ -666,6 +669,7 @@ public class NetworkTypeController extends StateMachine { case EVENT_SECONDARY_TIMER_EXPIRED: if (DBG) log("Secondary timer expired for state: " + mSecondaryTimerState); mIsSecondaryTimerActive = false; mSecondaryTimerExpireTimestamp = 0; mSecondaryTimerState = ""; updateTimers(); mLastShownNrDueToAdvancedBand = false; Loading Loading @@ -1251,6 +1255,8 @@ public class NetworkTypeController extends StateMachine { private void updatePhysicalChannelConfigs(List<PhysicalChannelConfig> physicalChannelConfigs) { boolean isPccListEmpty = physicalChannelConfigs == null || physicalChannelConfigs.isEmpty(); if (isPccListEmpty && isUsingPhysicalChannelConfigForRrcDetection()) { // Clear mPrimaryCellChangedWhileIdle to allow later potential one-off PCI change. // Update link status to be DORMANT, but keep ratcheted bands. log("Physical channel configs updated: not updating PCC fields for empty PCC list " + "indicating RRC idle."); mPrimaryCellChangedWhileIdle = false; Loading Loading @@ -1310,6 +1316,7 @@ public class NetworkTypeController extends StateMachine { + mLastAnchorNrCellId + " -> " + anchorNrCellId); mPrimaryCellChangedWhileIdle = true; mLastAnchorNrCellId = anchorNrCellId; reduceSecondaryTimerIfNeeded(); return; } if (mRatchetPccFieldsForSameAnchorNrCell) { Loading @@ -1330,6 +1337,27 @@ public class NetworkTypeController extends StateMachine { } } /** * Called when PCI change, specifically during idle state. */ private void reduceSecondaryTimerIfNeeded() { if (!mIsSecondaryTimerActive || mNrAdvancedBandsSecondaryTimer <= 0) return; // Secondary timer is active, so we must have a valid secondary rule right now. OverrideTimerRule secondaryRule = mOverrideTimerRules.get(mPrimaryTimerState); if (secondaryRule != null) { int secondaryDuration = secondaryRule.getSecondaryTimer(mSecondaryTimerState); long durationMillis = secondaryDuration * 1000L; if ((mSecondaryTimerExpireTimestamp - SystemClock.uptimeMillis()) > durationMillis) { if (DBG) log("Due to PCI change, reduce the secondary timer to " + durationMillis); removeMessages(EVENT_SECONDARY_TIMER_EXPIRED); sendMessageDelayed(EVENT_SECONDARY_TIMER_EXPIRED, mSecondaryTimerState, durationMillis); } } else { loge("!! Secondary timer is active, but found no rule for " + mPrimaryTimerState); } } private void transitionWithTimerTo(IState destState) { String destName = destState.getName(); if (mIsPrimaryTimerActive) { Loading Loading @@ -1369,7 +1397,9 @@ public class NetworkTypeController extends StateMachine { mSecondaryTimerState = currentName; mPreviousState = currentName; mIsSecondaryTimerActive = true; sendMessageDelayed(EVENT_SECONDARY_TIMER_EXPIRED, destState, duration * 1000L); long durationMillis = duration * 1000L; mSecondaryTimerExpireTimestamp = SystemClock.uptimeMillis() + durationMillis; sendMessageDelayed(EVENT_SECONDARY_TIMER_EXPIRED, destState, durationMillis); } mIsPrimaryTimerActive = false; transitionTo(getCurrentState()); Loading Loading @@ -1434,6 +1464,7 @@ public class NetworkTypeController extends StateMachine { } removeMessages(EVENT_SECONDARY_TIMER_EXPIRED); mIsSecondaryTimerActive = false; mSecondaryTimerExpireTimestamp = 0; mSecondaryTimerState = ""; transitionToCurrentState(); return; Loading Loading @@ -1464,6 +1495,7 @@ public class NetworkTypeController extends StateMachine { removeMessages(EVENT_SECONDARY_TIMER_EXPIRED); mIsPrimaryTimerActive = false; mIsSecondaryTimerActive = false; mSecondaryTimerExpireTimestamp = 0; mPrimaryTimerState = ""; mSecondaryTimerState = ""; Loading