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

Commit f313eb9f authored by Sukanya Rajkhowa's avatar Sukanya Rajkhowa Committed by Omkar Kolangade
Browse files

Telephony: Handle PS DETACH failure during DDS SWITCH

In DSDS, PS DETACH can fail if there is an ongoing voice call on the same sub.
This scenario is triggered when sub1 is DDS and is in a voice call. At this time
there is an MMS on sub2. DdsScheduler goes into DdsSwitchState and initiates an
on demand DDS switch from sub1 to sub2. This involves doing a PS DETACH on sub 1
followed by PS ATTACH on sub2.
If PS DETACH itself does not go through, data connection on sub1 will not be torn
down. As a result, DdsScheduler will be stuck in DdsSwitch state unable to process
further DDS switch requests.
Handle this by introducing PS DETACH retries for 6 times and notifying DdsScheduler
of the failure so that it goes back to IdleState to process further requests

CRs-Fixed: 759265
Change-Id: Ia426a51167be007847b1edde444eb154bb536e5a
parent 951c86d7
Loading
Loading
Loading
Loading
+68 −16
Original line number Diff line number Diff line
@@ -33,6 +33,7 @@ import android.telephony.TelephonyManager;
import android.telephony.SubscriptionManager;
import android.net.NetworkRequest;

import com.android.internal.os.SomeArgs;
import com.android.internal.telephony.IccCardConstants;
import com.android.internal.telephony.Phone;
import com.android.internal.telephony.PhoneConstants;
@@ -75,6 +76,7 @@ public class DctController extends Handler {
    private static final int EVENT_SET_DATA_ALLOW_DONE = 2;
    private static final int EVENT_DELAYED_RETRY = 3;
    private static final int EVENT_LEGACY_SET_DATA_SUBSCRIPTION = 4;
    private static final int EVENT_SET_DATA_ALLOW_FALSE = 5;

    private RegistrantList mNotifyDefaultDataSwitchInfo = new RegistrantList();
    private RegistrantList mNotifyOnDemandDataSwitchInfo = new RegistrantList();
@@ -676,17 +678,29 @@ public class DctController extends Handler {

                case EVENT_DELAYED_RETRY: {
                    Rlog.d(LOG_TAG, "EVENT_DELAYED_RETRY");
                    SwitchInfo s = (SwitchInfo)msg.obj;
                    SomeArgs args = (SomeArgs)msg.obj;
                    try {
                        SwitchInfo s = (SwitchInfo)args.arg1;
                        boolean psAttach = (boolean)args.arg2;
                        Rlog.d(LOG_TAG, " Retry, switchInfo = " + s);

                        Integer phoneId = s.mPhoneId;
                        long[] subId = mSubController.getSubId(phoneId);
                        Phone phone = mPhones[phoneId].getActivePhone();
                        DcTrackerBase dcTracker =((PhoneBase)phone).mDcTracker;

                        if(psAttach) {
                            Message psAttachDone = Message.obtain(this,
                                    EVENT_SET_DATA_ALLOW_DONE, s);
                    Phone phone = mPhones[phoneId].getActivePhone();
                    DcTrackerBase dcTracker =((PhoneBase)phone).mDcTracker;
                            dcTracker.setDataAllowed(true, psAttachDone);
                        } else {
                            Message psDetachDone = Message.obtain(this,
                                    EVENT_SET_DATA_ALLOW_FALSE, s);
                            dcTracker.setDataAllowed(false, psDetachDone);
                        }
                    } finally {
                        args.recycle();
                    }
                    break;
                }

@@ -706,7 +720,10 @@ public class DctController extends Handler {
                                + " attempt delayed retry");
                        s.incRetryCount();
                        if ( s.isRetryPossible()) {
                            sendMessageDelayed(obtainMessage(EVENT_DELAYED_RETRY, s),
                            SomeArgs args = SomeArgs.obtain();
                            args.arg1 = s;
                            args.arg2 = true;
                            sendMessageDelayed(obtainMessage(EVENT_DELAYED_RETRY, args),
                                    ATTACH_RETRY_DELAY);
                            return;
                        } else {
@@ -731,6 +748,41 @@ public class DctController extends Handler {
                    }
                    break;
                }

                case EVENT_SET_DATA_ALLOW_FALSE: {
                    AsyncResult ar = (AsyncResult)msg.obj;
                    SwitchInfo s = (SwitchInfo)ar.userObj;

                    Exception errorEx = null;

                    Integer phoneId = s.mPhoneId;
                    long[] subId = mSubController.getSubId(phoneId);
                    Rlog.d(LOG_TAG, "EVENT_SET_DATA_FALSE  phoneId :" + subId[0]
                            + ", switchInfo = " + s);

                    if (ar.exception != null) {
                        Rlog.d(LOG_TAG, "Failed, switchInfo = " + s
                                + " attempt delayed retry");
                        s.incRetryCount();
                        if (s.isRetryPossible()) {
                            SomeArgs args = SomeArgs.obtain();
                            args.arg1 = s;
                            args.arg2 = false;
                            sendMessageDelayed(obtainMessage(EVENT_DELAYED_RETRY, args),
                                    ATTACH_RETRY_DELAY);
                            return;
                        } else {
                            Rlog.d(LOG_TAG, "Already did max retries, notify failure");
                            errorEx = new RuntimeException("PS DETACH failed");
                            mNotifyOnDemandDataSwitchInfo.notifyRegistrants(
                                    new AsyncResult(null, s.mNetworkRequest, errorEx));
                       }
                    } else {
                        Rlog.d(LOG_TAG, "PS DETACH success = " + s);
                    }
                    break;
                }

                case AsyncChannel.CMD_CHANNEL_HALF_CONNECTED: {
                    if(msg.arg1 == AsyncChannel.STATUS_SUCCESSFUL) {
                        logd("HALF_CONNECTED: Connection successful with DDS switch"
@@ -815,16 +867,16 @@ public class DctController extends Handler {
                            mSubController.getCurrentDds());
                    Phone phone = mPhones[prefPhoneId].getActivePhone();
                    DcTrackerBase dcTracker =((PhoneBase)phone).mDcTracker;
                    dcTracker.setDataAllowed(false, null);
                    SwitchInfo s = new SwitchInfo(new Integer(phoneId), n, false, false);
                    Message dataAllowFalse = Message.obtain(DctController.this,
                            EVENT_SET_DATA_ALLOW_FALSE, s);
                    dcTracker.setDataAllowed(false, dataAllowFalse);
                    if (phone.getPhoneType() == PhoneConstants.PHONE_TYPE_CDMA) {
                        //cleanup data from apss as there is no detach procedure for CDMA
                        dcTracker.cleanUpAllConnections("Ondemand DDS switch");
                    }
                    SwitchInfo s = new SwitchInfo(new Integer(phoneId), n, false, false);
                    mPhones[prefPhoneId].registerForAllDataDisconnected(
                            sDctController, EVENT_ALL_DATA_DISCONNECTED, s);


                    break;
                }
            }