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

Commit 2f102d49 authored by Jack Yu's avatar Jack Yu Committed by Gerrit Code Review
Browse files

Merge "Add support to retry for DDS switch failures"

parents 443f1585 0c38d31c
Loading
Loading
Loading
Loading
+153 −12
Original line number Original line Diff line number Diff line
@@ -52,6 +52,7 @@ import android.os.RemoteException;
import android.telephony.CarrierConfigManager;
import android.telephony.CarrierConfigManager;
import android.telephony.PhoneCapability;
import android.telephony.PhoneCapability;
import android.telephony.PhoneStateListener;
import android.telephony.PhoneStateListener;
import android.telephony.SubscriptionInfo;
import android.telephony.SubscriptionManager;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
import android.telephony.TelephonyManager;
import android.telephony.TelephonyRegistryManager;
import android.telephony.TelephonyRegistryManager;
@@ -74,7 +75,9 @@ import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Calendar;
import java.util.Collections;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.List;
import java.util.Set;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletableFuture;


/**
/**
@@ -267,6 +270,7 @@ public class PhoneSwitcher extends Handler {
    @VisibleForTesting
    @VisibleForTesting
    public static final int EVENT_MULTI_SIM_CONFIG_CHANGED        = 117;
    public static final int EVENT_MULTI_SIM_CONFIG_CHANGED        = 117;
    private static final int EVENT_NETWORK_AVAILABLE              = 118;
    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
    // 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
@@ -287,6 +291,8 @@ public class PhoneSwitcher extends Handler {


    private ConnectivityManager mConnectivityManager;
    private ConnectivityManager mConnectivityManager;


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

    private class DefaultNetworkCallback extends ConnectivityManager.NetworkCallback {
    private class DefaultNetworkCallback extends ConnectivityManager.NetworkCallback {
        public int mExpectedSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
        public int mExpectedSubId = SubscriptionManager.INVALID_SUBSCRIPTION_ID;
        public int mSwitchReason = TelephonyEvent.DataSwitch.Reason.DATA_SWITCH_REASON_UNKNOWN;
        public int mSwitchReason = TelephonyEvent.DataSwitch.Reason.DATA_SWITCH_REASON_UNKNOWN;
@@ -363,6 +369,11 @@ public class PhoneSwitcher extends Handler {
        mRadioConfig = RadioConfig.getInstance();
        mRadioConfig = RadioConfig.getInstance();
        mValidator = CellularNetworkValidator.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();
        mActivePhoneRegistrants = new RegistrantList();
        for (int i = 0; i < mActiveModemCount; i++) {
        for (int i = 0; i < mActiveModemCount; i++) {
            mPhoneStates[i] = new PhoneState();
            mPhoneStates[i] = new PhoneState();
@@ -379,6 +390,8 @@ public class PhoneSwitcher extends Handler {
                PhoneFactory.getPhone(i).getDataEnabledSettings().registerForDataEnabledChanged(
                PhoneFactory.getPhone(i).getDataEnabledSettings().registerForDataEnabledChanged(
                        this, EVENT_DATA_ENABLED_CHANGED, null);
                        this, EVENT_DATA_ENABLED_CHANGED, null);
            }
            }
            Set<CommandException.Error> ddsFailure = new HashSet<CommandException.Error>();
            mCurrentDdsSwitchFailure.add(ddsFailure);
        }
        }


        if (mActiveModemCount > 0) {
        if (mActiveModemCount > 0) {
@@ -423,6 +436,8 @@ public class PhoneSwitcher extends Handler {
        networkFactory.setScoreFilter(101);
        networkFactory.setScoreFilter(101);
        networkFactory.register();
        networkFactory.register();


        updateHalCommandToUse();

        log("PhoneSwitcher started");
        log("PhoneSwitcher started");
    }
    }


@@ -434,6 +449,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 =
    private final SubscriptionManager.OnSubscriptionsChangedListener mSubscriptionsChangedListener =
            new SubscriptionManager.OnSubscriptionsChangedListener() {
            new SubscriptionManager.OnSubscriptionsChangedListener() {
        @Override
        @Override
@@ -504,9 +553,21 @@ public class PhoneSwitcher extends Handler {
                break;
                break;
            }
            }
            case EVENT_PRECISE_CALL_STATE_CHANGED: {
            case EVENT_PRECISE_CALL_STATE_CHANGED: {
                log("EVENT_PRECISE_CALL_STATE_CHANGED");

                // If the phoneId in voice call didn't change, do nothing.
                // If the phoneId in voice call didn't change, do nothing.
                if (!isPhoneInVoiceCallChanged()) break;
                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
                // Only handle this event if we are currently waiting for the emergency call
                // associated with the override request to start or end.
                // associated with the override request to start or end.
                if (mEmergencyOverride != null && mEmergencyOverride.mPendingOriginatingCall) {
                if (mEmergencyOverride != null && mEmergencyOverride.mPendingOriginatingCall) {
@@ -557,18 +618,21 @@ public class PhoneSwitcher extends Handler {
                    mEmergencyOverride.sendOverrideCompleteCallbackResultAndClear(commandSuccess);
                    mEmergencyOverride.sendOverrideCompleteCallbackResultAndClear(commandSuccess);
                    // Do not retry , as we do not allow changes in onEvaluate during an emergency
                    // 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.
                    // call. When the call ends, we will start the countdown to remove the override.
                } else if (!commandSuccess) {
                } else {
                    int phoneId = (int) ar.userObj;
                    int phoneId = (int) ar.userObj;
                    log("Modem command failed. with exception " + ar.exception);
                    onDdsSwitchResponse(ar, phoneId);
                    sendMessageDelayed(Message.obtain(this, EVENT_MODEM_COMMAND_RETRY,
                            phoneId), MODEM_COMMAND_RETRY_PERIOD_MS);
                }
                }
                break;
                break;
            }
            }
            case EVENT_MODEM_COMMAND_RETRY: {
            case EVENT_MODEM_COMMAND_RETRY: {
                int phoneId = (int) msg.obj;
                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);
                    sendRilCommands(phoneId);
                } else {
                    log("EVENT_MODEM_COMMAND_RETRY: skip retry as DDS sub changed");
                    mCurrentDdsSwitchFailure.get(phoneId).clear();
                }
                break;
                break;
            }
            }
            case EVENT_OVERRIDE_DDS_FOR_EMERGENCY: {
            case EVENT_OVERRIDE_DDS_FOR_EMERGENCY: {
@@ -626,6 +690,21 @@ public class PhoneSwitcher extends Handler {
                onMultiSimConfigChanged(activeModemCount);
                onMultiSimConfigChanged(activeModemCount);
                break;
                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;
            }
        }
        }
    }
    }


@@ -637,6 +716,8 @@ public class PhoneSwitcher extends Handler {


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


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

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


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

            notifyPreferredDataSubIdChanged();

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


    protected void sendRilCommands(int phoneId) {
    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);
        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) {
@@ -1417,4 +1499,63 @@ public class PhoneSwitcher extends Handler {
        mLocalLog.dump(fd, pw, args);
        mLocalLog.dump(fd, pw, args);
        pw.decreaseIndent();
        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.