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

Commit a4905a43 authored by Jack Yu's avatar Jack Yu Committed by Android (Google) Code Review
Browse files

Merge "Add support to retry for DDS switch failures" into sc-dev

parents 1cd24c56 12f290d9
Loading
Loading
Loading
Loading
+153 −12
Original line number Diff line number Diff line
@@ -54,6 +54,7 @@ import android.os.RemoteException;
import android.telephony.CarrierConfigManager;
import android.telephony.PhoneCapability;
import android.telephony.PhoneStateListener;
import android.telephony.SubscriptionInfo;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
import android.telephony.TelephonyRegistryManager;
@@ -78,7 +79,9 @@ import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.concurrent.CompletableFuture;

/**
@@ -271,6 +274,7 @@ public class PhoneSwitcher extends Handler {
    @VisibleForTesting
    public static final int EVENT_MULTI_SIM_CONFIG_CHANGED        = 117;
    private static final int EVENT_NETWORK_AVAILABLE              = 118;
    private static final int EVENT_PROCESS_SIM_STATE_CHANGE       = 119;

    // 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
@@ -291,6 +295,8 @@ public class PhoneSwitcher extends Handler {

    private ConnectivityManager mConnectivityManager;

    private List<Set<CommandException.Error>> mCurrentDdsSwitchFailure;

    private class DefaultNetworkCallback extends ConnectivityManager.NetworkCallback {
        public int mExpectedSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
        public int mSwitchReason = TelephonyEvent.DataSwitch.Reason.DATA_SWITCH_REASON_UNKNOWN;
@@ -402,6 +408,11 @@ public class PhoneSwitcher extends Handler {
        mRadioConfig = RadioConfig.getInstance();
        mValidator = CellularNetworkValidator.getInstance();

        mCurrentDdsSwitchFailure = new ArrayList<Set<CommandException.Error>>();
        IntentFilter filter = new IntentFilter();
        filter.addAction(TelephonyManager.ACTION_SIM_APPLICATION_STATE_CHANGED);
        mContext.registerReceiver(mSimStateIntentReceiver, filter);

        mActivePhoneRegistrants = new RegistrantList();
        for (int i = 0; i < mActiveModemCount; i++) {
            mPhoneStates[i] = new PhoneState();
@@ -418,6 +429,8 @@ public class PhoneSwitcher extends Handler {
                PhoneFactory.getPhone(i).getDataEnabledSettings().registerForDataEnabledChanged(
                        this, EVENT_DATA_ENABLED_CHANGED, null);
            }
            Set<CommandException.Error> ddsFailure = new HashSet<CommandException.Error>();
            mCurrentDdsSwitchFailure.add(ddsFailure);
        }

        if (mActiveModemCount > 0) {
@@ -461,6 +474,8 @@ public class PhoneSwitcher extends Handler {
        // we want to see all requests
        networkFactory.registerIgnoringScore();

        updateHalCommandToUse();

        log("PhoneSwitcher started");
    }

@@ -472,6 +487,40 @@ public class PhoneSwitcher extends Handler {
        }
    };

    private BroadcastReceiver mSimStateIntentReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            if (action.equals(TelephonyManager.ACTION_SIM_APPLICATION_STATE_CHANGED)) {
                int state = intent.getIntExtra(TelephonyManager.EXTRA_SIM_STATE,
                        TelephonyManager.SIM_STATE_UNKNOWN);
                int slotIndex = intent.getIntExtra(SubscriptionManager.EXTRA_SLOT_INDEX,
                        SubscriptionManager.INVALID_SIM_SLOT_INDEX);
                log("mSimStateIntentReceiver: slotIndex = " + slotIndex + " state = " + state);
                obtainMessage(EVENT_PROCESS_SIM_STATE_CHANGE, slotIndex, state).sendToTarget();
            }
        }
    };

    private boolean isSimApplicationReady(int slotIndex) {
        if (!SubscriptionManager.isValidSlotIndex(slotIndex)) {
            return false;
        }

        SubscriptionInfo info = SubscriptionController.getInstance()
                .getActiveSubscriptionInfoForSimSlotIndex(slotIndex,
                mContext.getOpPackageName(), null);
        boolean uiccAppsEnabled = info != null && info.areUiccApplicationsEnabled();

        IccCard iccCard = PhoneFactory.getPhone(slotIndex).getIccCard();
        if (!iccCard.isEmptyProfile() && uiccAppsEnabled) {
            log("isSimApplicationReady: SIM is ready for slotIndex: " + slotIndex);
            return true;
        } else {
            return false;
        }
    }

    private final SubscriptionManager.OnSubscriptionsChangedListener mSubscriptionsChangedListener =
            new SubscriptionManager.OnSubscriptionsChangedListener() {
        @Override
@@ -542,9 +591,21 @@ public class PhoneSwitcher extends Handler {
                break;
            }
            case EVENT_PRECISE_CALL_STATE_CHANGED: {
                log("EVENT_PRECISE_CALL_STATE_CHANGED");

                // If the phoneId in voice call didn't change, do nothing.
                if (!isPhoneInVoiceCallChanged()) break;

                if (!isAnyVoiceCallActiveOnDevice()) {
                    for (int i = 0; i < mActiveModemCount; i++) {
                        if (mCurrentDdsSwitchFailure.get(i).contains(
                                CommandException.Error.OP_NOT_ALLOWED_DURING_VOICE_CALL)
                                 && isPhoneIdValidForRetry(i)) {
                            sendRilCommands(i);
                        }
                    }
                }

                // Only handle this event if we are currently waiting for the emergency call
                // associated with the override request to start or end.
                if (mEmergencyOverride != null && mEmergencyOverride.mPendingOriginatingCall) {
@@ -595,18 +656,21 @@ public class PhoneSwitcher extends Handler {
                    mEmergencyOverride.sendOverrideCompleteCallbackResultAndClear(commandSuccess);
                    // Do not retry , as we do not allow changes in onEvaluate during an emergency
                    // call. When the call ends, we will start the countdown to remove the override.
                } else if (!commandSuccess) {
                } else {
                    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);
                    onDdsSwitchResponse(ar, phoneId);
                }
                break;
            }
            case EVENT_MODEM_COMMAND_RETRY: {
                int phoneId = (int) msg.obj;
                log("Resend modem command on phone " + phoneId);
                if (isPhoneIdValidForRetry(phoneId)) {
                    log("EVENT_MODEM_COMMAND_RETRY: resend modem command on phone " + phoneId);
                    sendRilCommands(phoneId);
                } else {
                    log("EVENT_MODEM_COMMAND_RETRY: skip retry as DDS sub changed");
                    mCurrentDdsSwitchFailure.get(phoneId).clear();
                }
                break;
            }
            case EVENT_OVERRIDE_DDS_FOR_EMERGENCY: {
@@ -664,6 +728,21 @@ public class PhoneSwitcher extends Handler {
                onMultiSimConfigChanged(activeModemCount);
                break;
            }
            case EVENT_PROCESS_SIM_STATE_CHANGE: {
                int slotIndex = (int) msg.arg1;
                int simState = (int) msg.arg2;

                if (!SubscriptionManager.isValidSlotIndex(slotIndex)) {
                    log("EVENT_PROCESS_SIM_STATE_CHANGE: skip processing due to invalid slotId: "
                            + slotIndex);
                } else if (mCurrentDdsSwitchFailure.get(slotIndex).contains(
                        CommandException.Error.INVALID_SIM_STATE)
                        && (TelephonyManager.SIM_STATE_LOADED == simState)
                        && isSimApplicationReady(slotIndex)) {
                    sendRilCommands(slotIndex);
                }
                break;
            }
        }
    }

@@ -675,6 +754,8 @@ public class PhoneSwitcher extends Handler {

        mPhoneSubscriptions = copyOf(mPhoneSubscriptions, mActiveModemCount);
        mPhoneStates = copyOf(mPhoneStates, mActiveModemCount);
        //clear the list in case of multisim config change
        mCurrentDdsSwitchFailure.clear();

        // Single SIM -> dual SIM switch.
        for (int phoneId = oldActiveModemCount; phoneId < mActiveModemCount; phoneId++) {
@@ -691,6 +772,9 @@ public class PhoneSwitcher extends Handler {
            }
            phone.getDataEnabledSettings().registerForDataEnabledChanged(
                    this, EVENT_DATA_ENABLED_CHANGED, null);

            Set<CommandException.Error> ddsFailure = new HashSet<CommandException.Error>();
            mCurrentDdsSwitchFailure.add(ddsFailure);
        }
    }

@@ -947,11 +1031,6 @@ public class PhoneSwitcher extends Handler {
                    activate(phoneId);
                }
            }

            notifyPreferredDataSubIdChanged();

            // Notify all registrants.
            mActivePhoneRegistrants.notifyRegistrants();
        }
        return diffDetected;
    }
@@ -1021,7 +1100,10 @@ public class PhoneSwitcher extends Handler {
    }

    protected void sendRilCommands(int phoneId) {
        if (!SubscriptionManager.isValidPhoneId(phoneId)) return;
        if (!SubscriptionManager.isValidPhoneId(phoneId)) {
            log("sendRilCommands: skip dds switch due to invalid phoneid=" + phoneId);
            return;
        }

        Message message = Message.obtain(this, EVENT_MODEM_COMMAND_DONE, phoneId);
        if (mHalCommandToUse == HAL_COMMAND_ALLOW_DATA || mHalCommandToUse == HAL_COMMAND_UNKNOWN) {
@@ -1455,4 +1537,63 @@ public class PhoneSwitcher extends Handler {
        mLocalLog.dump(fd, pw, args);
        pw.decreaseIndent();
    }

    private boolean isAnyVoiceCallActiveOnDevice() {
        boolean ret = mPhoneIdInVoiceCall != SubscriptionManager.INVALID_PHONE_INDEX;
        log("isAnyVoiceCallActiveOnDevice: " + ret);
        return ret;
    }

    private void onDdsSwitchResponse(AsyncResult ar, int phoneId) {
        if (ar.exception != null) {
            log("onDdsSwitchResponse: DDS switch failed. with exception " + ar.exception);
            if (ar.exception instanceof CommandException) {
                CommandException.Error error = ((CommandException)
                        (ar.exception)).getCommandError();
                mCurrentDdsSwitchFailure.get(phoneId).add(error);
                if (error == CommandException.Error.OP_NOT_ALLOWED_DURING_VOICE_CALL) {
                    log("onDdsSwitchResponse: Wait for call end indication");
                    return;
                } else if (error == CommandException.Error.INVALID_SIM_STATE) {
                    /* If there is a attach failure due to sim not ready then
                    hold the retry until sim gets ready */
                    log("onDdsSwitchResponse: Wait for SIM to get READY");
                    return;
                }
            }

            log("onDdsSwitchResponse: Scheduling DDS switch retry");
            sendMessageDelayed(Message.obtain(this, EVENT_MODEM_COMMAND_RETRY,
                        phoneId), MODEM_COMMAND_RETRY_PERIOD_MS);
        } else {
            log("onDdsSwitchResponse: DDS switch success on phoneId = " + phoneId);
            mCurrentDdsSwitchFailure.get(phoneId).clear();
            // Notify all registrants
            mActivePhoneRegistrants.notifyRegistrants();
            notifyPreferredDataSubIdChanged();
        }
    }

    private boolean isPhoneIdValidForRetry(int phoneId) {
        int phoneIdForRequest = INVALID_PHONE_INDEX;
        int ddsPhoneId = mSubscriptionController.getPhoneId(
                mSubscriptionController.getDefaultDataSubId());
        if (ddsPhoneId != INVALID_PHONE_INDEX && ddsPhoneId == phoneId) {
            return true;
        } else {
            if (mPrioritizedDcRequests.size() == 0) {
                return false;
            }
            for (int i = 0; i < mMaxDataAttachModemCount; i++) {
                DcRequest dcRequest = mPrioritizedDcRequests.get(i);
                if (dcRequest != null) {
                    phoneIdForRequest = phoneIdForRequest(dcRequest.networkRequest);
                    if (phoneIdForRequest == phoneId) {
                        return true;
                    }
                }
            }
        }
        return false;
    }
}
+115 −5

File changed.

Preview size limit exceeded, changes collapsed.