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

Commit 689e05fa authored by Robert Greenwalt's avatar Robert Greenwalt
Browse files

Handle RIL failures of DATA_ALLOWED.

Some of our radios don't handle the command so we need to watch
for errors and move to appropriate states.  This fixes a race
between SIM notifications and ServiceState where often on
VZW we'd end up thinking we were detached (and never setting
up data calls) when we actually were still attached.

bug:20537726
Change-Id: Ieb32e613c16a79e8c18d65d1cce84d093d51a4b0
parent 325ae99b
Loading
Loading
Loading
Loading
+36 −8
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@ import com.android.internal.util.AsyncChannel;
import com.android.internal.util.Protocol;
import com.android.internal.util.State;
import com.android.internal.util.StateMachine;
import com.android.internal.telephony.CommandException;
import com.android.internal.telephony.Phone;
import com.android.internal.telephony.PhoneConstants;
import com.android.internal.telephony.PhoneBase;
@@ -40,6 +41,7 @@ public class DcSwitchStateMachine extends StateMachine {
    private static final int EVENT_CONNECTED       = BASE + 0;
    private static final int EVENT_DATA_ALLOWED    = BASE + 1;
    private static final int CMD_RETRY_ATTACH      = BASE + 2;
    private static final int EVENT_DATA_DISALLOWED = BASE + 3;

    private int mId;
    private Phone mPhone;
@@ -168,10 +170,20 @@ public class DcSwitchStateMachine extends StateMachine {
                case EVENT_DATA_ALLOWED: {
                    AsyncResult ar = (AsyncResult)msg.obj;
                    if (mCurrentAllowedSequence != msg.arg1) {
                        loge("EVENT_DATA_ATTACHED ignored arg1=" + msg.arg1 + ", seq=" +
                        loge("EVENT_DATA_ALLOWED ignored arg1=" + msg.arg1 + ", seq=" +
                                mCurrentAllowedSequence);
                    } else if (ar.exception != null) {
                        loge("EVENT_DATA_ATTACHED failed, " + ar.exception);
                        if (ar.exception instanceof CommandException) {
                            CommandException e = (CommandException)ar.exception;
                            if (e.getCommandError() ==
                                    CommandException.Error.REQUEST_NOT_SUPPORTED) {
                                // must be on a single-sim device so stay in Attaching
                                // this is important to avoid an infinite loop
                                retVal = HANDLED;
                                break;
                            }
                        }
                        loge("EVENT_DATA_ALLOWED failed, " + ar.exception);
                        transitionTo(mIdleState);
                    }
                    retVal = HANDLED;
@@ -272,12 +284,14 @@ public class DcSwitchStateMachine extends StateMachine {
    }

    private class DetachingState extends State {
        private int mCurrentDisallowedSequence = 0;

        @Override
        public void enter() {
            if (DBG) log("DetachingState: enter");
            PhoneBase pb = (PhoneBase)((PhoneProxy)mPhone).getActivePhone();
            pb.mCi.setDataAllowed(false, obtainMessage(
                    DcSwitchAsyncChannel.EVENT_DATA_DETACHED));
            pb.mCi.setDataAllowed(false, obtainMessage(EVENT_DATA_DISALLOWED,
                    ++mCurrentDisallowedSequence, 0));
        }

        @Override
@@ -303,7 +317,21 @@ public class DcSwitchStateMachine extends StateMachine {
                    retVal = HANDLED;
                    break;
                }

                case EVENT_DATA_DISALLOWED: {
                    AsyncResult ar = (AsyncResult)msg.obj;
                    if (mCurrentDisallowedSequence != msg.arg1) {
                        loge("EVENT_DATA_DISALLOWED ignored arg1=" + msg.arg1 + ", seq=" +
                                mCurrentDisallowedSequence);
                    } else if (ar.exception != null) {
                        // go back to attached as we still think we are.  Notifications
                        // from the ServiceStateTracker will kick us out of attached when
                        // appropriate.
                        loge("EVENT_DATA_DISALLOWED failed, " + ar.exception);
                        transitionTo(mAttachedState);
                    }
                    retVal = HANDLED;
                    break;
                }
                case DcSwitchAsyncChannel.REQ_DISCONNECT_ALL: {
                    if (DBG) {
                        log("DetachingState: REQ_DISCONNECT_ALL, already detaching" );