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

Commit 28280a96 authored by Amit Mahajan's avatar Amit Mahajan Committed by android-build-merger
Browse files

Merge "Add a timeout in waiting state to unblock the state machine after 30s."

am: 1ef77a50

Change-Id: I4202b2b45770b230daf0f910f4f90b4c1e513cef
parents 6e6c19ba 1ef77a50
Loading
Loading
Loading
Loading
+47 −0
Original line number Diff line number Diff line
@@ -158,6 +158,17 @@ public abstract class InboundSmsHandler extends StateMachine {
    /** New SMS received as an AsyncResult. */
    public static final int EVENT_INJECT_SMS = 8;

    /** Update tracker object; used only in waiting state */
    private static final int EVENT_UPDATE_TRACKER = 9;

    /** Timeout in case state machine is stuck in a state for too long; used only in waiting
     * state */
    private static final int EVENT_STATE_TIMEOUT = 10;

    /** Timeout duration for EVENT_STATE_TIMEOUT */
    @VisibleForTesting
    public static final int STATE_TIMEOUT = 30000;

    /** Wakelock release delay when returning to idle state. */
    private static final int WAKELOCK_TIMEOUT = 3000;

@@ -450,6 +461,7 @@ public abstract class InboundSmsHandler extends StateMachine {
                    // if any broadcasts were sent, transition to waiting state
                    InboundSmsTracker inboundSmsTracker = (InboundSmsTracker) msg.obj;
                    if (processMessagePart(inboundSmsTracker)) {
                        sendMessage(EVENT_UPDATE_TRACKER, inboundSmsTracker);
                        transitionTo(mWaitingState);
                    } else {
                        // if event is sent from SmsBroadcastUndelivered.broadcastSms(), and
@@ -493,18 +505,41 @@ public abstract class InboundSmsHandler extends StateMachine {
     * {@link IdleState} after any deferred {@link #EVENT_BROADCAST_SMS} messages are handled.
     */
    private class WaitingState extends State {
        private InboundSmsTracker mTracker;

        @Override
        public void enter() {
            if (DBG) log("entering Waiting state");
            mTracker = null;
            sendMessageDelayed(EVENT_STATE_TIMEOUT, STATE_TIMEOUT);
        }

        @Override
        public void exit() {
            if (DBG) log("exiting Waiting state");
            // Before moving to idle state, set wakelock timeout to WAKE_LOCK_TIMEOUT milliseconds
            // to give any receivers time to take their own wake locks
            setWakeLockTimeout(WAKELOCK_TIMEOUT);
            if (VDBG) {
                if (hasMessages(EVENT_STATE_TIMEOUT)) {
                    log("exiting Waiting state: removing EVENT_STATE_TIMEOUT from message queue");
                }
                if (hasMessages(EVENT_UPDATE_TRACKER)) {
                    log("exiting Waiting state: removing EVENT_UPDATE_TRACKER from message queue");
                }
            }
            removeMessages(EVENT_STATE_TIMEOUT);
            removeMessages(EVENT_UPDATE_TRACKER);
        }

        @Override
        public boolean processMessage(Message msg) {
            log("WaitingState.processMessage:" + msg.what);
            switch (msg.what) {
                case EVENT_UPDATE_TRACKER:
                    mTracker = (InboundSmsTracker) msg.obj;
                    return HANDLED;

                case EVENT_BROADCAST_SMS:
                    // defer until the current broadcast completes
                    deferMessage(msg);
@@ -520,6 +555,18 @@ public abstract class InboundSmsHandler extends StateMachine {
                    // not ready to return to idle; ignore
                    return HANDLED;

                case EVENT_STATE_TIMEOUT:
                    // stuck in WaitingState for too long; drop the message and exit this state
                    if (mTracker != null) {
                        log("WaitingState.processMessage: EVENT_STATE_TIMEOUT; dropping message");
                        dropSms(new SmsBroadcastReceiver(mTracker));
                    } else {
                        log("WaitingState.processMessage: EVENT_STATE_TIMEOUT; mTracker is null "
                                + "- sending EVENT_BROADCAST_COMPLETE");
                        sendMessage(EVENT_BROADCAST_COMPLETE);
                    }
                    return HANDLED;

                default:
                    // parent state handles the other message types
                    return NOT_HANDLED;
+25 −1
Original line number Diff line number Diff line
@@ -47,8 +47,8 @@ import android.os.UserHandle;
import android.os.UserManager;
import android.provider.Telephony;
import android.support.test.filters.FlakyTest;
import android.support.test.filters.MediumTest;
import android.test.mock.MockContentResolver;
import android.test.suitebuilder.annotation.MediumTest;

import com.android.internal.telephony.FakeSmsContentProvider;
import com.android.internal.telephony.InboundSmsHandler;
@@ -777,4 +777,28 @@ public class GsmInboundSmsHandlerTest extends TelephonyTest {

        verifySmsIntentBroadcasts(0);
    }

    @FlakyTest
    @Ignore
    @Test
    @MediumTest
    public void testWaitingStateTimeout() throws Exception {
        transitionFromStartupToIdle();

        // send new SMS to state machine and verify that triggers SMS_DELIVER_ACTION
        mGsmInboundSmsHandler.sendMessage(InboundSmsHandler.EVENT_NEW_SMS,
                new AsyncResult(null, mSmsMessage, null));
        waitForMs(100);

        ArgumentCaptor<Intent> intentArgumentCaptor = ArgumentCaptor.forClass(Intent.class);
        verify(mContext, times(1)).sendBroadcast(
                intentArgumentCaptor.capture());
        assertEquals(Telephony.Sms.Intents.SMS_DELIVER_ACTION,
                intentArgumentCaptor.getAllValues().get(0).getAction());
        assertEquals("WaitingState", getCurrentState().getName());

        waitForMs(InboundSmsHandler.STATE_TIMEOUT + 300);

        assertEquals("IdleState", getCurrentState().getName());
    }
}