Loading src/java/com/android/internal/telephony/PhoneSwitcher.java +78 −62 Original line number Diff line number Diff line Loading @@ -105,31 +105,40 @@ public class PhoneSwitcher extends Handler { private int mMaxActivePhones; private static PhoneSwitcher sPhoneSwitcher = null; // Default subscription ID from user setting. private int mDefaultDataSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID; // Which non-opportunistic subscription is set as data subscription among all non-oppt // subscriptions. This value usually comes from user setting, and it's the subscription used for // Internet data if mOpptDataSubId is not set. private int mNonOpptDataSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID; // If mPreferredDataSubId is an active subscription, it overrides // mDefaultDataSubId and decides: // 1. In modem layer, which subscription is preferred to have data traffic on. // 2. In TelephonyNetworkFactory, which subscription will apply default network requests, which // are requests without specifying a subId. private int mPreferredDataSubId = SubscriptionManager.DEFAULT_SUBSCRIPTION_ID; // mOpptDataSubId must be an active subscription. If it's set, it overrides mNonOpptDataSubId // to be used for Internet data. private int mOpptDataSubId = SubscriptionManager.DEFAULT_SUBSCRIPTION_ID; // The phone ID that has an active voice call. If set, and its mobile data setting is on, // it will become the mPreferredDataPhoneId. private int mPhoneIdInVoiceCall = SubscriptionManager.INVALID_PHONE_INDEX; @VisibleForTesting // Corresponding phoneId after considering mPreferredDataSubId and mDefaultDataSubId above. // It decides: // 1. In modem layer, which modem is DDS (preferred to have data traffic on) // 2. In TelephonyNetworkFactory, which subscription will apply default network requests, which // are requests without specifying a subId. // Corresponding phoneId after considering mOpptDataSubId, mNonOpptDataSubId and // mPhoneIdInVoiceCall above. protected int mPreferredDataPhoneId = SubscriptionManager.INVALID_PHONE_INDEX; private int mPhoneIdInCall = SubscriptionManager.INVALID_PHONE_INDEX; // Subscription ID corresponds to mPreferredDataPhoneId. private int mPreferredDataSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID; private ISetOpportunisticDataCallback mSetOpptSubCallback; private static final int EVENT_DEFAULT_SUBSCRIPTION_CHANGED = 101; private static final int EVENT_NON_OPPT_SUBSCRIPTION_CHANGED = 101; private static final int EVENT_SUBSCRIPTION_CHANGED = 102; private static final int EVENT_REQUEST_NETWORK = 103; private static final int EVENT_RELEASE_NETWORK = 104; private static final int EVENT_EMERGENCY_TOGGLE = 105; private static final int EVENT_RADIO_CAPABILITY_CHANGED = 106; private static final int EVENT_CHANGE_PREFERRED_SUBSCRIPTION = 107; private static final int EVENT_OPPT_SUBSCRIPTION_CHANGED = 107; private static final int EVENT_RADIO_AVAILABLE = 108; private static final int EVENT_PHONE_IN_CALL_CHANGED = 109; private static final int EVENT_NETWORK_VALIDATION_DONE = 110; Loading Loading @@ -161,7 +170,7 @@ public class PhoneSwitcher extends Handler { if (mConnectivityManager.getNetworkCapabilities(network) .hasTransport(TRANSPORT_CELLULAR)) { logDataSwitchEvent( mPreferredDataSubId, mOpptDataSubId, TelephonyEvent.EventState.EVENT_STATE_END, TelephonyEvent.DataSwitch.Reason.DATA_SWITCH_REASON_UNKNOWN); } Loading Loading @@ -236,21 +245,21 @@ public class PhoneSwitcher extends Handler { @Override public void onPreciseCallStateChanged(PreciseCallState callState) { int oldPhoneIdInCall = mPhoneIdInCall; int oldPhoneIdInVoiceCall = mPhoneIdInVoiceCall; // If there's no active call, the value will become INVALID_PHONE_INDEX // and internet data will be switched back to system selected or user selected // subscription. mPhoneIdInCall = SubscriptionManager.INVALID_PHONE_INDEX; mPhoneIdInVoiceCall = SubscriptionManager.INVALID_PHONE_INDEX; for (Phone phone : mPhones) { if (isCallActive(phone) || isCallActive(phone.getImsPhone())) { mPhoneIdInCall = phone.getPhoneId(); mPhoneIdInVoiceCall = phone.getPhoneId(); break; } } if (mPhoneIdInCall != oldPhoneIdInCall) { log("mPhoneIdInCall changed from" + oldPhoneIdInCall + " to " + mPhoneIdInCall); if (mPhoneIdInVoiceCall != oldPhoneIdInVoiceCall) { log("mPhoneIdInVoiceCall changed from" + oldPhoneIdInVoiceCall + " to " + mPhoneIdInVoiceCall); Message msg = PhoneSwitcher.this.obtainMessage(EVENT_PHONE_IN_CALL_CHANGED); msg.sendToTarget(); } Loading Loading @@ -317,7 +326,7 @@ public class PhoneSwitcher extends Handler { private final BroadcastReceiver mDefaultDataChangedReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { Message msg = PhoneSwitcher.this.obtainMessage(EVENT_DEFAULT_SUBSCRIPTION_CHANGED); Message msg = PhoneSwitcher.this.obtainMessage(EVENT_NON_OPPT_SUBSCRIPTION_CHANGED); msg.sendToTarget(); } }; Loading @@ -338,9 +347,9 @@ public class PhoneSwitcher extends Handler { onEvaluate(REQUESTS_UNCHANGED, "subChanged"); break; } case EVENT_DEFAULT_SUBSCRIPTION_CHANGED: { if (onEvaluate(REQUESTS_UNCHANGED, "defaultChanged")) { logDataSwitchEvent(mPreferredDataSubId, case EVENT_NON_OPPT_SUBSCRIPTION_CHANGED: { if (onEvaluate(REQUESTS_UNCHANGED, "non-oppt data subId changed")) { logDataSwitchEvent(mOpptDataSubId, TelephonyEvent.EventState.EVENT_STATE_START, DataSwitch.Reason.DATA_SWITCH_REASON_MANUAL); registerDefaultNetworkChangeCallback(); Loading @@ -363,7 +372,7 @@ public class PhoneSwitcher extends Handler { resendRilCommands(msg); break; } case EVENT_CHANGE_PREFERRED_SUBSCRIPTION: { case EVENT_OPPT_SUBSCRIPTION_CHANGED: { int subId = msg.arg1; boolean needValidation = (msg.arg2 == 1); ISetOpportunisticDataCallback callback = Loading @@ -382,7 +391,7 @@ public class PhoneSwitcher extends Handler { } case EVENT_PHONE_IN_CALL_CHANGED: { if (onEvaluate(REQUESTS_UNCHANGED, "EVENT_PHONE_IN_CALL_CHANGED")) { logDataSwitchEvent(mPreferredDataSubId, logDataSwitchEvent(mOpptDataSubId, TelephonyEvent.EventState.EVENT_STATE_START, DataSwitch.Reason.DATA_SWITCH_REASON_IN_CALL); registerDefaultNetworkChangeCallback(); Loading Loading @@ -521,11 +530,12 @@ public class PhoneSwitcher extends Handler { // If we use HAL_COMMAND_PREFERRED_DATA, boolean diffDetected = mHalCommandToUse != HAL_COMMAND_PREFERRED_DATA && requestsChanged; // Check if user setting of default data sub is changed. final int dataSub = mSubscriptionController.getDefaultDataSubId(); if (dataSub != mDefaultDataSubId) { sb.append(" default ").append(mDefaultDataSubId).append("->").append(dataSub); mDefaultDataSubId = dataSub; // Check if user setting of default non-opportunistic data sub is changed. final int nonOpptDataSubId = mSubscriptionController.getDefaultDataSubId(); if (nonOpptDataSubId != mNonOpptDataSubId) { sb.append(" mNonOpptDataSubId ").append(mNonOpptDataSubId).append("->") .append(nonOpptDataSubId); mNonOpptDataSubId = nonOpptDataSubId; } // Check if phoneId to subId mapping is changed. Loading @@ -541,7 +551,7 @@ public class PhoneSwitcher extends Handler { // Check if phoneId for preferred data is changed. int oldPreferredDataPhoneId = mPreferredDataPhoneId; updatePhoneIdForDefaultNetworkRequests(); updatePreferredDataPhoneId(); if (oldPreferredDataPhoneId != mPreferredDataPhoneId) { sb.append(" preferred phoneId ").append(oldPreferredDataPhoneId) .append("->").append(mPreferredDataPhoneId); Loading Loading @@ -588,8 +598,8 @@ public class PhoneSwitcher extends Handler { } if (VDBG) { log("default subId = " + mDefaultDataSubId); log("preferred subId = " + mPreferredDataSubId); log("mNonOpptDataSubId = " + mNonOpptDataSubId); log("mOpptDataSubId = " + mOpptDataSubId); for (int i = 0; i < mNumPhones; i++) { log(" phone[" + i + "] using sub[" + mPhoneSubscriptions[i] + "]"); } Loading @@ -609,8 +619,7 @@ public class PhoneSwitcher extends Handler { } } notifyActiveDataSubIdChanged(mSubscriptionController.getSubIdUsingPhoneId( mPreferredDataPhoneId)); notifyPreferredDataSubIdChanged(); // Notify all registrants. mActivePhoneRegistrants.notifyRegistrants(); Loading Loading @@ -734,23 +743,23 @@ public class PhoneSwitcher extends Handler { } private int getSubIdForDefaultNetworkRequests() { if (mSubscriptionController.isActiveSubId(mPreferredDataSubId)) { return mPreferredDataSubId; if (mSubscriptionController.isActiveSubId(mOpptDataSubId)) { return mOpptDataSubId; } else { return mDefaultDataSubId; return mNonOpptDataSubId; } } // This updates mPreferredDataPhoneId which decides which phone should // handle default network requests. private void updatePhoneIdForDefaultNetworkRequests() { if (SubscriptionManager.isValidPhoneId(mPhoneIdInCall)) { private void updatePreferredDataPhoneId() { if (SubscriptionManager.isValidPhoneId(mPhoneIdInVoiceCall)) { // 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 = mPhoneIdInCall; mPreferredDataPhoneId = mPhoneIdInVoiceCall; } else { int subId = getSubIdForDefaultNetworkRequests(); int phoneId = SubscriptionManager.INVALID_PHONE_INDEX; Loading @@ -766,6 +775,8 @@ public class PhoneSwitcher extends Handler { mPreferredDataPhoneId = phoneId; } mPreferredDataSubId = mSubscriptionController.getSubIdUsingPhoneId(mPreferredDataPhoneId); } public boolean shouldApplyNetworkRequest(NetworkRequest networkRequest, int phoneId) { Loading Loading @@ -823,7 +834,7 @@ public class PhoneSwitcher extends Handler { mValidator.stopValidation(); } if (subId == mPreferredDataSubId) { if (subId == mOpptDataSubId) { sendSetOpptCallbackHelper(callback, SET_OPPORTUNISTIC_SUB_SUCCESS); return; } Loading @@ -837,7 +848,7 @@ public class PhoneSwitcher extends Handler { mValidator.validate(subId, DEFAULT_VALIDATION_EXPIRATION_TIME, false, mValidationCallback); } else { setPreferredSubscription(subId); setOpportunisticSubscriptionInternal(subId); sendSetOpptCallbackHelper(callback, SET_OPPORTUNISTIC_SUB_SUCCESS); } } Loading @@ -851,9 +862,9 @@ public class PhoneSwitcher extends Handler { mValidator.stopValidation(); } // Set mPreferredDataSubId back to DEFAULT_SUBSCRIPTION_ID. This will trigger // data switch to mDefaultDataSubId. setPreferredSubscription(SubscriptionManager.DEFAULT_SUBSCRIPTION_ID); // Set mOpptDataSubId back to DEFAULT_SUBSCRIPTION_ID. This will trigger // data switch to mNonOpptDataSubId. setOpportunisticSubscriptionInternal(SubscriptionManager.DEFAULT_SUBSCRIPTION_ID); sendSetOpptCallbackHelper(callback, SET_OPPORTUNISTIC_SUB_SUCCESS); } Loading @@ -869,11 +880,11 @@ public class PhoneSwitcher extends Handler { /** * Set opportunistic data subscription. */ private void setPreferredSubscription(int subId) { if (mPreferredDataSubId != subId) { mPreferredDataSubId = subId; if (onEvaluate(REQUESTS_UNCHANGED, "preferredDataSubscriptionIdChanged")) { logDataSwitchEvent(mPreferredDataSubId, private void setOpportunisticSubscriptionInternal(int subId) { if (mOpptDataSubId != subId) { mOpptDataSubId = subId; if (onEvaluate(REQUESTS_UNCHANGED, "oppt data subId changed")) { logDataSwitchEvent(mOpptDataSubId, TelephonyEvent.EventState.EVENT_STATE_START, DataSwitch.Reason.DATA_SWITCH_REASON_CBRS); registerDefaultNetworkChangeCallback(); Loading @@ -884,7 +895,7 @@ public class PhoneSwitcher extends Handler { private void onValidationDone(int subId, boolean passed) { log("Network validation " + (passed ? "passed" : "failed") + " on subId " + subId); if (passed) setPreferredSubscription(subId); if (passed) setOpportunisticSubscriptionInternal(subId); // Trigger callback if needed sendSetOpptCallbackHelper(mSetOpptSubCallback, passed ? SET_OPPORTUNISTIC_SUB_SUCCESS Loading @@ -892,12 +903,14 @@ public class PhoneSwitcher extends Handler { mSetOpptSubCallback = null; } // TODO b/123598154: rename preferredDataSub to opportunisticSubId. public void trySetPreferredSubscription(int subId, boolean needValidation, /** * Notify PhoneSwitcher to try to switch data to an opportunistic subscription. */ public void trySetOpportunisticDataSubscription(int subId, boolean needValidation, ISetOpportunisticDataCallback callback) { log("Try set preferred subscription to subId " + subId log("Try set opportunistic data subscription to subId " + subId + (needValidation ? " with " : " without ") + "validation"); PhoneSwitcher.this.obtainMessage(EVENT_CHANGE_PREFERRED_SUBSCRIPTION, PhoneSwitcher.this.obtainMessage(EVENT_OPPT_SUBSCRIPTION_CHANGED, subId, needValidation ? 1 : 0, callback).sendToTarget(); } Loading @@ -915,8 +928,8 @@ public class PhoneSwitcher extends Handler { ? HAL_COMMAND_PREFERRED_DATA : HAL_COMMAND_ALLOW_DATA; } public int getPreferredDataSubscriptionId() { return mPreferredDataSubId; public int getOpportunisticDataSubscriptionId() { return mOpptDataSubId; } public int getPreferredDataPhoneId() { Loading @@ -930,19 +943,22 @@ public class PhoneSwitcher extends Handler { } private void logDataSwitchEvent(int subId, int state, int reason) { subId = subId == DEFAULT_SUBSCRIPTION_ID ? mDefaultDataSubId : subId; subId = subId == DEFAULT_SUBSCRIPTION_ID ? mNonOpptDataSubId : subId; DataSwitch dataSwitch = new DataSwitch(); dataSwitch.state = state; dataSwitch.reason = reason; TelephonyMetrics.getInstance().writeDataSwitch(subId, dataSwitch); } private void notifyActiveDataSubIdChanged(int activeDataSubId) { /** * See {@link PhoneStateListener#LISTEN_ACTIVE_DATA_SUBSCRIPTION_ID_CHANGE}. */ private void notifyPreferredDataSubIdChanged() { ITelephonyRegistry tr = ITelephonyRegistry.Stub.asInterface(ServiceManager.getService( "telephony.registry")); try { log("notifyActiveDataSubIdChanged to " + activeDataSubId); tr.notifyActiveDataSubIdChanged(activeDataSubId); log("notifyPreferredDataSubIdChanged to " + mPreferredDataSubId); tr.notifyActiveDataSubIdChanged(mPreferredDataSubId); } catch (RemoteException ex) { // Should never happen because its always available. } Loading src/java/com/android/internal/telephony/SubscriptionController.java +2 −2 Original line number Diff line number Diff line Loading @@ -2669,7 +2669,7 @@ public class SubscriptionController extends ISub.Stub { final long token = Binder.clearCallingIdentity(); try { PhoneSwitcher.getInstance().trySetPreferredSubscription( PhoneSwitcher.getInstance().trySetOpportunisticDataSubscription( subId, needValidation, callback); } finally { Binder.restoreCallingIdentity(token); Loading @@ -2682,7 +2682,7 @@ public class SubscriptionController extends ISub.Stub { final long token = Binder.clearCallingIdentity(); try { return PhoneSwitcher.getInstance().getPreferredDataSubscriptionId(); return PhoneSwitcher.getInstance().getOpportunisticDataSubscriptionId(); } finally { Binder.restoreCallingIdentity(token); } Loading tests/telephonytests/src/com/android/internal/telephony/PhoneSwitcherTest.java +6 −6 Original line number Diff line number Diff line Loading @@ -386,14 +386,14 @@ public class PhoneSwitcherTest extends TelephonyTest { assertTrue(mDataAllowed[0]); // Set sub 2 as preferred sub should make phone 1 activated and phone 0 deactivated. mPhoneSwitcher.trySetPreferredSubscription(2, false, null); mPhoneSwitcher.trySetOpportunisticDataSubscription(2, false, null); waitABit(); assertFalse(mDataAllowed[0]); assertTrue(mDataAllowed[1]); // Unset preferred sub should make default data sub (phone 0 / sub 1) activated again. mPhoneSwitcher.trySetPreferredSubscription(SubscriptionManager.DEFAULT_SUBSCRIPTION_ID, false, null); mPhoneSwitcher.trySetOpportunisticDataSubscription( SubscriptionManager.DEFAULT_SUBSCRIPTION_ID, false, null); waitABit(); assertTrue(mDataAllowed[0]); assertFalse(mDataAllowed[1]); Loading Loading @@ -442,7 +442,7 @@ public class PhoneSwitcherTest extends TelephonyTest { assertTrue(mPhoneSwitcher.shouldApplyNetworkRequest(mmsRequest, 1)); // Set sub 2 as preferred sub should make phone 1 preferredDataModem mPhoneSwitcher.trySetPreferredSubscription(2, false, null); mPhoneSwitcher.trySetOpportunisticDataSubscription(2, false, null); waitABit(); verify(mMockRadioConfig).setPreferredDataModem(eq(1), any()); verify(mActivePhoneSwitchHandler, times(2)).sendMessageAtTime(any(), anyLong()); Loading @@ -455,8 +455,8 @@ public class PhoneSwitcherTest extends TelephonyTest { clearInvocations(mActivePhoneSwitchHandler); // Unset preferred sub should make phone0 preferredDataModem again. mPhoneSwitcher.trySetPreferredSubscription(SubscriptionManager.DEFAULT_SUBSCRIPTION_ID, false, null); mPhoneSwitcher.trySetOpportunisticDataSubscription( SubscriptionManager.DEFAULT_SUBSCRIPTION_ID, false, null); waitABit(); verify(mMockRadioConfig).setPreferredDataModem(eq(0), any()); verify(mActivePhoneSwitchHandler, times(2)).sendMessageAtTime(any(), anyLong()); Loading Loading
src/java/com/android/internal/telephony/PhoneSwitcher.java +78 −62 Original line number Diff line number Diff line Loading @@ -105,31 +105,40 @@ public class PhoneSwitcher extends Handler { private int mMaxActivePhones; private static PhoneSwitcher sPhoneSwitcher = null; // Default subscription ID from user setting. private int mDefaultDataSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID; // Which non-opportunistic subscription is set as data subscription among all non-oppt // subscriptions. This value usually comes from user setting, and it's the subscription used for // Internet data if mOpptDataSubId is not set. private int mNonOpptDataSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID; // If mPreferredDataSubId is an active subscription, it overrides // mDefaultDataSubId and decides: // 1. In modem layer, which subscription is preferred to have data traffic on. // 2. In TelephonyNetworkFactory, which subscription will apply default network requests, which // are requests without specifying a subId. private int mPreferredDataSubId = SubscriptionManager.DEFAULT_SUBSCRIPTION_ID; // mOpptDataSubId must be an active subscription. If it's set, it overrides mNonOpptDataSubId // to be used for Internet data. private int mOpptDataSubId = SubscriptionManager.DEFAULT_SUBSCRIPTION_ID; // The phone ID that has an active voice call. If set, and its mobile data setting is on, // it will become the mPreferredDataPhoneId. private int mPhoneIdInVoiceCall = SubscriptionManager.INVALID_PHONE_INDEX; @VisibleForTesting // Corresponding phoneId after considering mPreferredDataSubId and mDefaultDataSubId above. // It decides: // 1. In modem layer, which modem is DDS (preferred to have data traffic on) // 2. In TelephonyNetworkFactory, which subscription will apply default network requests, which // are requests without specifying a subId. // Corresponding phoneId after considering mOpptDataSubId, mNonOpptDataSubId and // mPhoneIdInVoiceCall above. protected int mPreferredDataPhoneId = SubscriptionManager.INVALID_PHONE_INDEX; private int mPhoneIdInCall = SubscriptionManager.INVALID_PHONE_INDEX; // Subscription ID corresponds to mPreferredDataPhoneId. private int mPreferredDataSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID; private ISetOpportunisticDataCallback mSetOpptSubCallback; private static final int EVENT_DEFAULT_SUBSCRIPTION_CHANGED = 101; private static final int EVENT_NON_OPPT_SUBSCRIPTION_CHANGED = 101; private static final int EVENT_SUBSCRIPTION_CHANGED = 102; private static final int EVENT_REQUEST_NETWORK = 103; private static final int EVENT_RELEASE_NETWORK = 104; private static final int EVENT_EMERGENCY_TOGGLE = 105; private static final int EVENT_RADIO_CAPABILITY_CHANGED = 106; private static final int EVENT_CHANGE_PREFERRED_SUBSCRIPTION = 107; private static final int EVENT_OPPT_SUBSCRIPTION_CHANGED = 107; private static final int EVENT_RADIO_AVAILABLE = 108; private static final int EVENT_PHONE_IN_CALL_CHANGED = 109; private static final int EVENT_NETWORK_VALIDATION_DONE = 110; Loading Loading @@ -161,7 +170,7 @@ public class PhoneSwitcher extends Handler { if (mConnectivityManager.getNetworkCapabilities(network) .hasTransport(TRANSPORT_CELLULAR)) { logDataSwitchEvent( mPreferredDataSubId, mOpptDataSubId, TelephonyEvent.EventState.EVENT_STATE_END, TelephonyEvent.DataSwitch.Reason.DATA_SWITCH_REASON_UNKNOWN); } Loading Loading @@ -236,21 +245,21 @@ public class PhoneSwitcher extends Handler { @Override public void onPreciseCallStateChanged(PreciseCallState callState) { int oldPhoneIdInCall = mPhoneIdInCall; int oldPhoneIdInVoiceCall = mPhoneIdInVoiceCall; // If there's no active call, the value will become INVALID_PHONE_INDEX // and internet data will be switched back to system selected or user selected // subscription. mPhoneIdInCall = SubscriptionManager.INVALID_PHONE_INDEX; mPhoneIdInVoiceCall = SubscriptionManager.INVALID_PHONE_INDEX; for (Phone phone : mPhones) { if (isCallActive(phone) || isCallActive(phone.getImsPhone())) { mPhoneIdInCall = phone.getPhoneId(); mPhoneIdInVoiceCall = phone.getPhoneId(); break; } } if (mPhoneIdInCall != oldPhoneIdInCall) { log("mPhoneIdInCall changed from" + oldPhoneIdInCall + " to " + mPhoneIdInCall); if (mPhoneIdInVoiceCall != oldPhoneIdInVoiceCall) { log("mPhoneIdInVoiceCall changed from" + oldPhoneIdInVoiceCall + " to " + mPhoneIdInVoiceCall); Message msg = PhoneSwitcher.this.obtainMessage(EVENT_PHONE_IN_CALL_CHANGED); msg.sendToTarget(); } Loading Loading @@ -317,7 +326,7 @@ public class PhoneSwitcher extends Handler { private final BroadcastReceiver mDefaultDataChangedReceiver = new BroadcastReceiver() { @Override public void onReceive(Context context, Intent intent) { Message msg = PhoneSwitcher.this.obtainMessage(EVENT_DEFAULT_SUBSCRIPTION_CHANGED); Message msg = PhoneSwitcher.this.obtainMessage(EVENT_NON_OPPT_SUBSCRIPTION_CHANGED); msg.sendToTarget(); } }; Loading @@ -338,9 +347,9 @@ public class PhoneSwitcher extends Handler { onEvaluate(REQUESTS_UNCHANGED, "subChanged"); break; } case EVENT_DEFAULT_SUBSCRIPTION_CHANGED: { if (onEvaluate(REQUESTS_UNCHANGED, "defaultChanged")) { logDataSwitchEvent(mPreferredDataSubId, case EVENT_NON_OPPT_SUBSCRIPTION_CHANGED: { if (onEvaluate(REQUESTS_UNCHANGED, "non-oppt data subId changed")) { logDataSwitchEvent(mOpptDataSubId, TelephonyEvent.EventState.EVENT_STATE_START, DataSwitch.Reason.DATA_SWITCH_REASON_MANUAL); registerDefaultNetworkChangeCallback(); Loading @@ -363,7 +372,7 @@ public class PhoneSwitcher extends Handler { resendRilCommands(msg); break; } case EVENT_CHANGE_PREFERRED_SUBSCRIPTION: { case EVENT_OPPT_SUBSCRIPTION_CHANGED: { int subId = msg.arg1; boolean needValidation = (msg.arg2 == 1); ISetOpportunisticDataCallback callback = Loading @@ -382,7 +391,7 @@ public class PhoneSwitcher extends Handler { } case EVENT_PHONE_IN_CALL_CHANGED: { if (onEvaluate(REQUESTS_UNCHANGED, "EVENT_PHONE_IN_CALL_CHANGED")) { logDataSwitchEvent(mPreferredDataSubId, logDataSwitchEvent(mOpptDataSubId, TelephonyEvent.EventState.EVENT_STATE_START, DataSwitch.Reason.DATA_SWITCH_REASON_IN_CALL); registerDefaultNetworkChangeCallback(); Loading Loading @@ -521,11 +530,12 @@ public class PhoneSwitcher extends Handler { // If we use HAL_COMMAND_PREFERRED_DATA, boolean diffDetected = mHalCommandToUse != HAL_COMMAND_PREFERRED_DATA && requestsChanged; // Check if user setting of default data sub is changed. final int dataSub = mSubscriptionController.getDefaultDataSubId(); if (dataSub != mDefaultDataSubId) { sb.append(" default ").append(mDefaultDataSubId).append("->").append(dataSub); mDefaultDataSubId = dataSub; // Check if user setting of default non-opportunistic data sub is changed. final int nonOpptDataSubId = mSubscriptionController.getDefaultDataSubId(); if (nonOpptDataSubId != mNonOpptDataSubId) { sb.append(" mNonOpptDataSubId ").append(mNonOpptDataSubId).append("->") .append(nonOpptDataSubId); mNonOpptDataSubId = nonOpptDataSubId; } // Check if phoneId to subId mapping is changed. Loading @@ -541,7 +551,7 @@ public class PhoneSwitcher extends Handler { // Check if phoneId for preferred data is changed. int oldPreferredDataPhoneId = mPreferredDataPhoneId; updatePhoneIdForDefaultNetworkRequests(); updatePreferredDataPhoneId(); if (oldPreferredDataPhoneId != mPreferredDataPhoneId) { sb.append(" preferred phoneId ").append(oldPreferredDataPhoneId) .append("->").append(mPreferredDataPhoneId); Loading Loading @@ -588,8 +598,8 @@ public class PhoneSwitcher extends Handler { } if (VDBG) { log("default subId = " + mDefaultDataSubId); log("preferred subId = " + mPreferredDataSubId); log("mNonOpptDataSubId = " + mNonOpptDataSubId); log("mOpptDataSubId = " + mOpptDataSubId); for (int i = 0; i < mNumPhones; i++) { log(" phone[" + i + "] using sub[" + mPhoneSubscriptions[i] + "]"); } Loading @@ -609,8 +619,7 @@ public class PhoneSwitcher extends Handler { } } notifyActiveDataSubIdChanged(mSubscriptionController.getSubIdUsingPhoneId( mPreferredDataPhoneId)); notifyPreferredDataSubIdChanged(); // Notify all registrants. mActivePhoneRegistrants.notifyRegistrants(); Loading Loading @@ -734,23 +743,23 @@ public class PhoneSwitcher extends Handler { } private int getSubIdForDefaultNetworkRequests() { if (mSubscriptionController.isActiveSubId(mPreferredDataSubId)) { return mPreferredDataSubId; if (mSubscriptionController.isActiveSubId(mOpptDataSubId)) { return mOpptDataSubId; } else { return mDefaultDataSubId; return mNonOpptDataSubId; } } // This updates mPreferredDataPhoneId which decides which phone should // handle default network requests. private void updatePhoneIdForDefaultNetworkRequests() { if (SubscriptionManager.isValidPhoneId(mPhoneIdInCall)) { private void updatePreferredDataPhoneId() { if (SubscriptionManager.isValidPhoneId(mPhoneIdInVoiceCall)) { // 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 = mPhoneIdInCall; mPreferredDataPhoneId = mPhoneIdInVoiceCall; } else { int subId = getSubIdForDefaultNetworkRequests(); int phoneId = SubscriptionManager.INVALID_PHONE_INDEX; Loading @@ -766,6 +775,8 @@ public class PhoneSwitcher extends Handler { mPreferredDataPhoneId = phoneId; } mPreferredDataSubId = mSubscriptionController.getSubIdUsingPhoneId(mPreferredDataPhoneId); } public boolean shouldApplyNetworkRequest(NetworkRequest networkRequest, int phoneId) { Loading Loading @@ -823,7 +834,7 @@ public class PhoneSwitcher extends Handler { mValidator.stopValidation(); } if (subId == mPreferredDataSubId) { if (subId == mOpptDataSubId) { sendSetOpptCallbackHelper(callback, SET_OPPORTUNISTIC_SUB_SUCCESS); return; } Loading @@ -837,7 +848,7 @@ public class PhoneSwitcher extends Handler { mValidator.validate(subId, DEFAULT_VALIDATION_EXPIRATION_TIME, false, mValidationCallback); } else { setPreferredSubscription(subId); setOpportunisticSubscriptionInternal(subId); sendSetOpptCallbackHelper(callback, SET_OPPORTUNISTIC_SUB_SUCCESS); } } Loading @@ -851,9 +862,9 @@ public class PhoneSwitcher extends Handler { mValidator.stopValidation(); } // Set mPreferredDataSubId back to DEFAULT_SUBSCRIPTION_ID. This will trigger // data switch to mDefaultDataSubId. setPreferredSubscription(SubscriptionManager.DEFAULT_SUBSCRIPTION_ID); // Set mOpptDataSubId back to DEFAULT_SUBSCRIPTION_ID. This will trigger // data switch to mNonOpptDataSubId. setOpportunisticSubscriptionInternal(SubscriptionManager.DEFAULT_SUBSCRIPTION_ID); sendSetOpptCallbackHelper(callback, SET_OPPORTUNISTIC_SUB_SUCCESS); } Loading @@ -869,11 +880,11 @@ public class PhoneSwitcher extends Handler { /** * Set opportunistic data subscription. */ private void setPreferredSubscription(int subId) { if (mPreferredDataSubId != subId) { mPreferredDataSubId = subId; if (onEvaluate(REQUESTS_UNCHANGED, "preferredDataSubscriptionIdChanged")) { logDataSwitchEvent(mPreferredDataSubId, private void setOpportunisticSubscriptionInternal(int subId) { if (mOpptDataSubId != subId) { mOpptDataSubId = subId; if (onEvaluate(REQUESTS_UNCHANGED, "oppt data subId changed")) { logDataSwitchEvent(mOpptDataSubId, TelephonyEvent.EventState.EVENT_STATE_START, DataSwitch.Reason.DATA_SWITCH_REASON_CBRS); registerDefaultNetworkChangeCallback(); Loading @@ -884,7 +895,7 @@ public class PhoneSwitcher extends Handler { private void onValidationDone(int subId, boolean passed) { log("Network validation " + (passed ? "passed" : "failed") + " on subId " + subId); if (passed) setPreferredSubscription(subId); if (passed) setOpportunisticSubscriptionInternal(subId); // Trigger callback if needed sendSetOpptCallbackHelper(mSetOpptSubCallback, passed ? SET_OPPORTUNISTIC_SUB_SUCCESS Loading @@ -892,12 +903,14 @@ public class PhoneSwitcher extends Handler { mSetOpptSubCallback = null; } // TODO b/123598154: rename preferredDataSub to opportunisticSubId. public void trySetPreferredSubscription(int subId, boolean needValidation, /** * Notify PhoneSwitcher to try to switch data to an opportunistic subscription. */ public void trySetOpportunisticDataSubscription(int subId, boolean needValidation, ISetOpportunisticDataCallback callback) { log("Try set preferred subscription to subId " + subId log("Try set opportunistic data subscription to subId " + subId + (needValidation ? " with " : " without ") + "validation"); PhoneSwitcher.this.obtainMessage(EVENT_CHANGE_PREFERRED_SUBSCRIPTION, PhoneSwitcher.this.obtainMessage(EVENT_OPPT_SUBSCRIPTION_CHANGED, subId, needValidation ? 1 : 0, callback).sendToTarget(); } Loading @@ -915,8 +928,8 @@ public class PhoneSwitcher extends Handler { ? HAL_COMMAND_PREFERRED_DATA : HAL_COMMAND_ALLOW_DATA; } public int getPreferredDataSubscriptionId() { return mPreferredDataSubId; public int getOpportunisticDataSubscriptionId() { return mOpptDataSubId; } public int getPreferredDataPhoneId() { Loading @@ -930,19 +943,22 @@ public class PhoneSwitcher extends Handler { } private void logDataSwitchEvent(int subId, int state, int reason) { subId = subId == DEFAULT_SUBSCRIPTION_ID ? mDefaultDataSubId : subId; subId = subId == DEFAULT_SUBSCRIPTION_ID ? mNonOpptDataSubId : subId; DataSwitch dataSwitch = new DataSwitch(); dataSwitch.state = state; dataSwitch.reason = reason; TelephonyMetrics.getInstance().writeDataSwitch(subId, dataSwitch); } private void notifyActiveDataSubIdChanged(int activeDataSubId) { /** * See {@link PhoneStateListener#LISTEN_ACTIVE_DATA_SUBSCRIPTION_ID_CHANGE}. */ private void notifyPreferredDataSubIdChanged() { ITelephonyRegistry tr = ITelephonyRegistry.Stub.asInterface(ServiceManager.getService( "telephony.registry")); try { log("notifyActiveDataSubIdChanged to " + activeDataSubId); tr.notifyActiveDataSubIdChanged(activeDataSubId); log("notifyPreferredDataSubIdChanged to " + mPreferredDataSubId); tr.notifyActiveDataSubIdChanged(mPreferredDataSubId); } catch (RemoteException ex) { // Should never happen because its always available. } Loading
src/java/com/android/internal/telephony/SubscriptionController.java +2 −2 Original line number Diff line number Diff line Loading @@ -2669,7 +2669,7 @@ public class SubscriptionController extends ISub.Stub { final long token = Binder.clearCallingIdentity(); try { PhoneSwitcher.getInstance().trySetPreferredSubscription( PhoneSwitcher.getInstance().trySetOpportunisticDataSubscription( subId, needValidation, callback); } finally { Binder.restoreCallingIdentity(token); Loading @@ -2682,7 +2682,7 @@ public class SubscriptionController extends ISub.Stub { final long token = Binder.clearCallingIdentity(); try { return PhoneSwitcher.getInstance().getPreferredDataSubscriptionId(); return PhoneSwitcher.getInstance().getOpportunisticDataSubscriptionId(); } finally { Binder.restoreCallingIdentity(token); } Loading
tests/telephonytests/src/com/android/internal/telephony/PhoneSwitcherTest.java +6 −6 Original line number Diff line number Diff line Loading @@ -386,14 +386,14 @@ public class PhoneSwitcherTest extends TelephonyTest { assertTrue(mDataAllowed[0]); // Set sub 2 as preferred sub should make phone 1 activated and phone 0 deactivated. mPhoneSwitcher.trySetPreferredSubscription(2, false, null); mPhoneSwitcher.trySetOpportunisticDataSubscription(2, false, null); waitABit(); assertFalse(mDataAllowed[0]); assertTrue(mDataAllowed[1]); // Unset preferred sub should make default data sub (phone 0 / sub 1) activated again. mPhoneSwitcher.trySetPreferredSubscription(SubscriptionManager.DEFAULT_SUBSCRIPTION_ID, false, null); mPhoneSwitcher.trySetOpportunisticDataSubscription( SubscriptionManager.DEFAULT_SUBSCRIPTION_ID, false, null); waitABit(); assertTrue(mDataAllowed[0]); assertFalse(mDataAllowed[1]); Loading Loading @@ -442,7 +442,7 @@ public class PhoneSwitcherTest extends TelephonyTest { assertTrue(mPhoneSwitcher.shouldApplyNetworkRequest(mmsRequest, 1)); // Set sub 2 as preferred sub should make phone 1 preferredDataModem mPhoneSwitcher.trySetPreferredSubscription(2, false, null); mPhoneSwitcher.trySetOpportunisticDataSubscription(2, false, null); waitABit(); verify(mMockRadioConfig).setPreferredDataModem(eq(1), any()); verify(mActivePhoneSwitchHandler, times(2)).sendMessageAtTime(any(), anyLong()); Loading @@ -455,8 +455,8 @@ public class PhoneSwitcherTest extends TelephonyTest { clearInvocations(mActivePhoneSwitchHandler); // Unset preferred sub should make phone0 preferredDataModem again. mPhoneSwitcher.trySetPreferredSubscription(SubscriptionManager.DEFAULT_SUBSCRIPTION_ID, false, null); mPhoneSwitcher.trySetOpportunisticDataSubscription( SubscriptionManager.DEFAULT_SUBSCRIPTION_ID, false, null); waitABit(); verify(mMockRadioConfig).setPreferredDataModem(eq(0), any()); verify(mActivePhoneSwitchHandler, times(2)).sendMessageAtTime(any(), anyLong()); Loading