1fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville/**
2fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville * Copyright (C) 2009 The Android Open Source Project
3fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville *
4fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville * Licensed under the Apache License, Version 2.0 (the "License");
5fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville * you may not use this file except in compliance with the License.
6fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville * You may obtain a copy of the License at
7fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville *
8fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville *      http://www.apache.org/licenses/LICENSE-2.0
9fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville *
10fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville * Unless required by applicable law or agreed to in writing, software
11fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville * distributed under the License is distributed on an "AS IS" BASIS,
12fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville * See the License for the specific language governing permissions and
14fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville * limitations under the License.
15fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville */
16fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
176b888d98f7fffe5b87b3d5421d2f9a119899c7ddWink Savillepackage com.android.internal.util;
186b888d98f7fffe5b87b3d5421d2f9a119899c7ddWink Saville
196b888d98f7fffe5b87b3d5421d2f9a119899c7ddWink Savilleimport android.os.Debug;
206b888d98f7fffe5b87b3d5421d2f9a119899c7ddWink Savilleimport android.os.HandlerThread;
216b888d98f7fffe5b87b3d5421d2f9a119899c7ddWink Savilleimport android.os.Looper;
226b888d98f7fffe5b87b3d5421d2f9a119899c7ddWink Savilleimport android.os.Message;
236b888d98f7fffe5b87b3d5421d2f9a119899c7ddWink Savilleimport android.os.SystemClock;
24fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
2564c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Savilleimport com.android.internal.util.State;
2664c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Savilleimport com.android.internal.util.StateMachine;
27bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Savilleimport com.android.internal.util.StateMachine.LogRec;
28fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
29f76c56bcaa9df1d1afa711177f813dc63f399795Brett Chabotimport android.test.suitebuilder.annotation.MediumTest;
30fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Savilleimport android.test.suitebuilder.annotation.SmallTest;
31fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Savilleimport android.util.Log;
32fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
33f76c56bcaa9df1d1afa711177f813dc63f399795Brett Chabotimport junit.framework.TestCase;
34fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
35fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville/**
3664c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville * Test for StateMachine.
37fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville */
3864c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Savillepublic class StateMachineTest extends TestCase {
39bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville    private static final String ENTER = "enter";
40bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville    private static final String EXIT = "exit";
41bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville    private static final String ON_QUITTING = "ON_QUITTING";
42bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville
43fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    private static final int TEST_CMD_1 = 1;
44fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    private static final int TEST_CMD_2 = 2;
45fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    private static final int TEST_CMD_3 = 3;
46fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    private static final int TEST_CMD_4 = 4;
47fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    private static final int TEST_CMD_5 = 5;
48fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    private static final int TEST_CMD_6 = 6;
49fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
50fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    private static final boolean DBG = true;
516b888d98f7fffe5b87b3d5421d2f9a119899c7ddWink Saville    private static final boolean WAIT_FOR_DEBUGGER = false;
5264c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville    private static final String TAG = "StateMachineTest";
53fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
54bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville    private void sleep(int millis) {
55bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        try {
56bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville            Thread.sleep(millis);
57bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        } catch(InterruptedException e) {
58bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        }
59bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville    }
60bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville
61fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    /**
62bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville     * Tests {@link StateMachine#quit()}.
631b8b98b3db5dcf0b01d1a632aafea076cc91f5a4Wink Saville     */
6464c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville    class StateMachineQuitTest extends StateMachine {
65bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        Object mWaitUntilTestDone = new Object();
661b8b98b3db5dcf0b01d1a632aafea076cc91f5a4Wink Saville
671b8b98b3db5dcf0b01d1a632aafea076cc91f5a4Wink Saville        StateMachineQuitTest(String name) {
681b8b98b3db5dcf0b01d1a632aafea076cc91f5a4Wink Saville            super(name);
691b8b98b3db5dcf0b01d1a632aafea076cc91f5a4Wink Saville            mThisSm = this;
701b8b98b3db5dcf0b01d1a632aafea076cc91f5a4Wink Saville            setDbg(DBG);
711b8b98b3db5dcf0b01d1a632aafea076cc91f5a4Wink Saville
721b8b98b3db5dcf0b01d1a632aafea076cc91f5a4Wink Saville            // Setup state machine with 1 state
731b8b98b3db5dcf0b01d1a632aafea076cc91f5a4Wink Saville            addState(mS1);
741b8b98b3db5dcf0b01d1a632aafea076cc91f5a4Wink Saville
751b8b98b3db5dcf0b01d1a632aafea076cc91f5a4Wink Saville            // Set the initial state
761b8b98b3db5dcf0b01d1a632aafea076cc91f5a4Wink Saville            setInitialState(mS1);
771b8b98b3db5dcf0b01d1a632aafea076cc91f5a4Wink Saville        }
781b8b98b3db5dcf0b01d1a632aafea076cc91f5a4Wink Saville
79bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        @Override
80bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        public void onQuitting() {
81bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville            Log.d(TAG, "onQuitting");
82bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville            addLogRec(ON_QUITTING);
83bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville            synchronized (mThisSm) {
84bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville                mThisSm.notifyAll();
85bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville            }
86bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville
87bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville            // Don't leave onQuitting before the test is done as everything is cleared
88bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville            // including the log records.
89bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville            synchronized (mWaitUntilTestDone) {
90bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville                try {
91bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville                    mWaitUntilTestDone.wait();
92bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville                } catch(InterruptedException e) {
93bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville                }
94bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville            }
95bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        }
96bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville
9764c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville        class S1 extends State {
98bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville            public void exit() {
99bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville                Log.d(TAG, "S1.exit");
100bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville                addLogRec(EXIT, mS1);
101bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville            }
10264c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            @Override
10364c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            public boolean processMessage(Message message) {
104bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville                switch(message.what) {
105bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville                    // Sleep and assume the other messages will be queued up.
106bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville                    case TEST_CMD_1: {
107bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville                        Log.d(TAG, "TEST_CMD_1");
108bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville                        sleep(500);
109bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville                        quit();
110bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville                        break;
111bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville                    }
112bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville                    default: {
113bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville                        Log.d(TAG, "default what=" + message.what);
114bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville                        break;
1151b8b98b3db5dcf0b01d1a632aafea076cc91f5a4Wink Saville                    }
1161b8b98b3db5dcf0b01d1a632aafea076cc91f5a4Wink Saville                }
117bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville                return HANDLED;
1181b8b98b3db5dcf0b01d1a632aafea076cc91f5a4Wink Saville            }
1191b8b98b3db5dcf0b01d1a632aafea076cc91f5a4Wink Saville        }
1201b8b98b3db5dcf0b01d1a632aafea076cc91f5a4Wink Saville
1211b8b98b3db5dcf0b01d1a632aafea076cc91f5a4Wink Saville        private StateMachineQuitTest mThisSm;
1221b8b98b3db5dcf0b01d1a632aafea076cc91f5a4Wink Saville        private S1 mS1 = new S1();
1231b8b98b3db5dcf0b01d1a632aafea076cc91f5a4Wink Saville    }
1241b8b98b3db5dcf0b01d1a632aafea076cc91f5a4Wink Saville
1251b8b98b3db5dcf0b01d1a632aafea076cc91f5a4Wink Saville    @SmallTest
126bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville    public void testStateMachineQuit() throws Exception {
1276b888d98f7fffe5b87b3d5421d2f9a119899c7ddWink Saville        if (WAIT_FOR_DEBUGGER) Debug.waitForDebugger();
1281b8b98b3db5dcf0b01d1a632aafea076cc91f5a4Wink Saville
1291b8b98b3db5dcf0b01d1a632aafea076cc91f5a4Wink Saville        StateMachineQuitTest smQuitTest = new StateMachineQuitTest("smQuitTest");
1301b8b98b3db5dcf0b01d1a632aafea076cc91f5a4Wink Saville        smQuitTest.start();
131bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        if (smQuitTest.isDbg()) Log.d(TAG, "testStateMachineQuit E");
1321b8b98b3db5dcf0b01d1a632aafea076cc91f5a4Wink Saville
1331b8b98b3db5dcf0b01d1a632aafea076cc91f5a4Wink Saville        synchronized (smQuitTest) {
134bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville
135bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville            // Send 6 message we'll quit on the first but all 6 should be processed before quitting.
1361b8b98b3db5dcf0b01d1a632aafea076cc91f5a4Wink Saville            for (int i = 1; i <= 6; i++) {
137bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville                smQuitTest.sendMessage(smQuitTest.obtainMessage(i));
138bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville            }
139bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville
140bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville            try {
141bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville                // wait for the messages to be handled
142bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville                smQuitTest.wait();
143bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville            } catch (InterruptedException e) {
144bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville                Log.e(TAG, "testStateMachineQuit: exception while waiting " + e.getMessage());
145bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville            }
146bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        }
147bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville
148bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(8, smQuitTest.getLogRecCount());
149bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville
150bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        LogRec lr;
151bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville
152bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        for (int i = 0; i < 6; i++) {
153bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville            lr = smQuitTest.getLogRec(i);
154bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville            assertEquals(i+1, lr.getWhat());
155bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville            assertEquals(smQuitTest.mS1, lr.getState());
156bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville            assertEquals(smQuitTest.mS1, lr.getOriginalState());
157bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        }
158bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        lr = smQuitTest.getLogRec(6);
159bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(EXIT, lr.getInfo());
160bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(smQuitTest.mS1, lr.getState());
161bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville
162bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        lr = smQuitTest.getLogRec(7);
163bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(ON_QUITTING, lr.getInfo());
164bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville
165bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        synchronized (smQuitTest.mWaitUntilTestDone) {
166bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville            smQuitTest.mWaitUntilTestDone.notifyAll();
167bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        }
168bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        if (smQuitTest.isDbg()) Log.d(TAG, "testStateMachineQuit X");
169bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville    }
170bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville
171bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville    /**
172bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville     * Tests {@link StateMachine#quitNow()}
173bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville     */
174bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville    class StateMachineQuitNowTest extends StateMachine {
175bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        Object mWaitUntilTestDone = new Object();
176bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville
177bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        StateMachineQuitNowTest(String name) {
178bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville            super(name);
179bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville            mThisSm = this;
180bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville            setDbg(DBG);
181bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville
182bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville            // Setup state machine with 1 state
183bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville            addState(mS1);
184bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville
185bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville            // Set the initial state
186bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville            setInitialState(mS1);
187bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        }
188bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville
189bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        @Override
190bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        public void onQuitting() {
191bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville            Log.d(TAG, "onQuitting");
192bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville            addLogRec(ON_QUITTING);
193bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville            synchronized (mThisSm) {
194bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville                mThisSm.notifyAll();
195bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville            }
196bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville
197bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville            // Don't leave onQuitting before the test is done as everything is cleared
198bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville            // including the log records.
199bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville            synchronized (mWaitUntilTestDone) {
200bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville                try {
201bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville                    mWaitUntilTestDone.wait();
202bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville                } catch(InterruptedException e) {
203bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville                }
204bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville            }
205bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        }
206bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville
207bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        class S1 extends State {
208bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville            public void exit() {
209bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville                Log.d(TAG, "S1.exit");
210bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville                addLogRec(EXIT, mS1);
2111b8b98b3db5dcf0b01d1a632aafea076cc91f5a4Wink Saville            }
212bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville            @Override
213bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville            public boolean processMessage(Message message) {
214bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville                switch(message.what) {
215bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville                    // Sleep and assume the other messages will be queued up.
216bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville                    case TEST_CMD_1: {
217bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville                        Log.d(TAG, "TEST_CMD_1");
218bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville                        sleep(500);
219bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville                        quitNow();
220bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville                        break;
221bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville                    }
222bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville                    default: {
223bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville                        Log.d(TAG, "default what=" + message.what);
224bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville                        break;
225bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville                    }
226bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville                }
227bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville                return HANDLED;
228bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville            }
229bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        }
230bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville
231bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        private StateMachineQuitNowTest mThisSm;
232bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        private S1 mS1 = new S1();
233bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville    }
2341b8b98b3db5dcf0b01d1a632aafea076cc91f5a4Wink Saville
235bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville    @SmallTest
236bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville    public void testStateMachineQuitNow() throws Exception {
237bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        if (WAIT_FOR_DEBUGGER) Debug.waitForDebugger();
2381b8b98b3db5dcf0b01d1a632aafea076cc91f5a4Wink Saville
239bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        StateMachineQuitNowTest smQuitNowTest = new StateMachineQuitNowTest("smQuitNowTest");
240bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        smQuitNowTest.start();
241bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        if (smQuitNowTest.isDbg()) Log.d(TAG, "testStateMachineQuitNow E");
242bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville
243bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        synchronized (smQuitNowTest) {
244bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville
245bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville            // Send 6 messages but we'll QuitNow on the first so even though
246bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville            // we send 6 only one will be processed.
247bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville            for (int i = 1; i <= 6; i++) {
248bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville                smQuitNowTest.sendMessage(smQuitNowTest.obtainMessage(i));
249bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville            }
2501b8b98b3db5dcf0b01d1a632aafea076cc91f5a4Wink Saville
2511b8b98b3db5dcf0b01d1a632aafea076cc91f5a4Wink Saville            try {
2521b8b98b3db5dcf0b01d1a632aafea076cc91f5a4Wink Saville                // wait for the messages to be handled
253bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville                smQuitNowTest.wait();
2541b8b98b3db5dcf0b01d1a632aafea076cc91f5a4Wink Saville            } catch (InterruptedException e) {
255bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville                Log.e(TAG, "testStateMachineQuitNow: exception while waiting " + e.getMessage());
2561b8b98b3db5dcf0b01d1a632aafea076cc91f5a4Wink Saville            }
2571b8b98b3db5dcf0b01d1a632aafea076cc91f5a4Wink Saville        }
2581b8b98b3db5dcf0b01d1a632aafea076cc91f5a4Wink Saville
259bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        // Only three records because we executed quitNow.
260bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(3, smQuitNowTest.getLogRecCount());
2611b8b98b3db5dcf0b01d1a632aafea076cc91f5a4Wink Saville
262bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        LogRec lr;
2631b8b98b3db5dcf0b01d1a632aafea076cc91f5a4Wink Saville
264bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        lr = smQuitNowTest.getLogRec(0);
265bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(1, lr.getWhat());
266bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(smQuitNowTest.mS1, lr.getState());
267bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(smQuitNowTest.mS1, lr.getOriginalState());
2681b8b98b3db5dcf0b01d1a632aafea076cc91f5a4Wink Saville
269bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        lr = smQuitNowTest.getLogRec(1);
270bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(EXIT, lr.getInfo());
271bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(smQuitNowTest.mS1, lr.getState());
2721b8b98b3db5dcf0b01d1a632aafea076cc91f5a4Wink Saville
273bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        lr = smQuitNowTest.getLogRec(2);
274bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(ON_QUITTING, lr.getInfo());
2751b8b98b3db5dcf0b01d1a632aafea076cc91f5a4Wink Saville
276bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        synchronized (smQuitNowTest.mWaitUntilTestDone) {
277bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville            smQuitNowTest.mWaitUntilTestDone.notifyAll();
278bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        }
279bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        if (smQuitNowTest.isDbg()) Log.d(TAG, "testStateMachineQuitNow X");
2801b8b98b3db5dcf0b01d1a632aafea076cc91f5a4Wink Saville    }
2811b8b98b3db5dcf0b01d1a632aafea076cc91f5a4Wink Saville
2821b8b98b3db5dcf0b01d1a632aafea076cc91f5a4Wink Saville    /**
283e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville     * Test enter/exit can use transitionTo
284e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville     */
28564c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville    class StateMachineEnterExitTransitionToTest extends StateMachine {
286bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville
287e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville        StateMachineEnterExitTransitionToTest(String name) {
288e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville            super(name);
289e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville            mThisSm = this;
290e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville            setDbg(DBG);
291e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville
292e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville            // Setup state machine with 1 state
293e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville            addState(mS1);
294e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville            addState(mS2);
295e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville            addState(mS3);
296e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville            addState(mS4);
297e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville
298e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville            // Set the initial state
299e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville            setInitialState(mS1);
300e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville        }
301e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville
30264c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville        class S1 extends State {
30364c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            @Override
30464c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            public void enter() {
305bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville                // Test transitions in enter on the initial state work
306bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville                addLogRec(ENTER, mS1);
307e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville                transitionTo(mS2);
308e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville                Log.d(TAG, "S1.enter");
309e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville            }
31064c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            @Override
31164c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            public void exit() {
312a4f3bec29c85ef9e0d07fdd551fe3c50f28b9adcWink Saville                // Test that message is HSM_INIT_CMD
313bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville                addLogRec(EXIT, mS1);
314e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville                Log.d(TAG, "S1.exit");
315e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville            }
316e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville        }
317e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville
31864c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville        class S2 extends State {
31964c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            @Override
32064c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            public void enter() {
321bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville                addLogRec(ENTER, mS2);
322e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville                Log.d(TAG, "S2.enter");
323e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville            }
32464c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            @Override
32564c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            public void exit() {
326bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville                addLogRec(EXIT, mS2);
327a4f3bec29c85ef9e0d07fdd551fe3c50f28b9adcWink Saville                assertEquals(TEST_CMD_1, getCurrentMessage().what);
328a4f3bec29c85ef9e0d07fdd551fe3c50f28b9adcWink Saville
329e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville                // Test transition in exit work
330e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville                transitionTo(mS4);
331e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville                Log.d(TAG, "S2.exit");
332e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville            }
33364c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            @Override
33464c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            public boolean processMessage(Message message) {
335e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville                // Start a transition to S3 but it will be
336a4f3bec29c85ef9e0d07fdd551fe3c50f28b9adcWink Saville                // changed to a transition to S4 in exit
337e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville                transitionTo(mS3);
338e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville                Log.d(TAG, "S2.processMessage");
339a4f3bec29c85ef9e0d07fdd551fe3c50f28b9adcWink Saville                return HANDLED;
340e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville            }
341e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville        }
342e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville
34364c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville        class S3 extends State {
34464c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            @Override
34564c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            public void enter() {
346bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville                addLogRec(ENTER, mS3);
347e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville                Log.d(TAG, "S3.enter");
348e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville            }
34964c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            @Override
35064c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            public void exit() {
351bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville                addLogRec(EXIT, mS3);
352e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville                Log.d(TAG, "S3.exit");
353e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville            }
354e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville        }
355e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville
35664c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville        class S4 extends State {
35764c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            @Override
35864c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            public void enter() {
359bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville                addLogRec(ENTER, mS4);
360e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville                // Test that we can do halting in an enter/exit
361e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville                transitionToHaltingState();
362e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville                Log.d(TAG, "S4.enter");
363e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville            }
36464c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            @Override
36564c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            public void exit() {
366bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville                addLogRec(EXIT, mS4);
367e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville                Log.d(TAG, "S4.exit");
368e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville            }
369e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville        }
370e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville
371e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville        @Override
372bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        protected void onHalting() {
373e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville            synchronized (mThisSm) {
374e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville                mThisSm.notifyAll();
375e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville            }
376e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville        }
377e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville
378e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville        private StateMachineEnterExitTransitionToTest mThisSm;
379e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville        private S1 mS1 = new S1();
380e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville        private S2 mS2 = new S2();
381e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville        private S3 mS3 = new S3();
382e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville        private S4 mS4 = new S4();
383e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville    }
384e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville
385e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville    @SmallTest
386e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville    public void testStateMachineEnterExitTransitionToTest() throws Exception {
387e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville        //if (WAIT_FOR_DEBUGGER) Debug.waitForDebugger();
388e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville
389e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville        StateMachineEnterExitTransitionToTest smEnterExitTranstionToTest =
390e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville            new StateMachineEnterExitTransitionToTest("smEnterExitTranstionToTest");
391e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville        smEnterExitTranstionToTest.start();
392e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville        if (smEnterExitTranstionToTest.isDbg()) {
393e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville            Log.d(TAG, "testStateMachineEnterExitTransitionToTest E");
394e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville        }
395e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville
396e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville        synchronized (smEnterExitTranstionToTest) {
397a4f3bec29c85ef9e0d07fdd551fe3c50f28b9adcWink Saville            smEnterExitTranstionToTest.sendMessage(TEST_CMD_1);
398e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville
399e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville            try {
400e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville                // wait for the messages to be handled
401e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville                smEnterExitTranstionToTest.wait();
402e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville            } catch (InterruptedException e) {
403e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville                Log.e(TAG, "testStateMachineEnterExitTransitionToTest: exception while waiting "
404e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville                    + e.getMessage());
405e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville            }
406e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville        }
407e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville
408bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(smEnterExitTranstionToTest.getLogRecCount(), 9);
409bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville
410bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        LogRec lr;
411bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville
412bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        lr = smEnterExitTranstionToTest.getLogRec(0);
413bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(ENTER, lr.getInfo());
414bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(smEnterExitTranstionToTest.mS1, lr.getState());
415bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville
416bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        lr = smEnterExitTranstionToTest.getLogRec(1);
417bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(EXIT, lr.getInfo());
418bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(smEnterExitTranstionToTest.mS1, lr.getState());
419bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville
420bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        lr = smEnterExitTranstionToTest.getLogRec(2);
421bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(ENTER, lr.getInfo());
422bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(smEnterExitTranstionToTest.mS2, lr.getState());
423bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville
424bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        lr = smEnterExitTranstionToTest.getLogRec(3);
425bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(TEST_CMD_1, lr.getWhat());
426bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(smEnterExitTranstionToTest.mS2, lr.getState());
427bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(smEnterExitTranstionToTest.mS2, lr.getOriginalState());
428bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville
429bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        lr = smEnterExitTranstionToTest.getLogRec(4);
430bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(EXIT, lr.getInfo());
431bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(smEnterExitTranstionToTest.mS2, lr.getState());
432bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville
433bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        lr = smEnterExitTranstionToTest.getLogRec(5);
434bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(ENTER, lr.getInfo());
435bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(smEnterExitTranstionToTest.mS3, lr.getState());
436e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville
437bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        lr = smEnterExitTranstionToTest.getLogRec(6);
438bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(EXIT, lr.getInfo());
439bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(smEnterExitTranstionToTest.mS3, lr.getState());
440e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville
441bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        lr = smEnterExitTranstionToTest.getLogRec(7);
442bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(ENTER, lr.getInfo());
443bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(smEnterExitTranstionToTest.mS4, lr.getState());
444e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville
445bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        lr = smEnterExitTranstionToTest.getLogRec(8);
446bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(EXIT, lr.getInfo());
447bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(smEnterExitTranstionToTest.mS4, lr.getState());
448e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville
449e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville        if (smEnterExitTranstionToTest.isDbg()) {
450e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville            Log.d(TAG, "testStateMachineEnterExitTransitionToTest X");
451e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville        }
452e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville    }
453e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville
454e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville    /**
455fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville     * Tests that ProcessedMessage works as a circular buffer.
456fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville     */
45764c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville    class StateMachine0 extends StateMachine {
458fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        StateMachine0(String name) {
459fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            super(name);
460fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            mThisSm = this;
461fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            setDbg(DBG);
462bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville            setLogRecSize(3);
463fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
464fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            // Setup state machine with 1 state
465fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            addState(mS1);
466fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
467fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            // Set the initial state
468fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            setInitialState(mS1);
469fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        }
470fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
47164c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville        class S1 extends State {
47264c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            @Override
47364c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            public boolean processMessage(Message message) {
474fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                if (message.what == TEST_CMD_6) {
475fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                    transitionToHaltingState();
476fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                }
477a4f3bec29c85ef9e0d07fdd551fe3c50f28b9adcWink Saville                return HANDLED;
478fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            }
479fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        }
480fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
481fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        @Override
482bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        protected void onHalting() {
483fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            synchronized (mThisSm) {
484fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                mThisSm.notifyAll();
485fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            }
486fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        }
487fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
488fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        private StateMachine0 mThisSm;
489fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        private S1 mS1 = new S1();
490fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    }
491fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
492fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    @SmallTest
493fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    public void testStateMachine0() throws Exception {
4941b8b98b3db5dcf0b01d1a632aafea076cc91f5a4Wink Saville        //if (WAIT_FOR_DEBUGGER) Debug.waitForDebugger();
495fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
496fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        StateMachine0 sm0 = new StateMachine0("sm0");
497fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        sm0.start();
498fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        if (sm0.isDbg()) Log.d(TAG, "testStateMachine0 E");
499fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
500fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        synchronized (sm0) {
501fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            // Send 6 messages
502fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            for (int i = 1; i <= 6; i++) {
503fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                sm0.sendMessage(sm0.obtainMessage(i));
504fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            }
505fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
506fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            try {
507fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                // wait for the messages to be handled
508fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                sm0.wait();
509fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            } catch (InterruptedException e) {
510fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                Log.e(TAG, "testStateMachine0: exception while waiting " + e.getMessage());
511fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            }
512fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        }
513fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
514bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(6, sm0.getLogRecCount());
515bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(3, sm0.getLogRecSize());
516fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
517bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        LogRec lr;
518bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        lr = sm0.getLogRec(0);
519bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(TEST_CMD_4, lr.getWhat());
520bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(sm0.mS1, lr.getState());
521bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(sm0.mS1, lr.getOriginalState());
522fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
523bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        lr = sm0.getLogRec(1);
524bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(TEST_CMD_5, lr.getWhat());
525bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(sm0.mS1, lr.getState());
526bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(sm0.mS1, lr.getOriginalState());
527fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
528bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        lr = sm0.getLogRec(2);
529bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(TEST_CMD_6, lr.getWhat());
530bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(sm0.mS1, lr.getState());
531bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(sm0.mS1, lr.getOriginalState());
532fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
533fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        if (sm0.isDbg()) Log.d(TAG, "testStateMachine0 X");
534fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    }
535fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
536fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    /**
537fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville     * This tests enter/exit and transitions to the same state.
538fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville     * The state machine has one state, it receives two messages
539fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville     * in state mS1. With the first message it transitions to
540fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville     * itself which causes it to be exited and reentered.
541fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville     */
54264c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville    class StateMachine1 extends StateMachine {
543fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        StateMachine1(String name) {
544fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            super(name);
545fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            mThisSm = this;
546fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            setDbg(DBG);
547fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
548fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            // Setup state machine with 1 state
549fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            addState(mS1);
550fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
551fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            // Set the initial state
552fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            setInitialState(mS1);
553fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            if (DBG) Log.d(TAG, "StateMachine1: ctor X");
554fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        }
555fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
55664c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville        class S1 extends State {
55764c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            @Override
55864c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            public void enter() {
559fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                mEnterCount++;
560fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            }
56164c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            @Override
56264c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            public void exit() {
56364c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville                mExitCount++;
56464c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            }
56564c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            @Override
56664c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            public boolean processMessage(Message message) {
567fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                if (message.what == TEST_CMD_1) {
568fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                    assertEquals(1, mEnterCount);
569fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                    assertEquals(0, mExitCount);
570fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                    transitionTo(mS1);
571fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                } else if (message.what == TEST_CMD_2) {
572fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                    assertEquals(2, mEnterCount);
573fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                    assertEquals(1, mExitCount);
574fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                    transitionToHaltingState();
575fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                }
576a4f3bec29c85ef9e0d07fdd551fe3c50f28b9adcWink Saville                return HANDLED;
577fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            }
578fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        }
579fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
580fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        @Override
581bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        protected void onHalting() {
582fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            synchronized (mThisSm) {
583fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                mThisSm.notifyAll();
584fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            }
585fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        }
586fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
587fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        private StateMachine1 mThisSm;
588fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        private S1 mS1 = new S1();
589fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
590fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        private int mEnterCount;
591fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        private int mExitCount;
592fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    }
593fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
594f76c56bcaa9df1d1afa711177f813dc63f399795Brett Chabot    @MediumTest
595fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    public void testStateMachine1() throws Exception {
596fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        StateMachine1 sm1 = new StateMachine1("sm1");
597fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        sm1.start();
598fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        if (sm1.isDbg()) Log.d(TAG, "testStateMachine1 E");
599fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
600fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        synchronized (sm1) {
601fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            // Send two messages
60291fbd56757751a7aca8ef2b4d936e587509e6eefWink Saville            sm1.sendMessage(TEST_CMD_1);
60391fbd56757751a7aca8ef2b4d936e587509e6eefWink Saville            sm1.sendMessage(TEST_CMD_2);
604fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
605fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            try {
606fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                // wait for the messages to be handled
607fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                sm1.wait();
608fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            } catch (InterruptedException e) {
609fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                Log.e(TAG, "testStateMachine1: exception while waiting " + e.getMessage());
610fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            }
611fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        }
612fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
613fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        assertEquals(2, sm1.mEnterCount);
614fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        assertEquals(2, sm1.mExitCount);
615fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
616bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(2, sm1.getLogRecSize());
617fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
618bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        LogRec lr;
619bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        lr = sm1.getLogRec(0);
620bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(TEST_CMD_1, lr.getWhat());
621bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(sm1.mS1, lr.getState());
622bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(sm1.mS1, lr.getOriginalState());
623fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
624bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        lr = sm1.getLogRec(1);
625bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(TEST_CMD_2, lr.getWhat());
626bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(sm1.mS1, lr.getState());
627bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(sm1.mS1, lr.getOriginalState());
628fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
629fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        assertEquals(2, sm1.mEnterCount);
630fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        assertEquals(2, sm1.mExitCount);
631fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
632fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        if (sm1.isDbg()) Log.d(TAG, "testStateMachine1 X");
633fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    }
634fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
635fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    /**
636fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville     * Test deferring messages and states with no parents. The state machine
637fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville     * has two states, it receives two messages in state mS1 deferring them
638fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville     * until what == TEST_CMD_2 and then transitions to state mS2. State
639fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville     * mS2 then receives both of the deferred messages first TEST_CMD_1 and
640fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville     * then TEST_CMD_2.
641fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville     */
64264c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville    class StateMachine2 extends StateMachine {
643fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        StateMachine2(String name) {
644fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            super(name);
645fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            mThisSm = this;
646fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            setDbg(DBG);
647fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
648fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            // Setup the hierarchy
649fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            addState(mS1);
650fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            addState(mS2);
651fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
652fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            // Set the initial state
653fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            setInitialState(mS1);
654fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            if (DBG) Log.d(TAG, "StateMachine2: ctor X");
655fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        }
656fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
65764c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville        class S1 extends State {
65864c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            @Override
65964c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            public void enter() {
660fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                mDidEnter = true;
661fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            }
66264c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            @Override
66364c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            public void exit() {
66464c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville                mDidExit = true;
66564c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            }
66664c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            @Override
66764c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            public boolean processMessage(Message message) {
668fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                deferMessage(message);
669fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                if (message.what == TEST_CMD_2) {
670fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                    transitionTo(mS2);
671fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                }
672a4f3bec29c85ef9e0d07fdd551fe3c50f28b9adcWink Saville                return HANDLED;
673fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            }
674fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        }
675fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
67664c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville        class S2 extends State {
67764c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            @Override
67864c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            public boolean processMessage(Message message) {
679fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                if (message.what == TEST_CMD_2) {
680fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                    transitionToHaltingState();
681fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                }
682a4f3bec29c85ef9e0d07fdd551fe3c50f28b9adcWink Saville                return HANDLED;
683fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            }
684fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        }
685fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
686fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        @Override
687bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        protected void onHalting() {
688fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            synchronized (mThisSm) {
689fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                mThisSm.notifyAll();
690fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            }
691fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        }
692fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
693fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        private StateMachine2 mThisSm;
694fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        private S1 mS1 = new S1();
695fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        private S2 mS2 = new S2();
696fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
697fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        private boolean mDidEnter = false;
698fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        private boolean mDidExit = false;
699fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    }
700fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
701f76c56bcaa9df1d1afa711177f813dc63f399795Brett Chabot    @MediumTest
702fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    public void testStateMachine2() throws Exception {
703fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        StateMachine2 sm2 = new StateMachine2("sm2");
704fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        sm2.start();
705fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        if (sm2.isDbg()) Log.d(TAG, "testStateMachine2 E");
706fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
707fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        synchronized (sm2) {
708fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            // Send two messages
70991fbd56757751a7aca8ef2b4d936e587509e6eefWink Saville            sm2.sendMessage(TEST_CMD_1);
71091fbd56757751a7aca8ef2b4d936e587509e6eefWink Saville            sm2.sendMessage(TEST_CMD_2);
711fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
712fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            try {
713fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                // wait for the messages to be handled
714fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                sm2.wait();
715fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            } catch (InterruptedException e) {
716fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                Log.e(TAG, "testStateMachine2: exception while waiting " + e.getMessage());
717fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            }
718fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        }
719fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
720bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(4, sm2.getLogRecSize());
721fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
722bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        LogRec lr;
723bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        lr = sm2.getLogRec(0);
724bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(TEST_CMD_1, lr.getWhat());
725bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(sm2.mS1, lr.getState());
726fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
727bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        lr = sm2.getLogRec(1);
728bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(TEST_CMD_2, lr.getWhat());
729bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(sm2.mS1, lr.getState());
730fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
731bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        lr = sm2.getLogRec(2);
732bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(TEST_CMD_1, lr.getWhat());
733bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(sm2.mS2, lr.getState());
734fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
735bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        lr = sm2.getLogRec(3);
736bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(TEST_CMD_2, lr.getWhat());
737bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(sm2.mS2, lr.getState());
738fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
739fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        assertTrue(sm2.mDidEnter);
740fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        assertTrue(sm2.mDidExit);
741fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
742fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        if (sm2.isDbg()) Log.d(TAG, "testStateMachine2 X");
743fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    }
744fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
745fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    /**
746fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville     * Test that unhandled messages in a child are handled by the parent.
747fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville     * When TEST_CMD_2 is received.
748fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville     */
74964c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville    class StateMachine3 extends StateMachine {
750fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        StateMachine3(String name) {
751fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            super(name);
752fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            mThisSm = this;
753fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            setDbg(DBG);
754fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
755fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            // Setup the simplest hierarchy of two states
756fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            // mParentState and mChildState.
757fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            // (Use indentation to help visualize hierarchy)
758fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            addState(mParentState);
759fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                addState(mChildState, mParentState);
760fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
761fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            // Set the initial state will be the child
762fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            setInitialState(mChildState);
763fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            if (DBG) Log.d(TAG, "StateMachine3: ctor X");
764fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        }
765fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
76664c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville        class ParentState extends State {
76764c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            @Override
76864c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            public boolean processMessage(Message message) {
769fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                if (message.what == TEST_CMD_2) {
770fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                    transitionToHaltingState();
771fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                }
772a4f3bec29c85ef9e0d07fdd551fe3c50f28b9adcWink Saville                return HANDLED;
773fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            }
774fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        }
775fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
77664c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville        class ChildState extends State {
77764c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            @Override
77864c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            public boolean processMessage(Message message) {
779a4f3bec29c85ef9e0d07fdd551fe3c50f28b9adcWink Saville                return NOT_HANDLED;
780fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            }
781fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        }
782fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
783fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        @Override
784bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        protected void onHalting() {
785fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            synchronized (mThisSm) {
786fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                mThisSm.notifyAll();
787fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            }
788fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        }
789fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
790fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        private StateMachine3 mThisSm;
791fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        private ParentState mParentState = new ParentState();
792fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        private ChildState mChildState = new ChildState();
793fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    }
794fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
795f76c56bcaa9df1d1afa711177f813dc63f399795Brett Chabot    @MediumTest
796fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    public void testStateMachine3() throws Exception {
797fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        StateMachine3 sm3 = new StateMachine3("sm3");
798fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        sm3.start();
799fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        if (sm3.isDbg()) Log.d(TAG, "testStateMachine3 E");
800fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
801fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        synchronized (sm3) {
802fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            // Send two messages
80391fbd56757751a7aca8ef2b4d936e587509e6eefWink Saville            sm3.sendMessage(TEST_CMD_1);
80491fbd56757751a7aca8ef2b4d936e587509e6eefWink Saville            sm3.sendMessage(TEST_CMD_2);
805fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
806fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            try {
807fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                // wait for the messages to be handled
808fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                sm3.wait();
809fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            } catch (InterruptedException e) {
810fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                Log.e(TAG, "testStateMachine3: exception while waiting " + e.getMessage());
811fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            }
812fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        }
813fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
814bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(2, sm3.getLogRecSize());
815fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
816bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        LogRec lr;
817bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        lr = sm3.getLogRec(0);
818bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(TEST_CMD_1, lr.getWhat());
819bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(sm3.mParentState, lr.getState());
820bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(sm3.mChildState, lr.getOriginalState());
821fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
822bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        lr = sm3.getLogRec(1);
823bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(TEST_CMD_2, lr.getWhat());
824bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(sm3.mParentState, lr.getState());
825bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(sm3.mChildState, lr.getOriginalState());
826fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
827fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        if (sm3.isDbg()) Log.d(TAG, "testStateMachine3 X");
828fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    }
829fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
830fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    /**
831fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville     * Test a hierarchy of 3 states a parent and two children
832fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville     * with transition from child 1 to child 2 and child 2
833fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville     * lets the parent handle the messages.
834fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville     */
83564c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville    class StateMachine4 extends StateMachine {
836fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        StateMachine4(String name) {
837fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            super(name);
838fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            mThisSm = this;
839fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            setDbg(DBG);
840fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
841fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            // Setup a hierarchy of three states
842fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            // mParentState, mChildState1 & mChildState2
843fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            // (Use indentation to help visualize hierarchy)
844fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            addState(mParentState);
845fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                addState(mChildState1, mParentState);
846fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                addState(mChildState2, mParentState);
847fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
848fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            // Set the initial state will be child 1
849fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            setInitialState(mChildState1);
850fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            if (DBG) Log.d(TAG, "StateMachine4: ctor X");
851fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        }
852fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
85364c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville        class ParentState extends State {
85464c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            @Override
85564c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            public boolean processMessage(Message message) {
856fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                if (message.what == TEST_CMD_2) {
857fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                    transitionToHaltingState();
858fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                }
859a4f3bec29c85ef9e0d07fdd551fe3c50f28b9adcWink Saville                return HANDLED;
860fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            }
861fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        }
862fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
86364c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville        class ChildState1 extends State {
86464c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            @Override
86564c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            public boolean processMessage(Message message) {
866fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                transitionTo(mChildState2);
867a4f3bec29c85ef9e0d07fdd551fe3c50f28b9adcWink Saville                return HANDLED;
868fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            }
869fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        }
870fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
87164c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville        class ChildState2 extends State {
87264c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            @Override
87364c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            public boolean processMessage(Message message) {
874a4f3bec29c85ef9e0d07fdd551fe3c50f28b9adcWink Saville                return NOT_HANDLED;
875fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            }
876fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        }
877fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
878fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        @Override
879bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        protected void onHalting() {
880fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            synchronized (mThisSm) {
881fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                mThisSm.notifyAll();
882fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            }
883fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        }
884fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
885fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        private StateMachine4 mThisSm;
886fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        private ParentState mParentState = new ParentState();
887fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        private ChildState1 mChildState1 = new ChildState1();
888fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        private ChildState2 mChildState2 = new ChildState2();
889fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    }
890fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
891f76c56bcaa9df1d1afa711177f813dc63f399795Brett Chabot    @MediumTest
892fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    public void testStateMachine4() throws Exception {
893fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        StateMachine4 sm4 = new StateMachine4("sm4");
894fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        sm4.start();
895fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        if (sm4.isDbg()) Log.d(TAG, "testStateMachine4 E");
896fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
897fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        synchronized (sm4) {
898fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            // Send two messages
89991fbd56757751a7aca8ef2b4d936e587509e6eefWink Saville            sm4.sendMessage(TEST_CMD_1);
90091fbd56757751a7aca8ef2b4d936e587509e6eefWink Saville            sm4.sendMessage(TEST_CMD_2);
901fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
902fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            try {
903fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                // wait for the messages to be handled
904fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                sm4.wait();
905fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            } catch (InterruptedException e) {
906fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                Log.e(TAG, "testStateMachine4: exception while waiting " + e.getMessage());
907fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            }
908fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        }
909fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
910fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
911bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(2, sm4.getLogRecSize());
912fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
913bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        LogRec lr;
914bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        lr = sm4.getLogRec(0);
915bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(TEST_CMD_1, lr.getWhat());
916bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(sm4.mChildState1, lr.getState());
917bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(sm4.mChildState1, lr.getOriginalState());
918fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
919bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        lr = sm4.getLogRec(1);
920bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(TEST_CMD_2, lr.getWhat());
921bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(sm4.mParentState, lr.getState());
922bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(sm4.mChildState2, lr.getOriginalState());
923fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
924fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        if (sm4.isDbg()) Log.d(TAG, "testStateMachine4 X");
925fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    }
926fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
927fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    /**
928fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville     * Test transition from one child to another of a "complex"
929fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville     * hierarchy with two parents and multiple children.
930fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville     */
93164c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville    class StateMachine5 extends StateMachine {
932fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        StateMachine5(String name) {
933fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            super(name);
934fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            mThisSm = this;
935fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            setDbg(DBG);
936fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
937fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            // Setup a hierarchy with two parents and some children.
938fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            // (Use indentation to help visualize hierarchy)
939fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            addState(mParentState1);
940fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                addState(mChildState1, mParentState1);
941fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                addState(mChildState2, mParentState1);
942fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
943fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            addState(mParentState2);
944fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                addState(mChildState3, mParentState2);
945fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                addState(mChildState4, mParentState2);
946fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                    addState(mChildState5, mChildState4);
947fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
948fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            // Set the initial state will be the child
949fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            setInitialState(mChildState1);
950fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            if (DBG) Log.d(TAG, "StateMachine5: ctor X");
951fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        }
952fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
95364c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville        class ParentState1 extends State {
95464c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            @Override
95564c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            public void enter() {
956fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                mParentState1EnterCount += 1;
957fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            }
95864c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            @Override
95964c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            public void exit() {
960fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                mParentState1ExitCount += 1;
961fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            }
96264c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            @Override
96364c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            public boolean processMessage(Message message) {
96464c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville                return HANDLED;
96564c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            }
966fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        }
967fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
96864c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville        class ChildState1 extends State {
96964c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            @Override
97064c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            public void enter() {
971fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                mChildState1EnterCount += 1;
972fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            }
97364c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            @Override
97464c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            public void exit() {
97564c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville                mChildState1ExitCount += 1;
97664c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            }
97764c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            @Override
97864c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            public boolean processMessage(Message message) {
979fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(1, mParentState1EnterCount);
980fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(0, mParentState1ExitCount);
981fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(1, mChildState1EnterCount);
982fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(0, mChildState1ExitCount);
983fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(0, mChildState2EnterCount);
984fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(0, mChildState2ExitCount);
985fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(0, mParentState2EnterCount);
986fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(0, mParentState2ExitCount);
987fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(0, mChildState3EnterCount);
988fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(0, mChildState3ExitCount);
989fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(0, mChildState4EnterCount);
990fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(0, mChildState4ExitCount);
991fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(0, mChildState5EnterCount);
992fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(0, mChildState5ExitCount);
993fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
994fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                transitionTo(mChildState2);
995a4f3bec29c85ef9e0d07fdd551fe3c50f28b9adcWink Saville                return HANDLED;
996fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            }
997fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        }
998fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
99964c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville        class ChildState2 extends State {
100064c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            @Override
100164c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            public void enter() {
1002fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                mChildState2EnterCount += 1;
1003fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            }
100464c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            @Override
100564c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            public void exit() {
100664c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville                mChildState2ExitCount += 1;
100764c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            }
100864c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            @Override
100964c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            public boolean processMessage(Message message) {
1010fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(1, mParentState1EnterCount);
1011fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(0, mParentState1ExitCount);
1012fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(1, mChildState1EnterCount);
1013fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(1, mChildState1ExitCount);
1014fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(1, mChildState2EnterCount);
1015fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(0, mChildState2ExitCount);
1016fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(0, mParentState2EnterCount);
1017fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(0, mParentState2ExitCount);
1018fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(0, mChildState3EnterCount);
1019fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(0, mChildState3ExitCount);
1020fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(0, mChildState4EnterCount);
1021fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(0, mChildState4ExitCount);
1022fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(0, mChildState5EnterCount);
1023fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(0, mChildState5ExitCount);
1024fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1025fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                transitionTo(mChildState5);
1026a4f3bec29c85ef9e0d07fdd551fe3c50f28b9adcWink Saville                return HANDLED;
1027fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            }
1028fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        }
1029fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
103064c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville        class ParentState2 extends State {
103164c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            @Override
103264c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            public void enter() {
1033fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                mParentState2EnterCount += 1;
1034fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            }
103564c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            @Override
103664c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            public void exit() {
103764c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville                mParentState2ExitCount += 1;
103864c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            }
103964c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            @Override
104064c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            public boolean processMessage(Message message) {
1041fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(1, mParentState1EnterCount);
1042fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(1, mParentState1ExitCount);
1043fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(1, mChildState1EnterCount);
1044fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(1, mChildState1ExitCount);
1045fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(1, mChildState2EnterCount);
1046fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(1, mChildState2ExitCount);
1047fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(2, mParentState2EnterCount);
1048fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(1, mParentState2ExitCount);
1049fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(1, mChildState3EnterCount);
1050fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(1, mChildState3ExitCount);
1051fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(2, mChildState4EnterCount);
1052fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(2, mChildState4ExitCount);
1053fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(1, mChildState5EnterCount);
1054fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(1, mChildState5ExitCount);
1055fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1056fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                transitionToHaltingState();
1057a4f3bec29c85ef9e0d07fdd551fe3c50f28b9adcWink Saville                return HANDLED;
1058fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            }
1059fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        }
1060fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
106164c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville        class ChildState3 extends State {
106264c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            @Override
106364c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            public void enter() {
1064fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                mChildState3EnterCount += 1;
1065fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            }
106664c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            @Override
106764c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            public void exit() {
106864c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville                mChildState3ExitCount += 1;
106964c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            }
107064c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            @Override
107164c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            public boolean processMessage(Message message) {
1072fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(1, mParentState1EnterCount);
1073fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(1, mParentState1ExitCount);
1074fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(1, mChildState1EnterCount);
1075fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(1, mChildState1ExitCount);
1076fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(1, mChildState2EnterCount);
1077fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(1, mChildState2ExitCount);
1078fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(1, mParentState2EnterCount);
1079fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(0, mParentState2ExitCount);
1080fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(1, mChildState3EnterCount);
1081fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(0, mChildState3ExitCount);
1082fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(1, mChildState4EnterCount);
1083fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(1, mChildState4ExitCount);
1084fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(1, mChildState5EnterCount);
1085fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(1, mChildState5ExitCount);
1086fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1087fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                transitionTo(mChildState4);
1088a4f3bec29c85ef9e0d07fdd551fe3c50f28b9adcWink Saville                return HANDLED;
1089fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            }
1090fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        }
1091fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
109264c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville        class ChildState4 extends State {
109364c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            @Override
109464c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            public void enter() {
1095fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                mChildState4EnterCount += 1;
1096fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            }
109764c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            @Override
109864c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            public void exit() {
109964c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville                mChildState4ExitCount += 1;
110064c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            }
110164c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            @Override
110264c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            public boolean processMessage(Message message) {
1103fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(1, mParentState1EnterCount);
1104fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(1, mParentState1ExitCount);
1105fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(1, mChildState1EnterCount);
1106fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(1, mChildState1ExitCount);
1107fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(1, mChildState2EnterCount);
1108fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(1, mChildState2ExitCount);
1109fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(1, mParentState2EnterCount);
1110fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(0, mParentState2ExitCount);
1111fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(1, mChildState3EnterCount);
1112fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(1, mChildState3ExitCount);
1113fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(2, mChildState4EnterCount);
1114fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(1, mChildState4ExitCount);
1115fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(1, mChildState5EnterCount);
1116fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(1, mChildState5ExitCount);
1117fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1118fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                transitionTo(mParentState2);
1119a4f3bec29c85ef9e0d07fdd551fe3c50f28b9adcWink Saville                return HANDLED;
1120fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            }
1121fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        }
1122fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
112364c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville        class ChildState5 extends State {
112464c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            @Override
112564c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            public void enter() {
1126fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                mChildState5EnterCount += 1;
1127fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            }
112864c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            @Override
112964c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            public void exit() {
113064c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville                mChildState5ExitCount += 1;
113164c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            }
113264c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            @Override
113364c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            public boolean processMessage(Message message) {
1134fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(1, mParentState1EnterCount);
1135fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(1, mParentState1ExitCount);
1136fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(1, mChildState1EnterCount);
1137fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(1, mChildState1ExitCount);
1138fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(1, mChildState2EnterCount);
1139fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(1, mChildState2ExitCount);
1140fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(1, mParentState2EnterCount);
1141fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(0, mParentState2ExitCount);
1142fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(0, mChildState3EnterCount);
1143fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(0, mChildState3ExitCount);
1144fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(1, mChildState4EnterCount);
1145fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(0, mChildState4ExitCount);
1146fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(1, mChildState5EnterCount);
1147fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(0, mChildState5ExitCount);
1148fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1149fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                transitionTo(mChildState3);
1150a4f3bec29c85ef9e0d07fdd551fe3c50f28b9adcWink Saville                return HANDLED;
1151fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            }
1152fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        }
1153fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1154fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        @Override
1155bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        protected void onHalting() {
1156fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            synchronized (mThisSm) {
1157fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                mThisSm.notifyAll();
1158fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            }
1159fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        }
1160fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1161fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        private StateMachine5 mThisSm;
1162fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        private ParentState1 mParentState1 = new ParentState1();
1163fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        private ChildState1 mChildState1 = new ChildState1();
1164fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        private ChildState2 mChildState2 = new ChildState2();
1165fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        private ParentState2 mParentState2 = new ParentState2();
1166fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        private ChildState3 mChildState3 = new ChildState3();
1167fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        private ChildState4 mChildState4 = new ChildState4();
1168fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        private ChildState5 mChildState5 = new ChildState5();
1169fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1170fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        private int mParentState1EnterCount = 0;
1171fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        private int mParentState1ExitCount = 0;
1172fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        private int mChildState1EnterCount = 0;
1173fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        private int mChildState1ExitCount = 0;
1174fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        private int mChildState2EnterCount = 0;
1175fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        private int mChildState2ExitCount = 0;
1176fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        private int mParentState2EnterCount = 0;
1177fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        private int mParentState2ExitCount = 0;
1178fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        private int mChildState3EnterCount = 0;
1179fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        private int mChildState3ExitCount = 0;
1180fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        private int mChildState4EnterCount = 0;
1181fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        private int mChildState4ExitCount = 0;
1182fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        private int mChildState5EnterCount = 0;
1183fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        private int mChildState5ExitCount = 0;
1184fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    }
1185fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1186f76c56bcaa9df1d1afa711177f813dc63f399795Brett Chabot    @MediumTest
1187fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    public void testStateMachine5() throws Exception {
1188fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        StateMachine5 sm5 = new StateMachine5("sm5");
1189fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        sm5.start();
1190fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        if (sm5.isDbg()) Log.d(TAG, "testStateMachine5 E");
1191fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1192fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        synchronized (sm5) {
1193fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            // Send 6 messages
119491fbd56757751a7aca8ef2b4d936e587509e6eefWink Saville            sm5.sendMessage(TEST_CMD_1);
119591fbd56757751a7aca8ef2b4d936e587509e6eefWink Saville            sm5.sendMessage(TEST_CMD_2);
119691fbd56757751a7aca8ef2b4d936e587509e6eefWink Saville            sm5.sendMessage(TEST_CMD_3);
119791fbd56757751a7aca8ef2b4d936e587509e6eefWink Saville            sm5.sendMessage(TEST_CMD_4);
119891fbd56757751a7aca8ef2b4d936e587509e6eefWink Saville            sm5.sendMessage(TEST_CMD_5);
119991fbd56757751a7aca8ef2b4d936e587509e6eefWink Saville            sm5.sendMessage(TEST_CMD_6);
1200fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1201fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            try {
1202fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                // wait for the messages to be handled
1203fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                sm5.wait();
1204fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            } catch (InterruptedException e) {
1205fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                Log.e(TAG, "testStateMachine5: exception while waiting " + e.getMessage());
1206fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            }
1207fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        }
1208fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1209fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1210bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(6, sm5.getLogRecSize());
1211fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1212fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        assertEquals(1, sm5.mParentState1EnterCount);
1213fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        assertEquals(1, sm5.mParentState1ExitCount);
1214fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        assertEquals(1, sm5.mChildState1EnterCount);
1215fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        assertEquals(1, sm5.mChildState1ExitCount);
1216fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        assertEquals(1, sm5.mChildState2EnterCount);
1217fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        assertEquals(1, sm5.mChildState2ExitCount);
1218fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        assertEquals(2, sm5.mParentState2EnterCount);
1219fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        assertEquals(2, sm5.mParentState2ExitCount);
1220fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        assertEquals(1, sm5.mChildState3EnterCount);
1221fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        assertEquals(1, sm5.mChildState3ExitCount);
1222fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        assertEquals(2, sm5.mChildState4EnterCount);
1223fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        assertEquals(2, sm5.mChildState4ExitCount);
1224fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        assertEquals(1, sm5.mChildState5EnterCount);
1225fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        assertEquals(1, sm5.mChildState5ExitCount);
1226fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1227bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        LogRec lr;
1228bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        lr = sm5.getLogRec(0);
1229bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(TEST_CMD_1, lr.getWhat());
1230bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(sm5.mChildState1, lr.getState());
1231bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(sm5.mChildState1, lr.getOriginalState());
1232bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville
1233bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        lr = sm5.getLogRec(1);
1234bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(TEST_CMD_2, lr.getWhat());
1235bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(sm5.mChildState2, lr.getState());
1236bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(sm5.mChildState2, lr.getOriginalState());
1237bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville
1238bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        lr = sm5.getLogRec(2);
1239bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(TEST_CMD_3, lr.getWhat());
1240bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(sm5.mChildState5, lr.getState());
1241bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(sm5.mChildState5, lr.getOriginalState());
1242bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville
1243bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        lr = sm5.getLogRec(3);
1244bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(TEST_CMD_4, lr.getWhat());
1245bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(sm5.mChildState3, lr.getState());
1246bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(sm5.mChildState3, lr.getOriginalState());
1247bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville
1248bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        lr = sm5.getLogRec(4);
1249bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(TEST_CMD_5, lr.getWhat());
1250bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(sm5.mChildState4, lr.getState());
1251bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(sm5.mChildState4, lr.getOriginalState());
1252bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville
1253bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        lr = sm5.getLogRec(5);
1254bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(TEST_CMD_6, lr.getWhat());
1255bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(sm5.mParentState2, lr.getState());
1256bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(sm5.mParentState2, lr.getOriginalState());
1257fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1258fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        if (sm5.isDbg()) Log.d(TAG, "testStateMachine5 X");
1259fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    }
1260fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1261fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    /**
1262fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville     * Test that the initial state enter is invoked immediately
1263fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville     * after construction and before any other messages arrive and that
1264fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville     * sendMessageDelayed works.
1265fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville     */
126664c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville    class StateMachine6 extends StateMachine {
1267fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        StateMachine6(String name) {
1268fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            super(name);
1269fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            mThisSm = this;
1270fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            setDbg(DBG);
1271fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1272fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            // Setup state machine with 1 state
1273fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            addState(mS1);
1274fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1275fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            // Set the initial state
1276fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            setInitialState(mS1);
1277fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            if (DBG) Log.d(TAG, "StateMachine6: ctor X");
1278fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        }
1279fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
128064c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville        class S1 extends State {
128164c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            @Override
128264c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            public void enter() {
128391fbd56757751a7aca8ef2b4d936e587509e6eefWink Saville                sendMessage(TEST_CMD_1);
1284fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            }
128564c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            @Override
128664c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            public boolean processMessage(Message message) {
1287fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                if (message.what == TEST_CMD_1) {
1288fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                    mArrivalTimeMsg1 = SystemClock.elapsedRealtime();
1289fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                } else if (message.what == TEST_CMD_2) {
1290fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                    mArrivalTimeMsg2 = SystemClock.elapsedRealtime();
1291fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                    transitionToHaltingState();
1292fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                }
1293a4f3bec29c85ef9e0d07fdd551fe3c50f28b9adcWink Saville                return HANDLED;
1294fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            }
1295fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        }
1296fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1297fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        @Override
1298bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        protected void onHalting() {
1299fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            synchronized (mThisSm) {
1300fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                mThisSm.notifyAll();
1301fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            }
1302fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        }
1303fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1304fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        private StateMachine6 mThisSm;
1305fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        private S1 mS1 = new S1();
1306fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1307fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        private long mArrivalTimeMsg1;
1308fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        private long mArrivalTimeMsg2;
1309fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    }
1310fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1311f76c56bcaa9df1d1afa711177f813dc63f399795Brett Chabot    @MediumTest
1312fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    public void testStateMachine6() throws Exception {
1313fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        final int DELAY_TIME = 250;
1314fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        final int DELAY_FUDGE = 20;
1315fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1316fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        StateMachine6 sm6 = new StateMachine6("sm6");
1317fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        sm6.start();
1318fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        if (sm6.isDbg()) Log.d(TAG, "testStateMachine6 E");
1319fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1320fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        synchronized (sm6) {
1321fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            // Send a message
132291fbd56757751a7aca8ef2b4d936e587509e6eefWink Saville            sm6.sendMessageDelayed(TEST_CMD_2, DELAY_TIME);
1323fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1324fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            try {
1325fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                // wait for the messages to be handled
1326fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                sm6.wait();
1327fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            } catch (InterruptedException e) {
1328fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                Log.e(TAG, "testStateMachine6: exception while waiting " + e.getMessage());
1329fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            }
1330fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        }
1331fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1332fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        /**
1333fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville         * TEST_CMD_1 was sent in enter and must always have been processed
1334fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville         * immediately after construction and hence the arrival time difference
1335fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville         * should always >= to the DELAY_TIME
1336fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville         */
1337fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        long arrivalTimeDiff = sm6.mArrivalTimeMsg2 - sm6.mArrivalTimeMsg1;
1338fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        long expectedDelay = DELAY_TIME - DELAY_FUDGE;
1339fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        if (sm6.isDbg()) Log.d(TAG, "testStateMachine6: expect " + arrivalTimeDiff
1340fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                                    + " >= " + expectedDelay);
1341fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        assertTrue(arrivalTimeDiff >= expectedDelay);
1342fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1343fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        if (sm6.isDbg()) Log.d(TAG, "testStateMachine6 X");
1344fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    }
1345fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1346fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    /**
1347fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville     * Test that enter is invoked immediately after exit. This validates
1348fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville     * that enter can be used to send a watch dog message for its state.
1349fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville     */
135064c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville    class StateMachine7 extends StateMachine {
1351fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        private final int SM7_DELAY_TIME = 250;
1352fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1353fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        StateMachine7(String name) {
1354fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            super(name);
1355fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            mThisSm = this;
1356fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            setDbg(DBG);
1357fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1358fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            // Setup state machine with 1 state
1359fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            addState(mS1);
1360fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            addState(mS2);
1361fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1362fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            // Set the initial state
1363fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            setInitialState(mS1);
1364fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            if (DBG) Log.d(TAG, "StateMachine7: ctor X");
1365fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        }
1366fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
136764c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville        class S1 extends State {
136864c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            @Override
136964c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            public void exit() {
137064c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville                sendMessage(TEST_CMD_2);
137164c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            }
137264c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            @Override
137364c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            public boolean processMessage(Message message) {
1374fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                transitionTo(mS2);
1375a4f3bec29c85ef9e0d07fdd551fe3c50f28b9adcWink Saville                return HANDLED;
1376fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            }
1377fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        }
1378fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
137964c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville        class S2 extends State {
138064c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            @Override
138164c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            public void enter() {
1382fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                // Send a delayed message as a watch dog
138391fbd56757751a7aca8ef2b4d936e587509e6eefWink Saville                sendMessageDelayed(TEST_CMD_3, SM7_DELAY_TIME);
1384fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            }
138564c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            @Override
138664c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            public boolean processMessage(Message message) {
1387fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                if (message.what == TEST_CMD_2) {
1388fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                    mMsgCount += 1;
1389fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                    mArrivalTimeMsg2 = SystemClock.elapsedRealtime();
1390fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                } else if (message.what == TEST_CMD_3) {
1391fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                    mMsgCount += 1;
1392fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                    mArrivalTimeMsg3 = SystemClock.elapsedRealtime();
1393fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                }
1394fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1395fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                if (mMsgCount == 2) {
1396fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                    transitionToHaltingState();
1397fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                }
1398a4f3bec29c85ef9e0d07fdd551fe3c50f28b9adcWink Saville                return HANDLED;
1399fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            }
1400fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        }
1401fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1402fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        @Override
1403bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        protected void onHalting() {
1404fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            synchronized (mThisSm) {
1405fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                mThisSm.notifyAll();
1406fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            }
1407fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        }
1408fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1409fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        private StateMachine7 mThisSm;
1410fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        private S1 mS1 = new S1();
1411fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        private S2 mS2 = new S2();
1412fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1413fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        private int mMsgCount = 0;
1414fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        private long mArrivalTimeMsg2;
1415fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        private long mArrivalTimeMsg3;
1416fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    }
1417fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1418f76c56bcaa9df1d1afa711177f813dc63f399795Brett Chabot    @MediumTest
1419fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    public void testStateMachine7() throws Exception {
1420fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        final int SM7_DELAY_FUDGE = 20;
1421fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1422fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        StateMachine7 sm7 = new StateMachine7("sm7");
1423fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        sm7.start();
1424fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        if (sm7.isDbg()) Log.d(TAG, "testStateMachine7 E");
1425fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1426fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        synchronized (sm7) {
1427fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            // Send a message
142891fbd56757751a7aca8ef2b4d936e587509e6eefWink Saville            sm7.sendMessage(TEST_CMD_1);
1429fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1430fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            try {
1431fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                // wait for the messages to be handled
1432fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                sm7.wait();
1433fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            } catch (InterruptedException e) {
1434fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                Log.e(TAG, "testStateMachine7: exception while waiting " + e.getMessage());
1435fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            }
1436fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        }
1437fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1438fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        /**
1439fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville         * TEST_CMD_3 was sent in S2.enter with a delay and must always have been
1440fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville         * processed immediately after S1.exit. Since S1.exit sent TEST_CMD_2
1441fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville         * without a delay the arrival time difference should always >= to SM7_DELAY_TIME.
1442fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville         */
1443fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        long arrivalTimeDiff = sm7.mArrivalTimeMsg3 - sm7.mArrivalTimeMsg2;
1444fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        long expectedDelay = sm7.SM7_DELAY_TIME - SM7_DELAY_FUDGE;
1445fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        if (sm7.isDbg()) Log.d(TAG, "testStateMachine7: expect " + arrivalTimeDiff
1446fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                                    + " >= " + expectedDelay);
1447fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        assertTrue(arrivalTimeDiff >= expectedDelay);
1448fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1449fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        if (sm7.isDbg()) Log.d(TAG, "testStateMachine7 X");
1450fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    }
1451fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1452fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    /**
1453fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville     * Test unhandledMessage.
1454fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville     */
145564c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville    class StateMachineUnhandledMessage extends StateMachine {
1456fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        StateMachineUnhandledMessage(String name) {
1457fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            super(name);
1458fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            mThisSm = this;
1459fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            setDbg(DBG);
1460fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1461fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            // Setup state machine with 1 state
1462fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            addState(mS1);
1463fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1464fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            // Set the initial state
1465fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            setInitialState(mS1);
1466fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        }
146764c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville        @Override
146864c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville        public void unhandledMessage(Message message) {
1469fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            mUnhandledMessageCount += 1;
1470fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        }
1471fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
147264c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville        class S1 extends State {
147364c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            @Override
147464c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            public boolean processMessage(Message message) {
1475fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                if (message.what == TEST_CMD_2) {
1476fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                    transitionToHaltingState();
1477fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                }
1478a4f3bec29c85ef9e0d07fdd551fe3c50f28b9adcWink Saville                return NOT_HANDLED;
1479fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            }
1480fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        }
1481fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1482fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        @Override
1483bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        protected void onHalting() {
1484fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            synchronized (mThisSm) {
1485fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                mThisSm.notifyAll();
1486fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            }
1487fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        }
1488fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1489fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        private StateMachineUnhandledMessage mThisSm;
1490fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        private int mUnhandledMessageCount;
1491fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        private S1 mS1 = new S1();
1492fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    }
1493fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1494fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    @SmallTest
1495fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    public void testStateMachineUnhandledMessage() throws Exception {
1496fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1497fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        StateMachineUnhandledMessage sm = new StateMachineUnhandledMessage("sm");
1498fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        sm.start();
1499fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        if (sm.isDbg()) Log.d(TAG, "testStateMachineUnhandledMessage E");
1500fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1501fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        synchronized (sm) {
1502fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            // Send 2 messages
1503fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            for (int i = 1; i <= 2; i++) {
150491fbd56757751a7aca8ef2b4d936e587509e6eefWink Saville                sm.sendMessage(i);
1505fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            }
1506fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1507fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            try {
1508fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                // wait for the messages to be handled
1509fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                sm.wait();
1510fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            } catch (InterruptedException e) {
1511fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                Log.e(TAG, "testStateMachineUnhandledMessage: exception while waiting "
1512fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                        + e.getMessage());
1513fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            }
1514fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        }
1515fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1516bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(sm.getLogRecCount(), 2);
1517fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        assertEquals(2, sm.mUnhandledMessageCount);
1518fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1519fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        if (sm.isDbg()) Log.d(TAG, "testStateMachineUnhandledMessage X");
1520fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    }
1521fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1522fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    /**
1523fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville     * Test state machines sharing the same thread/looper. Multiple instances
1524fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville     * of the same state machine will be created. They will all share the
1525fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville     * same thread and thus each can update <code>sharedCounter</code> which
1526fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville     * will be used to notify testStateMachineSharedThread that the test is
1527fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville     * complete.
1528fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville     */
152964c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville    class StateMachineSharedThread extends StateMachine {
1530f0f566ec4607376583e59964a6a8a6dcb0265c20Wink Saville        StateMachineSharedThread(String name, Looper looper, int maxCount) {
1531f0f566ec4607376583e59964a6a8a6dcb0265c20Wink Saville            super(name, looper);
1532fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            mMaxCount = maxCount;
1533fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            setDbg(DBG);
1534fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1535fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            // Setup state machine with 1 state
1536fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            addState(mS1);
1537fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1538fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            // Set the initial state
1539fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            setInitialState(mS1);
1540fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        }
1541fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
154264c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville        class S1 extends State {
154364c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            @Override
154464c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            public boolean processMessage(Message message) {
1545fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                if (message.what == TEST_CMD_4) {
1546fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                    transitionToHaltingState();
1547fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                }
1548a4f3bec29c85ef9e0d07fdd551fe3c50f28b9adcWink Saville                return HANDLED;
1549fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            }
1550fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        }
1551fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1552fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        @Override
1553bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        protected void onHalting() {
1554fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            // Update the shared counter, which is OK since all state
1555fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            // machines are using the same thread.
1556fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            sharedCounter += 1;
1557fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            if (sharedCounter == mMaxCount) {
1558fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                synchronized (waitObject) {
1559fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                    waitObject.notifyAll();
1560fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                }
1561fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            }
1562fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        }
1563fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1564fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        private int mMaxCount;
1565fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        private S1 mS1 = new S1();
1566fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    }
1567fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    private static int sharedCounter = 0;
1568fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    private static Object waitObject = new Object();
1569fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1570f76c56bcaa9df1d1afa711177f813dc63f399795Brett Chabot    @MediumTest
1571fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    public void testStateMachineSharedThread() throws Exception {
1572fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        if (DBG) Log.d(TAG, "testStateMachineSharedThread E");
1573fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1574fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        // Create and start the handler thread
1575fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        HandlerThread smThread = new HandlerThread("testStateMachineSharedThread");
1576fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        smThread.start();
1577fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1578fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        // Create the state machines
1579fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        StateMachineSharedThread sms[] = new StateMachineSharedThread[10];
1580fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        for (int i = 0; i < sms.length; i++) {
1581f0f566ec4607376583e59964a6a8a6dcb0265c20Wink Saville            sms[i] = new StateMachineSharedThread("sm", smThread.getLooper(), sms.length);
1582fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            sms[i].start();
1583fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        }
1584fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1585fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        synchronized (waitObject) {
1586fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            // Send messages to each of the state machines
1587fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            for (StateMachineSharedThread sm : sms) {
1588fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                for (int i = 1; i <= 4; i++) {
158991fbd56757751a7aca8ef2b4d936e587509e6eefWink Saville                    sm.sendMessage(i);
1590fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                }
1591fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            }
1592fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1593fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            // Wait for the last state machine to notify its done
1594fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            try {
1595fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                waitObject.wait();
1596fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            } catch (InterruptedException e) {
1597fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                Log.e(TAG, "testStateMachineSharedThread: exception while waiting "
1598fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                        + e.getMessage());
1599fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            }
1600fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        }
1601fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1602fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        for (StateMachineSharedThread sm : sms) {
1603bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville            assertEquals(sm.getLogRecCount(), 4);
1604bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville            for (int i = 0; i < sm.getLogRecCount(); i++) {
1605bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville                LogRec lr = sm.getLogRec(i);
1606bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville                assertEquals(i+1, lr.getWhat());
1607bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville                assertEquals(sm.mS1, lr.getState());
1608bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville                assertEquals(sm.mS1, lr.getOriginalState());
1609fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            }
1610fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        }
1611fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1612fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        if (DBG) Log.d(TAG, "testStateMachineSharedThread X");
1613fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    }
1614fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1615f76c56bcaa9df1d1afa711177f813dc63f399795Brett Chabot    @MediumTest
1616fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    public void testHsm1() throws Exception {
1617fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        if (DBG) Log.d(TAG, "testHsm1 E");
1618fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1619fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        Hsm1 sm = Hsm1.makeHsm1();
1620fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1621fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        // Send messages
162291fbd56757751a7aca8ef2b4d936e587509e6eefWink Saville        sm.sendMessage(Hsm1.CMD_1);
162391fbd56757751a7aca8ef2b4d936e587509e6eefWink Saville        sm.sendMessage(Hsm1.CMD_2);
1624fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1625fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        synchronized (sm) {
1626fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            // Wait for the last state machine to notify its done
1627fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            try {
1628fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                sm.wait();
1629fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            } catch (InterruptedException e) {
1630fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                Log.e(TAG, "testHsm1: exception while waiting " + e.getMessage());
1631fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            }
1632fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        }
1633fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1634bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(7, sm.getLogRecCount());
1635bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        LogRec lr = sm.getLogRec(0);
1636bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(Hsm1.CMD_1, lr.getWhat());
1637bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(sm.mS1, lr.getState());
1638bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(sm.mS1, lr.getOriginalState());
1639fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1640bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        lr = sm.getLogRec(1);
1641bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(Hsm1.CMD_2, lr.getWhat());
1642bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(sm.mP1, lr.getState());
1643bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(sm.mS1, lr.getOriginalState());
1644fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1645bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        lr = sm.getLogRec(2);
1646bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(Hsm1.CMD_2, lr.getWhat());
1647bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(sm.mS2, lr.getState());
1648bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(sm.mS2, lr.getOriginalState());
1649fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1650bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        lr = sm.getLogRec(3);
1651bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(Hsm1.CMD_3, lr.getWhat());
1652bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(sm.mS2, lr.getState());
1653bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(sm.mS2, lr.getOriginalState());
1654fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1655bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        lr = sm.getLogRec(4);
1656bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(Hsm1.CMD_3, lr.getWhat());
1657bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(sm.mP2, lr.getState());
1658bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(sm.mP2, lr.getOriginalState());
1659fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1660bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        lr = sm.getLogRec(5);
1661bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(Hsm1.CMD_4, lr.getWhat());
1662bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(sm.mP2, lr.getState());
1663bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(sm.mP2, lr.getOriginalState());
1664fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1665bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        lr = sm.getLogRec(6);
1666bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(Hsm1.CMD_5, lr.getWhat());
1667bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(sm.mP2, lr.getState());
1668bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(sm.mP2, lr.getOriginalState());
1669fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1670fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        if (DBG) Log.d(TAG, "testStateMachineSharedThread X");
1671fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    }
1672fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville}
1673fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
167464c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Savilleclass Hsm1 extends StateMachine {
1675fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    private static final String TAG = "hsm1";
1676fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1677fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    public static final int CMD_1 = 1;
1678fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    public static final int CMD_2 = 2;
1679fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    public static final int CMD_3 = 3;
1680fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    public static final int CMD_4 = 4;
1681fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    public static final int CMD_5 = 5;
1682fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1683fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    public static Hsm1 makeHsm1() {
1684fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        Log.d(TAG, "makeHsm1 E");
1685fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        Hsm1 sm = new Hsm1("hsm1");
1686fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        sm.start();
1687fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        Log.d(TAG, "makeHsm1 X");
1688fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        return sm;
1689fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    }
1690fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1691fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    Hsm1(String name) {
1692fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        super(name);
1693fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        Log.d(TAG, "ctor E");
1694fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1695fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        // Add states, use indentation to show hierarchy
1696fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        addState(mP1);
1697fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            addState(mS1, mP1);
1698fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            addState(mS2, mP1);
1699fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        addState(mP2);
1700fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1701fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        // Set the initial state
1702fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        setInitialState(mS1);
1703fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        Log.d(TAG, "ctor X");
1704fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    }
1705fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
170664c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville    class P1 extends State {
170764c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville        @Override
170864c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville        public void enter() {
1709fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            Log.d(TAG, "P1.enter");
1710fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        }
171164c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville        @Override
171264c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville        public void exit() {
171364c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            Log.d(TAG, "P1.exit");
171464c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville        }
171564c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville        @Override
171664c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville        public boolean processMessage(Message message) {
1717fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            boolean retVal;
1718fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            Log.d(TAG, "P1.processMessage what=" + message.what);
1719fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            switch(message.what) {
1720fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            case CMD_2:
1721fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                // CMD_2 will arrive in mS2 before CMD_3
172291fbd56757751a7aca8ef2b4d936e587509e6eefWink Saville                sendMessage(CMD_3);
1723fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                deferMessage(message);
1724fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                transitionTo(mS2);
1725fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                retVal = true;
1726fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                break;
1727fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            default:
1728fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                // Any message we don't understand in this state invokes unhandledMessage
1729fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                retVal = false;
1730fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                break;
1731fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            }
1732fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            return retVal;
1733fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        }
1734fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    }
1735fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
173664c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville    class S1 extends State {
173764c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville        @Override
173864c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville        public void enter() {
1739fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            Log.d(TAG, "S1.enter");
1740fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        }
174164c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville        @Override
174264c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville        public void exit() {
174364c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            Log.d(TAG, "S1.exit");
174464c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville        }
174564c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville        @Override
174664c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville        public boolean processMessage(Message message) {
1747fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            Log.d(TAG, "S1.processMessage what=" + message.what);
1748fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            if (message.what == CMD_1) {
1749fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                // Transition to ourself to show that enter/exit is called
1750fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                transitionTo(mS1);
1751a4f3bec29c85ef9e0d07fdd551fe3c50f28b9adcWink Saville                return HANDLED;
1752fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            } else {
1753fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                // Let parent process all other messages
1754a4f3bec29c85ef9e0d07fdd551fe3c50f28b9adcWink Saville                return NOT_HANDLED;
1755fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            }
1756fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        }
1757fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    }
1758fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
175964c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville    class S2 extends State {
176064c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville        @Override
176164c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville        public void enter() {
1762fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            Log.d(TAG, "S2.enter");
1763fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        }
176464c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville        @Override
176564c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville        public void exit() {
176664c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            Log.d(TAG, "S2.exit");
176764c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville        }
176864c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville        @Override
176964c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville        public boolean processMessage(Message message) {
1770fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            boolean retVal;
1771fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            Log.d(TAG, "S2.processMessage what=" + message.what);
1772fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            switch(message.what) {
1773fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            case(CMD_2):
177491fbd56757751a7aca8ef2b4d936e587509e6eefWink Saville                sendMessage(CMD_4);
1775fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                retVal = true;
1776fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                break;
1777fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            case(CMD_3):
1778fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                deferMessage(message);
1779fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                transitionTo(mP2);
1780fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                retVal = true;
1781fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                break;
1782fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            default:
1783fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                retVal = false;
1784fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                break;
1785fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            }
1786fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            return retVal;
1787fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        }
1788fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    }
1789fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
179064c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville    class P2 extends State {
179164c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville        @Override
179264c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville        public void enter() {
1793fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            Log.d(TAG, "P2.enter");
179491fbd56757751a7aca8ef2b4d936e587509e6eefWink Saville            sendMessage(CMD_5);
1795fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        }
179664c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville        @Override
179764c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville        public void exit() {
179864c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            Log.d(TAG, "P2.exit");
179964c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville        }
180064c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville        @Override
180164c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville        public boolean processMessage(Message message) {
1802fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            Log.d(TAG, "P2.processMessage what=" + message.what);
1803fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            switch(message.what) {
1804fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            case(CMD_3):
1805fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                break;
1806fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            case(CMD_4):
1807fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                break;
1808fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            case(CMD_5):
1809fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                transitionToHaltingState();
1810fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                break;
1811fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            }
1812a4f3bec29c85ef9e0d07fdd551fe3c50f28b9adcWink Saville            return HANDLED;
1813fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        }
1814fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    }
1815fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1816fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    @Override
1817bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville    protected void onHalting() {
1818fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        Log.d(TAG, "halting");
1819fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        synchronized (this) {
1820fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            this.notifyAll();
1821fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        }
1822fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    }
1823fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1824fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    P1 mP1 = new P1();
1825fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    S1 mS1 = new S1();
1826fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    S2 mS2 = new S2();
1827fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    P2 mP2 = new P2();
1828fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville}
1829