Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 3cf10e3f authored by Xiangyu/Malcolm Chen's avatar Xiangyu/Malcolm Chen Committed by android-build-merger
Browse files

Merge changes from topic "128645056"

am: bb873b34

Change-Id: I8cf9bd81cb4ea9e68599589baaee16a16ef96e1a
parents a3cd9c3d bb873b34
Loading
Loading
Loading
Loading
+7 −5
Original line number Original line Diff line number Diff line
@@ -18,11 +18,11 @@ package com.android.internal.telephony;


import static android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID;
import static android.telephony.SubscriptionManager.INVALID_SUBSCRIPTION_ID;
import static android.telephony.TelephonyManager.ACTION_PRIMARY_SUBSCRIPTION_LIST_CHANGED;
import static android.telephony.TelephonyManager.ACTION_PRIMARY_SUBSCRIPTION_LIST_CHANGED;
import static android.telephony.TelephonyManager.EXTRA_DEFAULT_SUBSCRIPTION_ID;
import static android.telephony.TelephonyManager.EXTRA_DEFAULT_SUBSCRIPTION_SELECT_FOR_ALL_TYPES;
import static android.telephony.TelephonyManager.EXTRA_DEFAULT_SUBSCRIPTION_SELECT_TYPE;
import static android.telephony.TelephonyManager.EXTRA_DEFAULT_SUBSCRIPTION_SELECT_TYPE;
import static android.telephony.TelephonyManager.EXTRA_DEFAULT_SUBSCRIPTION_SELECT_TYPE_ALL;
import static android.telephony.TelephonyManager.EXTRA_DEFAULT_SUBSCRIPTION_SELECT_TYPE_DATA;
import static android.telephony.TelephonyManager.EXTRA_DEFAULT_SUBSCRIPTION_SELECT_TYPE_DATA;
import static android.telephony.TelephonyManager.EXTRA_DEFAULT_SUBSCRIPTION_SELECT_TYPE_NONE;
import static android.telephony.TelephonyManager.EXTRA_DEFAULT_SUBSCRIPTION_SELECT_TYPE_NONE;
import static android.telephony.TelephonyManager.EXTRA_SUBSCRIPTION_ID;


import android.content.Context;
import android.content.Context;
import android.content.Intent;
import android.content.Intent;
@@ -31,6 +31,7 @@ import android.provider.Settings;
import android.provider.Settings.SettingNotFoundException;
import android.provider.Settings.SettingNotFoundException;
import android.telephony.SubscriptionInfo;
import android.telephony.SubscriptionInfo;
import android.telephony.SubscriptionManager;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
import android.util.Log;
import android.util.Log;


import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.annotations.VisibleForTesting;
@@ -246,6 +247,7 @@ public class MultiSimSettingController {


    private void showSimSelectDialogIfNeeded(List<SubscriptionInfo> prevPrimarySubs,
    private void showSimSelectDialogIfNeeded(List<SubscriptionInfo> prevPrimarySubs,
            boolean dataSelected, boolean voiceSelected, boolean smsSelected) {
            boolean dataSelected, boolean voiceSelected, boolean smsSelected) {
        @TelephonyManager.DefaultSubscriptionSelectType
        int dialogType = EXTRA_DEFAULT_SUBSCRIPTION_SELECT_TYPE_NONE;
        int dialogType = EXTRA_DEFAULT_SUBSCRIPTION_SELECT_TYPE_NONE;
        int preferredSubId = INVALID_SUBSCRIPTION_ID;
        int preferredSubId = INVALID_SUBSCRIPTION_ID;
        boolean primarySubRemoved = prevPrimarySubs != null
        boolean primarySubRemoved = prevPrimarySubs != null
@@ -259,7 +261,7 @@ public class MultiSimSettingController {
        // user to select default for data as it's most important.
        // user to select default for data as it's most important.
        if (mPrimarySubList.size() == 1 && primarySubRemoved
        if (mPrimarySubList.size() == 1 && primarySubRemoved
                && (!dataSelected || !smsSelected || !voiceSelected)) {
                && (!dataSelected || !smsSelected || !voiceSelected)) {
            dialogType = EXTRA_DEFAULT_SUBSCRIPTION_SELECT_FOR_ALL_TYPES;
            dialogType = EXTRA_DEFAULT_SUBSCRIPTION_SELECT_TYPE_ALL;
            preferredSubId = mPrimarySubList.get(0).getSubscriptionId();
            preferredSubId = mPrimarySubList.get(0).getSubscriptionId();
        } else if (mPrimarySubList.size() > 1 && (!dataSelected || primarySubAdded)) {
        } else if (mPrimarySubList.size() > 1 && (!dataSelected || primarySubAdded)) {
            dialogType = EXTRA_DEFAULT_SUBSCRIPTION_SELECT_TYPE_DATA;
            dialogType = EXTRA_DEFAULT_SUBSCRIPTION_SELECT_TYPE_DATA;
@@ -272,8 +274,8 @@ public class MultiSimSettingController {
                    "com.android.settings.sim.SimSelectNotification");
                    "com.android.settings.sim.SimSelectNotification");
            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
            intent.putExtra(EXTRA_DEFAULT_SUBSCRIPTION_SELECT_TYPE, dialogType);
            intent.putExtra(EXTRA_DEFAULT_SUBSCRIPTION_SELECT_TYPE, dialogType);
            if (dialogType == EXTRA_DEFAULT_SUBSCRIPTION_SELECT_FOR_ALL_TYPES) {
            if (dialogType == EXTRA_DEFAULT_SUBSCRIPTION_SELECT_TYPE_ALL) {
                intent.putExtra(EXTRA_DEFAULT_SUBSCRIPTION_ID, preferredSubId);
                intent.putExtra(EXTRA_SUBSCRIPTION_ID, preferredSubId);
            }
            }
            mContext.sendBroadcast(intent);
            mContext.sendBroadcast(intent);
        }
        }
+112 −79
Original line number Original line Diff line number Diff line
@@ -40,6 +40,7 @@ import android.net.NetworkFactory;
import android.net.NetworkRequest;
import android.net.NetworkRequest;
import android.net.NetworkSpecifier;
import android.net.NetworkSpecifier;
import android.net.StringNetworkSpecifier;
import android.net.StringNetworkSpecifier;
import android.os.AsyncResult;
import android.os.Handler;
import android.os.Handler;
import android.os.Looper;
import android.os.Looper;
import android.os.Message;
import android.os.Message;
@@ -82,6 +83,7 @@ public class PhoneSwitcher extends Handler {
    private static final boolean VDBG = false;
    private static final boolean VDBG = false;


    private static final int DEFAULT_NETWORK_CHANGE_TIMEOUT_MS = 5000;
    private static final int DEFAULT_NETWORK_CHANGE_TIMEOUT_MS = 5000;
    private static final int MODEM_COMMAND_RETRY_PERIOD_MS     = 5000;


    private final List<DcRequest> mPrioritizedDcRequests = new ArrayList<DcRequest>();
    private final List<DcRequest> mPrioritizedDcRequests = new ArrayList<DcRequest>();
    private final RegistrantList mActivePhoneRegistrants;
    private final RegistrantList mActivePhoneRegistrants;
@@ -105,35 +107,46 @@ public class PhoneSwitcher extends Handler {
    private int mMaxActivePhones;
    private int mMaxActivePhones;
    private static PhoneSwitcher sPhoneSwitcher = null;
    private static PhoneSwitcher sPhoneSwitcher = null;


    // Default subscription ID from user setting.
    // Which primary (non-opportunistic) subscription is set as data subscription among all primary
    private int mDefaultDataSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
    // subscriptions. This value usually comes from user setting, and it's the subscription used for
    // Internet data if mOpptDataSubId is not set.
    private int mPrimaryDataSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;


    // If mPreferredDataSubId is an active subscription, it overrides
    // mOpptDataSubId must be an active subscription. If it's set, it overrides mPrimaryDataSubId
    // mDefaultDataSubId and decides:
    // to be used for Internet data.
    // 1. In modem layer, which subscription is preferred to have data traffic on.
    private int mOpptDataSubId = SubscriptionManager.DEFAULT_SUBSCRIPTION_ID;
    // 2. In TelephonyNetworkFactory, which subscription will apply default network requests, which

    //    are requests without specifying a subId.
    // The phone ID that has an active voice call. If set, and its mobile data setting is on,
    private int mPreferredDataSubId = SubscriptionManager.DEFAULT_SUBSCRIPTION_ID;
    // it will become the mPreferredDataPhoneId.
    private int mPhoneIdInVoiceCall = SubscriptionManager.INVALID_PHONE_INDEX;


    @VisibleForTesting
    @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, mPrimaryDataSubId and
    // mPhoneIdInVoiceCall above.
    protected int mPreferredDataPhoneId = SubscriptionManager.INVALID_PHONE_INDEX;
    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 ISetOpportunisticDataCallback mSetOpptSubCallback;


    private static final int EVENT_DEFAULT_SUBSCRIPTION_CHANGED   = 101;
    private static final int EVENT_PRIMARY_DATA_SUB_CHANGED       = 101;
    private static final int EVENT_SUBSCRIPTION_CHANGED           = 102;
    private static final int EVENT_SUBSCRIPTION_CHANGED           = 102;
    private static final int EVENT_REQUEST_NETWORK                = 103;
    private static final int EVENT_REQUEST_NETWORK                = 103;
    private static final int EVENT_RELEASE_NETWORK                = 104;
    private static final int EVENT_RELEASE_NETWORK                = 104;
    private static final int EVENT_EMERGENCY_TOGGLE               = 105;
    private static final int EVENT_EMERGENCY_TOGGLE               = 105;
    private static final int EVENT_RADIO_CAPABILITY_CHANGED       = 106;
    private static final int EVENT_RADIO_CAPABILITY_CHANGED       = 106;
    private static final int EVENT_CHANGE_PREFERRED_SUBSCRIPTION  = 107;
    private static final int EVENT_OPPT_DATA_SUB_CHANGED          = 107;
    private static final int EVENT_RADIO_AVAILABLE                = 108;
    private static final int EVENT_RADIO_AVAILABLE                = 108;
    private static final int EVENT_PHONE_IN_CALL_CHANGED          = 109;
    private static final int EVENT_PHONE_IN_CALL_CHANGED          = 109;
    private static final int EVENT_NETWORK_VALIDATION_DONE        = 110;
    private static final int EVENT_NETWORK_VALIDATION_DONE        = 110;
    private static final int EVENT_REMOVE_DEFAULT_NETWORK_CHANGE_CALLBACK = 111;
    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;


    // Depending on version of IRadioConfig, we need to send either RIL_REQUEST_ALLOW_DATA if it's
    // 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
    // 1.0, or RIL_REQUEST_SET_PREFERRED_DATA if it's 1.1 or later. So internally mHalCommandToUse
@@ -161,7 +174,7 @@ public class PhoneSwitcher extends Handler {
                    if (mConnectivityManager.getNetworkCapabilities(network)
                    if (mConnectivityManager.getNetworkCapabilities(network)
                            .hasTransport(TRANSPORT_CELLULAR)) {
                            .hasTransport(TRANSPORT_CELLULAR)) {
                        logDataSwitchEvent(
                        logDataSwitchEvent(
                                mPreferredDataSubId,
                                mOpptDataSubId,
                                TelephonyEvent.EventState.EVENT_STATE_END,
                                TelephonyEvent.EventState.EVENT_STATE_END,
                                TelephonyEvent.DataSwitch.Reason.DATA_SWITCH_REASON_UNKNOWN);
                                TelephonyEvent.DataSwitch.Reason.DATA_SWITCH_REASON_UNKNOWN);
                    }
                    }
@@ -236,21 +249,21 @@ public class PhoneSwitcher extends Handler {


            @Override
            @Override
            public void onPreciseCallStateChanged(PreciseCallState callState) {
            public void onPreciseCallStateChanged(PreciseCallState callState) {
                int oldPhoneIdInCall = mPhoneIdInCall;
                int oldPhoneIdInVoiceCall = mPhoneIdInVoiceCall;
                // If there's no active call, the value will become INVALID_PHONE_INDEX
                // 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
                // and internet data will be switched back to system selected or user selected
                // subscription.
                // subscription.
                mPhoneIdInCall = SubscriptionManager.INVALID_PHONE_INDEX;
                mPhoneIdInVoiceCall = SubscriptionManager.INVALID_PHONE_INDEX;
                for (Phone phone : mPhones) {
                for (Phone phone : mPhones) {
                    if (isCallActive(phone) || isCallActive(phone.getImsPhone())) {
                    if (isCallActive(phone) || isCallActive(phone.getImsPhone())) {
                        mPhoneIdInCall = phone.getPhoneId();
                        mPhoneIdInVoiceCall = phone.getPhoneId();
                        break;
                        break;
                    }
                    }
                }
                }


                if (mPhoneIdInCall != oldPhoneIdInCall) {
                if (mPhoneIdInVoiceCall != oldPhoneIdInVoiceCall) {
                    log("mPhoneIdInCall changed from" + oldPhoneIdInCall
                    log("mPhoneIdInVoiceCall changed from" + oldPhoneIdInVoiceCall
                            + " to " + mPhoneIdInCall);
                            + " to " + mPhoneIdInVoiceCall);
                    Message msg = PhoneSwitcher.this.obtainMessage(EVENT_PHONE_IN_CALL_CHANGED);
                    Message msg = PhoneSwitcher.this.obtainMessage(EVENT_PHONE_IN_CALL_CHANGED);
                    msg.sendToTarget();
                    msg.sendToTarget();
                }
                }
@@ -320,7 +333,7 @@ public class PhoneSwitcher extends Handler {
    private final BroadcastReceiver mDefaultDataChangedReceiver = new BroadcastReceiver() {
    private final BroadcastReceiver mDefaultDataChangedReceiver = new BroadcastReceiver() {
        @Override
        @Override
        public void onReceive(Context context, Intent intent) {
        public void onReceive(Context context, Intent intent) {
            Message msg = PhoneSwitcher.this.obtainMessage(EVENT_DEFAULT_SUBSCRIPTION_CHANGED);
            Message msg = PhoneSwitcher.this.obtainMessage(EVENT_PRIMARY_DATA_SUB_CHANGED);
            msg.sendToTarget();
            msg.sendToTarget();
        }
        }
    };
    };
@@ -341,9 +354,9 @@ public class PhoneSwitcher extends Handler {
                onEvaluate(REQUESTS_UNCHANGED, "subChanged");
                onEvaluate(REQUESTS_UNCHANGED, "subChanged");
                break;
                break;
            }
            }
            case EVENT_DEFAULT_SUBSCRIPTION_CHANGED: {
            case EVENT_PRIMARY_DATA_SUB_CHANGED: {
                if (onEvaluate(REQUESTS_UNCHANGED, "defaultChanged")) {
                if (onEvaluate(REQUESTS_UNCHANGED, "primary data subId changed")) {
                    logDataSwitchEvent(mPreferredDataSubId,
                    logDataSwitchEvent(mOpptDataSubId,
                            TelephonyEvent.EventState.EVENT_STATE_START,
                            TelephonyEvent.EventState.EVENT_STATE_START,
                            DataSwitch.Reason.DATA_SWITCH_REASON_MANUAL);
                            DataSwitch.Reason.DATA_SWITCH_REASON_MANUAL);
                    registerDefaultNetworkChangeCallback();
                    registerDefaultNetworkChangeCallback();
@@ -363,10 +376,11 @@ public class PhoneSwitcher extends Handler {
                break;
                break;
            }
            }
            case EVENT_RADIO_CAPABILITY_CHANGED: {
            case EVENT_RADIO_CAPABILITY_CHANGED: {
                resendRilCommands(msg);
                final int phoneId = msg.arg1;
                sendRilCommands(phoneId);
                break;
                break;
            }
            }
            case EVENT_CHANGE_PREFERRED_SUBSCRIPTION: {
            case EVENT_OPPT_DATA_SUB_CHANGED: {
                int subId = msg.arg1;
                int subId = msg.arg1;
                boolean needValidation = (msg.arg2 == 1);
                boolean needValidation = (msg.arg2 == 1);
                ISetOpportunisticDataCallback callback =
                ISetOpportunisticDataCallback callback =
@@ -385,7 +399,7 @@ public class PhoneSwitcher extends Handler {
            }
            }
            case EVENT_PHONE_IN_CALL_CHANGED: {
            case EVENT_PHONE_IN_CALL_CHANGED: {
                if (onEvaluate(REQUESTS_UNCHANGED, "EVENT_PHONE_IN_CALL_CHANGED")) {
                if (onEvaluate(REQUESTS_UNCHANGED, "EVENT_PHONE_IN_CALL_CHANGED")) {
                    logDataSwitchEvent(mPreferredDataSubId,
                    logDataSwitchEvent(mOpptDataSubId,
                            TelephonyEvent.EventState.EVENT_STATE_START,
                            TelephonyEvent.EventState.EVENT_STATE_START,
                            DataSwitch.Reason.DATA_SWITCH_REASON_IN_CALL);
                            DataSwitch.Reason.DATA_SWITCH_REASON_IN_CALL);
                    registerDefaultNetworkChangeCallback();
                    registerDefaultNetworkChangeCallback();
@@ -402,6 +416,21 @@ public class PhoneSwitcher extends Handler {
                removeDefaultNetworkChangeCallback();
                removeDefaultNetworkChangeCallback();
                break;
                break;
            }
            }
            case EVENT_MODEM_COMMAND_DONE: {
                AsyncResult ar = (AsyncResult) msg.obj;
                if (ar != null && ar.exception != null) {
                    int phoneId = (int) ar.userObj;
                    log("Modem command failed. with exception " + ar.exception);
                    sendMessageDelayed(Message.obtain(this, EVENT_MODEM_COMMAND_RETRY,
                            phoneId), MODEM_COMMAND_RETRY_PERIOD_MS);
                }
                break;
            }
            case EVENT_MODEM_COMMAND_RETRY: {
                int phoneId = (int) msg.obj;
                log("Resend modem command on phone " + phoneId);
                sendRilCommands(phoneId);
            }
        }
        }
    }
    }


@@ -524,11 +553,12 @@ public class PhoneSwitcher extends Handler {
        // If we use HAL_COMMAND_PREFERRED_DATA,
        // If we use HAL_COMMAND_PREFERRED_DATA,
        boolean diffDetected = mHalCommandToUse != HAL_COMMAND_PREFERRED_DATA && requestsChanged;
        boolean diffDetected = mHalCommandToUse != HAL_COMMAND_PREFERRED_DATA && requestsChanged;


        // Check if user setting of default data sub is changed.
        // Check if user setting of default non-opportunistic data sub is changed.
        final int dataSub = mSubscriptionController.getDefaultDataSubId();
        final int primaryDataSubId = mSubscriptionController.getDefaultDataSubId();
        if (dataSub != mDefaultDataSubId) {
        if (primaryDataSubId != mPrimaryDataSubId) {
            sb.append(" default ").append(mDefaultDataSubId).append("->").append(dataSub);
            sb.append(" mPrimaryDataSubId ").append(mPrimaryDataSubId).append("->")
            mDefaultDataSubId = dataSub;
                .append(primaryDataSubId);
            mPrimaryDataSubId = primaryDataSubId;
        }
        }


        // Check if phoneId to subId mapping is changed.
        // Check if phoneId to subId mapping is changed.
@@ -544,7 +574,7 @@ public class PhoneSwitcher extends Handler {


        // Check if phoneId for preferred data is changed.
        // Check if phoneId for preferred data is changed.
        int oldPreferredDataPhoneId = mPreferredDataPhoneId;
        int oldPreferredDataPhoneId = mPreferredDataPhoneId;
        updatePhoneIdForDefaultNetworkRequests();
        updatePreferredDataPhoneId();
        if (oldPreferredDataPhoneId != mPreferredDataPhoneId) {
        if (oldPreferredDataPhoneId != mPreferredDataPhoneId) {
            sb.append(" preferred phoneId ").append(oldPreferredDataPhoneId)
            sb.append(" preferred phoneId ").append(oldPreferredDataPhoneId)
                    .append("->").append(mPreferredDataPhoneId);
                    .append("->").append(mPreferredDataPhoneId);
@@ -555,13 +585,12 @@ public class PhoneSwitcher extends Handler {
            log("evaluating due to " + sb.toString());
            log("evaluating due to " + sb.toString());
            if (mHalCommandToUse == HAL_COMMAND_PREFERRED_DATA) {
            if (mHalCommandToUse == HAL_COMMAND_PREFERRED_DATA) {
                // With HAL_COMMAND_PREFERRED_DATA, all phones are assumed to allow PS attach.
                // With HAL_COMMAND_PREFERRED_DATA, all phones are assumed to allow PS attach.
                // So marking all phone as active.
                // So marking all phone as active, and the phone with mPreferredDataPhoneId
                // will send radioConfig command.
                for (int phoneId = 0; phoneId < mNumPhones; phoneId++) {
                for (int phoneId = 0; phoneId < mNumPhones; phoneId++) {
                    activate(phoneId);
                    mPhoneStates[phoneId].active = true;
                }
                if (SubscriptionManager.isUsableSubIdValue(mPreferredDataPhoneId)) {
                    mRadioConfig.setPreferredDataModem(mPreferredDataPhoneId, null);
                }
                }
                sendRilCommands(mPreferredDataPhoneId);
            } else {
            } else {
                List<Integer> newActivePhones = new ArrayList<Integer>();
                List<Integer> newActivePhones = new ArrayList<Integer>();


@@ -591,8 +620,8 @@ public class PhoneSwitcher extends Handler {
                }
                }


                if (VDBG) {
                if (VDBG) {
                    log("default subId = " + mDefaultDataSubId);
                    log("mPrimaryDataSubId = " + mPrimaryDataSubId);
                    log("preferred subId = " + mPreferredDataSubId);
                    log("mOpptDataSubId = " + mOpptDataSubId);
                    for (int i = 0; i < mNumPhones; i++) {
                    for (int i = 0; i < mNumPhones; i++) {
                        log(" phone[" + i + "] using sub[" + mPhoneSubscriptions[i] + "]");
                        log(" phone[" + i + "] using sub[" + mPhoneSubscriptions[i] + "]");
                    }
                    }
@@ -612,8 +641,7 @@ public class PhoneSwitcher extends Handler {
                }
                }
            }
            }


            notifyActiveDataSubIdChanged(mSubscriptionController.getSubIdUsingPhoneId(
            notifyPreferredDataSubIdChanged();
                    mPreferredDataPhoneId));


            // Notify all registrants.
            // Notify all registrants.
            mActivePhoneRegistrants.notifyRegistrants();
            mActivePhoneRegistrants.notifyRegistrants();
@@ -642,12 +670,7 @@ public class PhoneSwitcher extends Handler {
        state.active = active;
        state.active = active;
        log((active ? "activate " : "deactivate ") + phoneId);
        log((active ? "activate " : "deactivate ") + phoneId);
        state.lastRequested = System.currentTimeMillis();
        state.lastRequested = System.currentTimeMillis();
        if (mHalCommandToUse == HAL_COMMAND_ALLOW_DATA || mHalCommandToUse == HAL_COMMAND_UNKNOWN) {
        sendRilCommands(phoneId);
            // Skip ALLOW_DATA for single SIM device
            if (mNumPhones > 1) {
                mCommandsInterfaces[phoneId].setDataAllowed(active, null);
            }
        }
    }
    }


    /**
    /**
@@ -661,15 +684,18 @@ public class PhoneSwitcher extends Handler {
        msg.sendToTarget();
        msg.sendToTarget();
    }
    }


    private void resendRilCommands(Message msg) {
    private void sendRilCommands(int phoneId) {
        final int phoneId = msg.arg1;
        if (!SubscriptionManager.isValidPhoneId(phoneId) || phoneId >= mNumPhones) return;

        Message message = Message.obtain(this, EVENT_MODEM_COMMAND_DONE, phoneId);
        if (mHalCommandToUse == HAL_COMMAND_ALLOW_DATA || mHalCommandToUse == HAL_COMMAND_UNKNOWN) {
        if (mHalCommandToUse == HAL_COMMAND_ALLOW_DATA || mHalCommandToUse == HAL_COMMAND_UNKNOWN) {
            // Skip ALLOW_DATA for single SIM device
            // Skip ALLOW_DATA for single SIM device
            if (mNumPhones > 1) {
            if (mNumPhones > 1) {
                mCommandsInterfaces[phoneId].setDataAllowed(isPhoneActive(phoneId), null);
                mCommandsInterfaces[phoneId].setDataAllowed(isPhoneActive(phoneId), message);
            }
            }
        } else {
        } else if (phoneId == mPreferredDataPhoneId) {
            mRadioConfig.setPreferredDataModem(mPreferredDataPhoneId, null);
            // Only setPreferredDataModem if the phoneId equals to current mPreferredDataPhoneId.
            mRadioConfig.setPreferredDataModem(mPreferredDataPhoneId, message);
        }
        }
    }
    }


@@ -737,23 +763,23 @@ public class PhoneSwitcher extends Handler {
    }
    }


    private int getSubIdForDefaultNetworkRequests() {
    private int getSubIdForDefaultNetworkRequests() {
        if (mSubscriptionController.isActiveSubId(mPreferredDataSubId)) {
        if (mSubscriptionController.isActiveSubId(mOpptDataSubId)) {
            return mPreferredDataSubId;
            return mOpptDataSubId;
        } else {
        } else {
            return mDefaultDataSubId;
            return mPrimaryDataSubId;
        }
        }
    }
    }


    // This updates mPreferredDataPhoneId which decides which phone should
    // This updates mPreferredDataPhoneId which decides which phone should
    // handle default network requests.
    // handle default network requests.
    private void updatePhoneIdForDefaultNetworkRequests() {
    private void updatePreferredDataPhoneId() {
        if (SubscriptionManager.isValidPhoneId(mPhoneIdInCall)) {
        if (SubscriptionManager.isValidPhoneId(mPhoneIdInVoiceCall)) {
            // If a phone is in call and user enabled its mobile data, we
            // If a phone is in call and user enabled its mobile data, we
            // should switch internet connection to it. Because the other modem
            // should switch internet connection to it. Because the other modem
            // will lose data connection anyway.
            // will lose data connection anyway.
            // TODO: validate network first.
            // TODO: validate network first.


            mPreferredDataPhoneId = mPhoneIdInCall;
            mPreferredDataPhoneId = mPhoneIdInVoiceCall;
        } else {
        } else {
            int subId = getSubIdForDefaultNetworkRequests();
            int subId = getSubIdForDefaultNetworkRequests();
            int phoneId = SubscriptionManager.INVALID_PHONE_INDEX;
            int phoneId = SubscriptionManager.INVALID_PHONE_INDEX;
@@ -769,6 +795,8 @@ public class PhoneSwitcher extends Handler {


            mPreferredDataPhoneId = phoneId;
            mPreferredDataPhoneId = phoneId;
        }
        }

        mPreferredDataSubId = mSubscriptionController.getSubIdUsingPhoneId(mPreferredDataPhoneId);
    }
    }


    public boolean shouldApplyNetworkRequest(NetworkRequest networkRequest, int phoneId) {
    public boolean shouldApplyNetworkRequest(NetworkRequest networkRequest, int phoneId) {
@@ -826,7 +854,7 @@ public class PhoneSwitcher extends Handler {
            mValidator.stopValidation();
            mValidator.stopValidation();
        }
        }


        if (subId == mPreferredDataSubId) {
        if (subId == mOpptDataSubId) {
            sendSetOpptCallbackHelper(callback, SET_OPPORTUNISTIC_SUB_SUCCESS);
            sendSetOpptCallbackHelper(callback, SET_OPPORTUNISTIC_SUB_SUCCESS);
            return;
            return;
        }
        }
@@ -840,7 +868,7 @@ public class PhoneSwitcher extends Handler {
            mValidator.validate(subId, DEFAULT_VALIDATION_EXPIRATION_TIME,
            mValidator.validate(subId, DEFAULT_VALIDATION_EXPIRATION_TIME,
                    false, mValidationCallback);
                    false, mValidationCallback);
        } else {
        } else {
            setPreferredSubscription(subId);
            setOpportunisticSubscriptionInternal(subId);
            sendSetOpptCallbackHelper(callback, SET_OPPORTUNISTIC_SUB_SUCCESS);
            sendSetOpptCallbackHelper(callback, SET_OPPORTUNISTIC_SUB_SUCCESS);
        }
        }
    }
    }
@@ -854,9 +882,9 @@ public class PhoneSwitcher extends Handler {
            mValidator.stopValidation();
            mValidator.stopValidation();
        }
        }


        // Set mPreferredDataSubId back to DEFAULT_SUBSCRIPTION_ID. This will trigger
        // Set mOpptDataSubId back to DEFAULT_SUBSCRIPTION_ID. This will trigger
        // data switch to mDefaultDataSubId.
        // data switch to mPrimaryDataSubId.
        setPreferredSubscription(SubscriptionManager.DEFAULT_SUBSCRIPTION_ID);
        setOpportunisticSubscriptionInternal(SubscriptionManager.DEFAULT_SUBSCRIPTION_ID);
        sendSetOpptCallbackHelper(callback, SET_OPPORTUNISTIC_SUB_SUCCESS);
        sendSetOpptCallbackHelper(callback, SET_OPPORTUNISTIC_SUB_SUCCESS);
    }
    }


@@ -872,11 +900,11 @@ public class PhoneSwitcher extends Handler {
    /**
    /**
     * Set opportunistic data subscription.
     * Set opportunistic data subscription.
     */
     */
    private void setPreferredSubscription(int subId) {
    private void setOpportunisticSubscriptionInternal(int subId) {
        if (mPreferredDataSubId != subId) {
        if (mOpptDataSubId != subId) {
            mPreferredDataSubId = subId;
            mOpptDataSubId = subId;
            if (onEvaluate(REQUESTS_UNCHANGED, "preferredDataSubscriptionIdChanged")) {
            if (onEvaluate(REQUESTS_UNCHANGED, "oppt data subId changed")) {
                logDataSwitchEvent(mPreferredDataSubId,
                logDataSwitchEvent(mOpptDataSubId,
                        TelephonyEvent.EventState.EVENT_STATE_START,
                        TelephonyEvent.EventState.EVENT_STATE_START,
                        DataSwitch.Reason.DATA_SWITCH_REASON_CBRS);
                        DataSwitch.Reason.DATA_SWITCH_REASON_CBRS);
                registerDefaultNetworkChangeCallback();
                registerDefaultNetworkChangeCallback();
@@ -887,7 +915,7 @@ public class PhoneSwitcher extends Handler {
    private void onValidationDone(int subId, boolean passed) {
    private void onValidationDone(int subId, boolean passed) {
        log("Network validation " + (passed ? "passed" : "failed")
        log("Network validation " + (passed ? "passed" : "failed")
                + " on subId " + subId);
                + " on subId " + subId);
        if (passed) setPreferredSubscription(subId);
        if (passed) setOpportunisticSubscriptionInternal(subId);


        // Trigger callback if needed
        // Trigger callback if needed
        sendSetOpptCallbackHelper(mSetOpptSubCallback, passed ? SET_OPPORTUNISTIC_SUB_SUCCESS
        sendSetOpptCallbackHelper(mSetOpptSubCallback, passed ? SET_OPPORTUNISTIC_SUB_SUCCESS
@@ -895,12 +923,14 @@ public class PhoneSwitcher extends Handler {
        mSetOpptSubCallback = null;
        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) {
            ISetOpportunisticDataCallback callback) {
        log("Try set preferred subscription to subId " + subId
        log("Try set opportunistic data subscription to subId " + subId
                + (needValidation ? " with " : " without ") + "validation");
                + (needValidation ? " with " : " without ") + "validation");
        PhoneSwitcher.this.obtainMessage(EVENT_CHANGE_PREFERRED_SUBSCRIPTION,
        PhoneSwitcher.this.obtainMessage(EVENT_OPPT_DATA_SUB_CHANGED,
                subId, needValidation ? 1 : 0, callback).sendToTarget();
                subId, needValidation ? 1 : 0, callback).sendToTarget();
    }
    }


@@ -918,8 +948,8 @@ public class PhoneSwitcher extends Handler {
                ? HAL_COMMAND_PREFERRED_DATA : HAL_COMMAND_ALLOW_DATA;
                ? HAL_COMMAND_PREFERRED_DATA : HAL_COMMAND_ALLOW_DATA;
    }
    }


    public int getPreferredDataSubscriptionId() {
    public int getOpportunisticDataSubscriptionId() {
        return mPreferredDataSubId;
        return mOpptDataSubId;
    }
    }


    public int getPreferredDataPhoneId() {
    public int getPreferredDataPhoneId() {
@@ -933,19 +963,22 @@ public class PhoneSwitcher extends Handler {
    }
    }


    private void logDataSwitchEvent(int subId, int state, int reason) {
    private void logDataSwitchEvent(int subId, int state, int reason) {
        subId = subId == DEFAULT_SUBSCRIPTION_ID ? mDefaultDataSubId : subId;
        subId = subId == DEFAULT_SUBSCRIPTION_ID ? mPrimaryDataSubId : subId;
        DataSwitch dataSwitch = new DataSwitch();
        DataSwitch dataSwitch = new DataSwitch();
        dataSwitch.state = state;
        dataSwitch.state = state;
        dataSwitch.reason = reason;
        dataSwitch.reason = reason;
        TelephonyMetrics.getInstance().writeDataSwitch(subId, dataSwitch);
        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(
        ITelephonyRegistry tr = ITelephonyRegistry.Stub.asInterface(ServiceManager.getService(
                "telephony.registry"));
                "telephony.registry"));
        try {
        try {
            log("notifyActiveDataSubIdChanged to " + activeDataSubId);
            log("notifyPreferredDataSubIdChanged to " + mPreferredDataSubId);
            tr.notifyActiveDataSubIdChanged(activeDataSubId);
            tr.notifyActiveDataSubIdChanged(mPreferredDataSubId);
        } catch (RemoteException ex) {
        } catch (RemoteException ex) {
            // Should never happen because its always available.
            // Should never happen because its always available.
        }
        }
+44 −38
Original line number Original line Diff line number Diff line
@@ -2054,6 +2054,8 @@ public class SubscriptionController extends ISub.Stub {
    public void setDefaultDataSubId(int subId) {
    public void setDefaultDataSubId(int subId) {
        enforceModifyPhoneState("setDefaultDataSubId");
        enforceModifyPhoneState("setDefaultDataSubId");


        final long identity = Binder.clearCallingIdentity();
        try {
            if (subId == SubscriptionManager.DEFAULT_SUBSCRIPTION_ID) {
            if (subId == SubscriptionManager.DEFAULT_SUBSCRIPTION_ID) {
                throw new RuntimeException("setDefaultDataSubId called with DEFAULT_SUB_ID");
                throw new RuntimeException("setDefaultDataSubId called with DEFAULT_SUB_ID");
            }
            }
@@ -2078,7 +2080,8 @@ public class SubscriptionController extends ISub.Stub {
                        // TODO Handle the general case of N modems and M subscriptions.
                        // TODO Handle the general case of N modems and M subscriptions.
                        raf = proxyController.getMinRafSupported();
                        raf = proxyController.getMinRafSupported();
                    }
                    }
                logdl("[setDefaultDataSubId] phoneId=" + phoneId + " subId=" + id + " RAF=" + raf);
                    logdl("[setDefaultDataSubId] phoneId=" + phoneId + " subId=" + id + " RAF="
                            + raf);
                    rafs[phoneId] = new RadioAccessFamily(phoneId, raf);
                    rafs[phoneId] = new RadioAccessFamily(phoneId, raf);
                }
                }
                if (atLeastOneMatch) {
                if (atLeastOneMatch) {
@@ -2095,6 +2098,9 @@ public class SubscriptionController extends ISub.Stub {
                    Settings.Global.MULTI_SIM_DATA_CALL_SUBSCRIPTION, subId);
                    Settings.Global.MULTI_SIM_DATA_CALL_SUBSCRIPTION, subId);
            MultiSimSettingController.getInstance().onDefaultDataSettingChanged();
            MultiSimSettingController.getInstance().onDefaultDataSettingChanged();
            broadcastDefaultDataSubIdChanged(subId);
            broadcastDefaultDataSubIdChanged(subId);
        } finally {
            Binder.restoreCallingIdentity(identity);
        }
    }
    }


    @UnsupportedAppUsage
    @UnsupportedAppUsage
@@ -2673,7 +2679,7 @@ public class SubscriptionController extends ISub.Stub {
        final long token = Binder.clearCallingIdentity();
        final long token = Binder.clearCallingIdentity();


        try {
        try {
            PhoneSwitcher.getInstance().trySetPreferredSubscription(
            PhoneSwitcher.getInstance().trySetOpportunisticDataSubscription(
                    subId, needValidation, callback);
                    subId, needValidation, callback);
        } finally {
        } finally {
            Binder.restoreCallingIdentity(token);
            Binder.restoreCallingIdentity(token);
@@ -2686,7 +2692,7 @@ public class SubscriptionController extends ISub.Stub {
        final long token = Binder.clearCallingIdentity();
        final long token = Binder.clearCallingIdentity();


        try {
        try {
            return PhoneSwitcher.getInstance().getPreferredDataSubscriptionId();
            return PhoneSwitcher.getInstance().getOpportunisticDataSubscriptionId();
        } finally {
        } finally {
            Binder.restoreCallingIdentity(token);
            Binder.restoreCallingIdentity(token);
        }
        }