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
19efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Savilleimport java.util.Collection;
20efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Savilleimport java.util.Iterator;
21efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville
226b888d98f7fffe5b87b3d5421d2f9a119899c7ddWink Savilleimport android.os.Debug;
236b888d98f7fffe5b87b3d5421d2f9a119899c7ddWink Savilleimport android.os.HandlerThread;
246b888d98f7fffe5b87b3d5421d2f9a119899c7ddWink Savilleimport android.os.Looper;
256b888d98f7fffe5b87b3d5421d2f9a119899c7ddWink Savilleimport android.os.Message;
266b888d98f7fffe5b87b3d5421d2f9a119899c7ddWink Savilleimport android.os.SystemClock;
27fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
2864c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Savilleimport com.android.internal.util.State;
2964c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Savilleimport com.android.internal.util.StateMachine;
30bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Savilleimport com.android.internal.util.StateMachine.LogRec;
31fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
32f76c56bcaa9df1d1afa711177f813dc63f399795Brett Chabotimport android.test.suitebuilder.annotation.MediumTest;
33fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Savilleimport android.test.suitebuilder.annotation.SmallTest;
34fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Savilleimport android.util.Log;
35fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
36f76c56bcaa9df1d1afa711177f813dc63f399795Brett Chabotimport junit.framework.TestCase;
37fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
38fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville/**
3964c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville * Test for StateMachine.
40fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville */
4164c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Savillepublic class StateMachineTest extends TestCase {
42bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville    private static final String ENTER = "enter";
43bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville    private static final String EXIT = "exit";
44bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville    private static final String ON_QUITTING = "ON_QUITTING";
45bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville
46fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    private static final int TEST_CMD_1 = 1;
47fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    private static final int TEST_CMD_2 = 2;
48fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    private static final int TEST_CMD_3 = 3;
49fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    private static final int TEST_CMD_4 = 4;
50fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    private static final int TEST_CMD_5 = 5;
51fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    private static final int TEST_CMD_6 = 6;
52fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
53fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    private static final boolean DBG = true;
546b888d98f7fffe5b87b3d5421d2f9a119899c7ddWink Saville    private static final boolean WAIT_FOR_DEBUGGER = false;
5564c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville    private static final String TAG = "StateMachineTest";
56fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
57bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville    private void sleep(int millis) {
58bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        try {
59bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville            Thread.sleep(millis);
60bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        } catch(InterruptedException e) {
61bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        }
62bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville    }
63bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville
64efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville    private void dumpLogRecs(StateMachine sm) {
65efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        int size = sm.getLogRecSize();
66efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        tlog("size=" + size + " count=" + sm.getLogRecCount());
67efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        for (int i = 0; i < size; i++) {
68efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville            LogRec lr = sm.getLogRec(i);
69efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville            tlog(lr.toString());
70efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        }
71efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville    }
72efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville
73efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville    private void dumpLogRecs(Collection<LogRec> clr) {
74efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        int size = clr.size();
75efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        tlog("size=" + size);
76efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        for (LogRec lr : clr) {
77efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville            tlog(lr.toString());
78efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        }
79efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville    }
80efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville
81fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    /**
82bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville     * Tests {@link StateMachine#quit()}.
831b8b98b3db5dcf0b01d1a632aafea076cc91f5a4Wink Saville     */
8464c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville    class StateMachineQuitTest extends StateMachine {
85efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        Collection<LogRec> mLogRecs;
861b8b98b3db5dcf0b01d1a632aafea076cc91f5a4Wink Saville
871b8b98b3db5dcf0b01d1a632aafea076cc91f5a4Wink Saville        StateMachineQuitTest(String name) {
881b8b98b3db5dcf0b01d1a632aafea076cc91f5a4Wink Saville            super(name);
891b8b98b3db5dcf0b01d1a632aafea076cc91f5a4Wink Saville            mThisSm = this;
901b8b98b3db5dcf0b01d1a632aafea076cc91f5a4Wink Saville            setDbg(DBG);
911b8b98b3db5dcf0b01d1a632aafea076cc91f5a4Wink Saville
921b8b98b3db5dcf0b01d1a632aafea076cc91f5a4Wink Saville            // Setup state machine with 1 state
931b8b98b3db5dcf0b01d1a632aafea076cc91f5a4Wink Saville            addState(mS1);
941b8b98b3db5dcf0b01d1a632aafea076cc91f5a4Wink Saville
951b8b98b3db5dcf0b01d1a632aafea076cc91f5a4Wink Saville            // Set the initial state
961b8b98b3db5dcf0b01d1a632aafea076cc91f5a4Wink Saville            setInitialState(mS1);
971b8b98b3db5dcf0b01d1a632aafea076cc91f5a4Wink Saville        }
981b8b98b3db5dcf0b01d1a632aafea076cc91f5a4Wink Saville
99bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        @Override
100bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        public void onQuitting() {
101efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville            log("onQuitting");
102bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville            addLogRec(ON_QUITTING);
103efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville            mLogRecs = mThisSm.copyLogRecs();
104bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville            synchronized (mThisSm) {
105bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville                mThisSm.notifyAll();
106bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville            }
107bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        }
108bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville
10964c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville        class S1 extends State {
110efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville            @Override
111bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville            public void exit() {
112efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                log("S1.exit");
113efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                addLogRec(EXIT);
114bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville            }
11564c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            @Override
11664c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            public boolean processMessage(Message message) {
117bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville                switch(message.what) {
118bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville                    // Sleep and assume the other messages will be queued up.
119bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville                    case TEST_CMD_1: {
120efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                        log("TEST_CMD_1");
121bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville                        sleep(500);
122bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville                        quit();
123bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville                        break;
124bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville                    }
125bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville                    default: {
126efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                        log("default what=" + message.what);
127bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville                        break;
1281b8b98b3db5dcf0b01d1a632aafea076cc91f5a4Wink Saville                    }
1291b8b98b3db5dcf0b01d1a632aafea076cc91f5a4Wink Saville                }
130bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville                return HANDLED;
1311b8b98b3db5dcf0b01d1a632aafea076cc91f5a4Wink Saville            }
1321b8b98b3db5dcf0b01d1a632aafea076cc91f5a4Wink Saville        }
1331b8b98b3db5dcf0b01d1a632aafea076cc91f5a4Wink Saville
1341b8b98b3db5dcf0b01d1a632aafea076cc91f5a4Wink Saville        private StateMachineQuitTest mThisSm;
1351b8b98b3db5dcf0b01d1a632aafea076cc91f5a4Wink Saville        private S1 mS1 = new S1();
1361b8b98b3db5dcf0b01d1a632aafea076cc91f5a4Wink Saville    }
1371b8b98b3db5dcf0b01d1a632aafea076cc91f5a4Wink Saville
1381b8b98b3db5dcf0b01d1a632aafea076cc91f5a4Wink Saville    @SmallTest
139bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville    public void testStateMachineQuit() throws Exception {
1406b888d98f7fffe5b87b3d5421d2f9a119899c7ddWink Saville        if (WAIT_FOR_DEBUGGER) Debug.waitForDebugger();
1411b8b98b3db5dcf0b01d1a632aafea076cc91f5a4Wink Saville
1421b8b98b3db5dcf0b01d1a632aafea076cc91f5a4Wink Saville        StateMachineQuitTest smQuitTest = new StateMachineQuitTest("smQuitTest");
1431b8b98b3db5dcf0b01d1a632aafea076cc91f5a4Wink Saville        smQuitTest.start();
144efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        if (smQuitTest.isDbg()) tlog("testStateMachineQuit E");
1451b8b98b3db5dcf0b01d1a632aafea076cc91f5a4Wink Saville
1461b8b98b3db5dcf0b01d1a632aafea076cc91f5a4Wink Saville        synchronized (smQuitTest) {
147bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville
148bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville            // Send 6 message we'll quit on the first but all 6 should be processed before quitting.
1491b8b98b3db5dcf0b01d1a632aafea076cc91f5a4Wink Saville            for (int i = 1; i <= 6; i++) {
150bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville                smQuitTest.sendMessage(smQuitTest.obtainMessage(i));
151bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville            }
152bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville
153bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville            try {
154bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville                // wait for the messages to be handled
155bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville                smQuitTest.wait();
156bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville            } catch (InterruptedException e) {
157efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                tloge("testStateMachineQuit: exception while waiting " + e.getMessage());
158bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville            }
159bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        }
160bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville
161efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        dumpLogRecs(smQuitTest.mLogRecs);
162efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        assertEquals(8, smQuitTest.mLogRecs.size());
163bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville
164bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        LogRec lr;
165efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        Iterator<LogRec> itr = smQuitTest.mLogRecs.iterator();
166efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        for (int i = 1; i <= 6; i++) {
167efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville            lr = itr.next();
168efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville            assertEquals(i, lr.getWhat());
169bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville            assertEquals(smQuitTest.mS1, lr.getState());
170bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville            assertEquals(smQuitTest.mS1, lr.getOriginalState());
171bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        }
172efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        lr = itr.next();
173bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(EXIT, lr.getInfo());
174bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(smQuitTest.mS1, lr.getState());
175bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville
176efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        lr = itr.next();
177bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(ON_QUITTING, lr.getInfo());
178bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville
179efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        if (smQuitTest.isDbg()) tlog("testStateMachineQuit X");
180bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville    }
181bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville
182bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville    /**
183bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville     * Tests {@link StateMachine#quitNow()}
184bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville     */
185bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville    class StateMachineQuitNowTest extends StateMachine {
186efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        public Collection<LogRec> mLogRecs = null;
187bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville
188bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        StateMachineQuitNowTest(String name) {
189bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville            super(name);
190bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville            mThisSm = this;
191bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville            setDbg(DBG);
192bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville
193bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville            // Setup state machine with 1 state
194bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville            addState(mS1);
195bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville
196bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville            // Set the initial state
197bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville            setInitialState(mS1);
198bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        }
199bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville
200bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        @Override
201bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        public void onQuitting() {
202efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville            log("onQuitting");
203bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville            addLogRec(ON_QUITTING);
204efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville            // Get a copy of the log records since we're quitting and they will disappear
205efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville            mLogRecs = mThisSm.copyLogRecs();
206efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville
207bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville            synchronized (mThisSm) {
208bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville                mThisSm.notifyAll();
209bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville            }
210bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        }
211bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville
212bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        class S1 extends State {
213efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville            @Override
214bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville            public void exit() {
215efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                log("S1.exit");
216efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                addLogRec(EXIT);
2171b8b98b3db5dcf0b01d1a632aafea076cc91f5a4Wink Saville            }
218bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville            @Override
219bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville            public boolean processMessage(Message message) {
220bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville                switch(message.what) {
221bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville                    // Sleep and assume the other messages will be queued up.
222bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville                    case TEST_CMD_1: {
223efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                        log("TEST_CMD_1");
224bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville                        sleep(500);
225bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville                        quitNow();
226bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville                        break;
227bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville                    }
228bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville                    default: {
229efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                        log("default what=" + message.what);
230bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville                        break;
231bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville                    }
232bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville                }
233bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville                return HANDLED;
234bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville            }
235bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        }
236bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville
237bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        private StateMachineQuitNowTest mThisSm;
238bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        private S1 mS1 = new S1();
239bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville    }
2401b8b98b3db5dcf0b01d1a632aafea076cc91f5a4Wink Saville
241bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville    @SmallTest
242bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville    public void testStateMachineQuitNow() throws Exception {
243bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        if (WAIT_FOR_DEBUGGER) Debug.waitForDebugger();
2441b8b98b3db5dcf0b01d1a632aafea076cc91f5a4Wink Saville
245bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        StateMachineQuitNowTest smQuitNowTest = new StateMachineQuitNowTest("smQuitNowTest");
246bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        smQuitNowTest.start();
247efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        if (smQuitNowTest.isDbg()) tlog("testStateMachineQuitNow E");
248bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville
249bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        synchronized (smQuitNowTest) {
250bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville
251efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville            // Send 6 message we'll QuitNow on the first even though
252bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville            // we send 6 only one will be processed.
253bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville            for (int i = 1; i <= 6; i++) {
254bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville                smQuitNowTest.sendMessage(smQuitNowTest.obtainMessage(i));
255bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville            }
2561b8b98b3db5dcf0b01d1a632aafea076cc91f5a4Wink Saville
2571b8b98b3db5dcf0b01d1a632aafea076cc91f5a4Wink Saville            try {
2581b8b98b3db5dcf0b01d1a632aafea076cc91f5a4Wink Saville                // wait for the messages to be handled
259bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville                smQuitNowTest.wait();
2601b8b98b3db5dcf0b01d1a632aafea076cc91f5a4Wink Saville            } catch (InterruptedException e) {
261efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                tloge("testStateMachineQuitNow: exception while waiting " + e.getMessage());
2621b8b98b3db5dcf0b01d1a632aafea076cc91f5a4Wink Saville            }
2631b8b98b3db5dcf0b01d1a632aafea076cc91f5a4Wink Saville        }
2641b8b98b3db5dcf0b01d1a632aafea076cc91f5a4Wink Saville
265efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        tlog("testStateMachineQuiteNow: logRecs=" + smQuitNowTest.mLogRecs);
266efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        assertEquals(3, smQuitNowTest.mLogRecs.size());
2671b8b98b3db5dcf0b01d1a632aafea076cc91f5a4Wink Saville
268efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        Iterator<LogRec> itr = smQuitNowTest.mLogRecs.iterator();
269efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        LogRec lr = itr.next();
270bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(1, lr.getWhat());
271bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(smQuitNowTest.mS1, lr.getState());
272bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(smQuitNowTest.mS1, lr.getOriginalState());
2731b8b98b3db5dcf0b01d1a632aafea076cc91f5a4Wink Saville
274efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        lr = itr.next();
275bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(EXIT, lr.getInfo());
276bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(smQuitNowTest.mS1, lr.getState());
2771b8b98b3db5dcf0b01d1a632aafea076cc91f5a4Wink Saville
278efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        lr = itr.next();
279bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(ON_QUITTING, lr.getInfo());
2801b8b98b3db5dcf0b01d1a632aafea076cc91f5a4Wink Saville
281efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        if (smQuitNowTest.isDbg()) tlog("testStateMachineQuitNow X");
2821b8b98b3db5dcf0b01d1a632aafea076cc91f5a4Wink Saville    }
2831b8b98b3db5dcf0b01d1a632aafea076cc91f5a4Wink Saville
2841b8b98b3db5dcf0b01d1a632aafea076cc91f5a4Wink Saville    /**
285e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville     * Test enter/exit can use transitionTo
286e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville     */
28764c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville    class StateMachineEnterExitTransitionToTest extends StateMachine {
288bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville
289e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville        StateMachineEnterExitTransitionToTest(String name) {
290e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville            super(name);
291e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville            mThisSm = this;
292e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville            setDbg(DBG);
293e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville
294e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville            // Setup state machine with 1 state
295e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville            addState(mS1);
296e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville            addState(mS2);
297e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville            addState(mS3);
298e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville            addState(mS4);
299e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville
300e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville            // Set the initial state
301e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville            setInitialState(mS1);
302e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville        }
303e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville
30464c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville        class S1 extends State {
30564c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            @Override
30664c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            public void enter() {
307bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville                // Test transitions in enter on the initial state work
308efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                addLogRec(ENTER);
309e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville                transitionTo(mS2);
310efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                log("S1.enter");
311e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville            }
31264c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            @Override
31364c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            public void exit() {
314efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                addLogRec(EXIT);
315efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                log("S1.exit");
316e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville            }
317e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville        }
318e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville
31964c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville        class S2 extends State {
32064c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            @Override
32164c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            public void enter() {
322efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                addLogRec(ENTER);
323efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                log("S2.enter");
324e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville            }
32564c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            @Override
32664c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            public void exit() {
327e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville                // Test transition in exit work
328e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville                transitionTo(mS4);
329efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville
330efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                assertEquals(TEST_CMD_1, getCurrentMessage().what);
331efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                addLogRec(EXIT);
332efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville
333efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                log("S2.exit");
334e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville            }
33564c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            @Override
33664c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            public boolean processMessage(Message message) {
337e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville                // Start a transition to S3 but it will be
338a4f3bec29c85ef9e0d07fdd551fe3c50f28b9adcWink Saville                // changed to a transition to S4 in exit
339e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville                transitionTo(mS3);
340efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                log("S2.processMessage");
341a4f3bec29c85ef9e0d07fdd551fe3c50f28b9adcWink Saville                return HANDLED;
342e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville            }
343e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville        }
344e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville
34564c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville        class S3 extends State {
34664c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            @Override
34764c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            public void enter() {
348efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                addLogRec(ENTER);
349efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                log("S3.enter");
350e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville            }
35164c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            @Override
35264c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            public void exit() {
353efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                addLogRec(EXIT);
354efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                log("S3.exit");
355e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville            }
356e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville        }
357e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville
35864c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville        class S4 extends State {
35964c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            @Override
36064c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            public void enter() {
361efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                addLogRec(ENTER);
362e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville                // Test that we can do halting in an enter/exit
363e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville                transitionToHaltingState();
364efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                log("S4.enter");
365e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville            }
36664c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            @Override
36764c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            public void exit() {
368efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                addLogRec(EXIT);
369efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                log("S4.exit");
370e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville            }
371e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville        }
372e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville
373e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville        @Override
374bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        protected void onHalting() {
375e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville            synchronized (mThisSm) {
376e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville                mThisSm.notifyAll();
377e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville            }
378e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville        }
379e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville
380e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville        private StateMachineEnterExitTransitionToTest mThisSm;
381e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville        private S1 mS1 = new S1();
382e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville        private S2 mS2 = new S2();
383e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville        private S3 mS3 = new S3();
384e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville        private S4 mS4 = new S4();
385e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville    }
386e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville
387e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville    @SmallTest
388e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville    public void testStateMachineEnterExitTransitionToTest() throws Exception {
389e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville        //if (WAIT_FOR_DEBUGGER) Debug.waitForDebugger();
390e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville
391e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville        StateMachineEnterExitTransitionToTest smEnterExitTranstionToTest =
392e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville            new StateMachineEnterExitTransitionToTest("smEnterExitTranstionToTest");
393e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville        smEnterExitTranstionToTest.start();
394e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville        if (smEnterExitTranstionToTest.isDbg()) {
395efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville            tlog("testStateMachineEnterExitTransitionToTest E");
396e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville        }
397e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville
398e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville        synchronized (smEnterExitTranstionToTest) {
399a4f3bec29c85ef9e0d07fdd551fe3c50f28b9adcWink Saville            smEnterExitTranstionToTest.sendMessage(TEST_CMD_1);
400e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville
401e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville            try {
402e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville                // wait for the messages to be handled
403e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville                smEnterExitTranstionToTest.wait();
404e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville            } catch (InterruptedException e) {
405efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                tloge("testStateMachineEnterExitTransitionToTest: exception while waiting "
406e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville                    + e.getMessage());
407e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville            }
408e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville        }
409e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville
410efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        dumpLogRecs(smEnterExitTranstionToTest);
411bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville
412efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        assertEquals(9, smEnterExitTranstionToTest.getLogRecCount());
413bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        LogRec lr;
414bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville
415bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        lr = smEnterExitTranstionToTest.getLogRec(0);
416bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(ENTER, lr.getInfo());
417bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(smEnterExitTranstionToTest.mS1, lr.getState());
418bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville
419bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        lr = smEnterExitTranstionToTest.getLogRec(1);
420bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(EXIT, lr.getInfo());
421bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(smEnterExitTranstionToTest.mS1, lr.getState());
422bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville
423bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        lr = smEnterExitTranstionToTest.getLogRec(2);
424bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(ENTER, lr.getInfo());
425bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(smEnterExitTranstionToTest.mS2, lr.getState());
426bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville
427bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        lr = smEnterExitTranstionToTest.getLogRec(3);
428bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(TEST_CMD_1, lr.getWhat());
429bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(smEnterExitTranstionToTest.mS2, lr.getState());
430bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(smEnterExitTranstionToTest.mS2, lr.getOriginalState());
431efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        assertEquals(smEnterExitTranstionToTest.mS3, lr.getDestState());
432bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville
433bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        lr = smEnterExitTranstionToTest.getLogRec(4);
434efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        assertEquals(TEST_CMD_1, lr.getWhat());
435bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(smEnterExitTranstionToTest.mS2, lr.getState());
436efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        assertEquals(smEnterExitTranstionToTest.mS2, lr.getOriginalState());
437efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        assertEquals(smEnterExitTranstionToTest.mS4, lr.getDestState());
438efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        assertEquals(EXIT, lr.getInfo());
439bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville
440bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        lr = smEnterExitTranstionToTest.getLogRec(5);
441efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        assertEquals(TEST_CMD_1, lr.getWhat());
442bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(ENTER, lr.getInfo());
443bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(smEnterExitTranstionToTest.mS3, lr.getState());
444efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        assertEquals(smEnterExitTranstionToTest.mS3, lr.getOriginalState());
445efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        assertEquals(smEnterExitTranstionToTest.mS4, lr.getDestState());
446e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville
447bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        lr = smEnterExitTranstionToTest.getLogRec(6);
448efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        assertEquals(TEST_CMD_1, lr.getWhat());
449bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(EXIT, lr.getInfo());
450bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(smEnterExitTranstionToTest.mS3, lr.getState());
451efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        assertEquals(smEnterExitTranstionToTest.mS3, lr.getOriginalState());
452efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        assertEquals(smEnterExitTranstionToTest.mS4, lr.getDestState());
453e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville
454bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        lr = smEnterExitTranstionToTest.getLogRec(7);
455efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        assertEquals(TEST_CMD_1, lr.getWhat());
456bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(ENTER, lr.getInfo());
457bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(smEnterExitTranstionToTest.mS4, lr.getState());
458efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        assertEquals(smEnterExitTranstionToTest.mS4, lr.getOriginalState());
459efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        assertEquals(smEnterExitTranstionToTest.mS4, lr.getDestState());
460e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville
461bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        lr = smEnterExitTranstionToTest.getLogRec(8);
462efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        assertEquals(TEST_CMD_1, lr.getWhat());
463bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(EXIT, lr.getInfo());
464bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(smEnterExitTranstionToTest.mS4, lr.getState());
465efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        assertEquals(smEnterExitTranstionToTest.mS4, lr.getOriginalState());
466e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville
467e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville        if (smEnterExitTranstionToTest.isDbg()) {
468efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville            tlog("testStateMachineEnterExitTransitionToTest X");
469e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville        }
470e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville    }
471e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville
472e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville    /**
473fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville     * Tests that ProcessedMessage works as a circular buffer.
474fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville     */
47564c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville    class StateMachine0 extends StateMachine {
476fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        StateMachine0(String name) {
477fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            super(name);
478fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            mThisSm = this;
479fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            setDbg(DBG);
480bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville            setLogRecSize(3);
481fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
482fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            // Setup state machine with 1 state
483fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            addState(mS1);
484fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
485fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            // Set the initial state
486fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            setInitialState(mS1);
487fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        }
488fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
48964c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville        class S1 extends State {
49064c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            @Override
49164c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            public boolean processMessage(Message message) {
492fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                if (message.what == TEST_CMD_6) {
493fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                    transitionToHaltingState();
494fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                }
495a4f3bec29c85ef9e0d07fdd551fe3c50f28b9adcWink Saville                return HANDLED;
496fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            }
497fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        }
498fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
499fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        @Override
500bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        protected void onHalting() {
501fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            synchronized (mThisSm) {
502fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                mThisSm.notifyAll();
503fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            }
504fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        }
505fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
506fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        private StateMachine0 mThisSm;
507fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        private S1 mS1 = new S1();
508fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    }
509fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
510fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    @SmallTest
511fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    public void testStateMachine0() throws Exception {
5121b8b98b3db5dcf0b01d1a632aafea076cc91f5a4Wink Saville        //if (WAIT_FOR_DEBUGGER) Debug.waitForDebugger();
513fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
514fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        StateMachine0 sm0 = new StateMachine0("sm0");
515fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        sm0.start();
516efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        if (sm0.isDbg()) tlog("testStateMachine0 E");
517fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
518fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        synchronized (sm0) {
519fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            // Send 6 messages
520fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            for (int i = 1; i <= 6; i++) {
521fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                sm0.sendMessage(sm0.obtainMessage(i));
522fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            }
523fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
524fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            try {
525fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                // wait for the messages to be handled
526fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                sm0.wait();
527fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            } catch (InterruptedException e) {
528efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                tloge("testStateMachine0: exception while waiting " + e.getMessage());
529fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            }
530fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        }
531fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
532bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(6, sm0.getLogRecCount());
533bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(3, sm0.getLogRecSize());
534fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
535efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        dumpLogRecs(sm0);
536efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville
537bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        LogRec lr;
538bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        lr = sm0.getLogRec(0);
539bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(TEST_CMD_4, lr.getWhat());
540bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(sm0.mS1, lr.getState());
541bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(sm0.mS1, lr.getOriginalState());
542fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
543bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        lr = sm0.getLogRec(1);
544bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(TEST_CMD_5, lr.getWhat());
545bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(sm0.mS1, lr.getState());
546bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(sm0.mS1, lr.getOriginalState());
547fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
548bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        lr = sm0.getLogRec(2);
549bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(TEST_CMD_6, lr.getWhat());
550bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(sm0.mS1, lr.getState());
551bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(sm0.mS1, lr.getOriginalState());
552fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
553efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        if (sm0.isDbg()) tlog("testStateMachine0 X");
554fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    }
555fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
556fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    /**
557fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville     * This tests enter/exit and transitions to the same state.
558fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville     * The state machine has one state, it receives two messages
559fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville     * in state mS1. With the first message it transitions to
560fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville     * itself which causes it to be exited and reentered.
561fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville     */
56264c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville    class StateMachine1 extends StateMachine {
563fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        StateMachine1(String name) {
564fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            super(name);
565fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            mThisSm = this;
566fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            setDbg(DBG);
567fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
568fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            // Setup state machine with 1 state
569fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            addState(mS1);
570fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
571fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            // Set the initial state
572fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            setInitialState(mS1);
573efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville            if (DBG) log("StateMachine1: ctor X");
574fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        }
575fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
57664c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville        class S1 extends State {
57764c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            @Override
57864c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            public void enter() {
579fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                mEnterCount++;
580fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            }
58164c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            @Override
58264c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            public void exit() {
58364c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville                mExitCount++;
58464c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            }
58564c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            @Override
58664c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            public boolean processMessage(Message message) {
587fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                if (message.what == TEST_CMD_1) {
588fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                    assertEquals(1, mEnterCount);
589fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                    assertEquals(0, mExitCount);
590fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                    transitionTo(mS1);
591fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                } else if (message.what == TEST_CMD_2) {
592fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                    assertEquals(2, mEnterCount);
593fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                    assertEquals(1, mExitCount);
594fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                    transitionToHaltingState();
595fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                }
596a4f3bec29c85ef9e0d07fdd551fe3c50f28b9adcWink Saville                return HANDLED;
597fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            }
598fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        }
599fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
600fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        @Override
601bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        protected void onHalting() {
602fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            synchronized (mThisSm) {
603fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                mThisSm.notifyAll();
604fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            }
605fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        }
606fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
607fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        private StateMachine1 mThisSm;
608fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        private S1 mS1 = new S1();
609fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
610fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        private int mEnterCount;
611fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        private int mExitCount;
612fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    }
613fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
614f76c56bcaa9df1d1afa711177f813dc63f399795Brett Chabot    @MediumTest
615fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    public void testStateMachine1() throws Exception {
616fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        StateMachine1 sm1 = new StateMachine1("sm1");
617fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        sm1.start();
618efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        if (sm1.isDbg()) tlog("testStateMachine1 E");
619fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
620fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        synchronized (sm1) {
621fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            // Send two messages
62291fbd56757751a7aca8ef2b4d936e587509e6eefWink Saville            sm1.sendMessage(TEST_CMD_1);
62391fbd56757751a7aca8ef2b4d936e587509e6eefWink Saville            sm1.sendMessage(TEST_CMD_2);
624fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
625fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            try {
626fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                // wait for the messages to be handled
627fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                sm1.wait();
628fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            } catch (InterruptedException e) {
629efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                tloge("testStateMachine1: exception while waiting " + e.getMessage());
630fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            }
631fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        }
632fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
633fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        assertEquals(2, sm1.mEnterCount);
634fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        assertEquals(2, sm1.mExitCount);
635fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
636bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(2, sm1.getLogRecSize());
637fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
638bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        LogRec lr;
639bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        lr = sm1.getLogRec(0);
640bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(TEST_CMD_1, lr.getWhat());
641bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(sm1.mS1, lr.getState());
642bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(sm1.mS1, lr.getOriginalState());
643fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
644bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        lr = sm1.getLogRec(1);
645bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(TEST_CMD_2, lr.getWhat());
646bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(sm1.mS1, lr.getState());
647bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(sm1.mS1, lr.getOriginalState());
648fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
649fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        assertEquals(2, sm1.mEnterCount);
650fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        assertEquals(2, sm1.mExitCount);
651fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
652efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        if (sm1.isDbg()) tlog("testStateMachine1 X");
653fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    }
654fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
655fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    /**
656fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville     * Test deferring messages and states with no parents. The state machine
657fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville     * has two states, it receives two messages in state mS1 deferring them
658fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville     * until what == TEST_CMD_2 and then transitions to state mS2. State
659fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville     * mS2 then receives both of the deferred messages first TEST_CMD_1 and
660fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville     * then TEST_CMD_2.
661fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville     */
66264c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville    class StateMachine2 extends StateMachine {
663fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        StateMachine2(String name) {
664fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            super(name);
665fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            mThisSm = this;
666fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            setDbg(DBG);
667fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
668fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            // Setup the hierarchy
669fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            addState(mS1);
670fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            addState(mS2);
671fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
672fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            // Set the initial state
673fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            setInitialState(mS1);
674efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville            if (DBG) log("StateMachine2: ctor X");
675fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        }
676fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
67764c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville        class S1 extends State {
67864c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            @Override
67964c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            public void enter() {
680fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                mDidEnter = true;
681fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            }
68264c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            @Override
68364c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            public void exit() {
68464c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville                mDidExit = true;
68564c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            }
68664c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            @Override
68764c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            public boolean processMessage(Message message) {
688fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                deferMessage(message);
689fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                if (message.what == TEST_CMD_2) {
690fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                    transitionTo(mS2);
691fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                }
692a4f3bec29c85ef9e0d07fdd551fe3c50f28b9adcWink Saville                return HANDLED;
693fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            }
694fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        }
695fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
69664c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville        class S2 extends State {
69764c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            @Override
69864c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            public boolean processMessage(Message message) {
699fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                if (message.what == TEST_CMD_2) {
700fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                    transitionToHaltingState();
701fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                }
702a4f3bec29c85ef9e0d07fdd551fe3c50f28b9adcWink Saville                return HANDLED;
703fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            }
704fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        }
705fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
706fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        @Override
707bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        protected void onHalting() {
708fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            synchronized (mThisSm) {
709fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                mThisSm.notifyAll();
710fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            }
711fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        }
712fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
713fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        private StateMachine2 mThisSm;
714fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        private S1 mS1 = new S1();
715fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        private S2 mS2 = new S2();
716fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
717fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        private boolean mDidEnter = false;
718fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        private boolean mDidExit = false;
719fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    }
720fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
721f76c56bcaa9df1d1afa711177f813dc63f399795Brett Chabot    @MediumTest
722fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    public void testStateMachine2() throws Exception {
723fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        StateMachine2 sm2 = new StateMachine2("sm2");
724fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        sm2.start();
725efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        if (sm2.isDbg()) tlog("testStateMachine2 E");
726fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
727fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        synchronized (sm2) {
728fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            // Send two messages
72991fbd56757751a7aca8ef2b4d936e587509e6eefWink Saville            sm2.sendMessage(TEST_CMD_1);
73091fbd56757751a7aca8ef2b4d936e587509e6eefWink Saville            sm2.sendMessage(TEST_CMD_2);
731fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
732fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            try {
733fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                // wait for the messages to be handled
734fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                sm2.wait();
735fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            } catch (InterruptedException e) {
736efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                tloge("testStateMachine2: exception while waiting " + e.getMessage());
737fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            }
738fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        }
739fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
740bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(4, sm2.getLogRecSize());
741fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
742bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        LogRec lr;
743bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        lr = sm2.getLogRec(0);
744bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(TEST_CMD_1, lr.getWhat());
745bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(sm2.mS1, lr.getState());
746fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
747bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        lr = sm2.getLogRec(1);
748bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(TEST_CMD_2, lr.getWhat());
749bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(sm2.mS1, lr.getState());
750fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
751bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        lr = sm2.getLogRec(2);
752bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(TEST_CMD_1, lr.getWhat());
753bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(sm2.mS2, lr.getState());
754fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
755bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        lr = sm2.getLogRec(3);
756bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(TEST_CMD_2, lr.getWhat());
757bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(sm2.mS2, lr.getState());
758fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
759fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        assertTrue(sm2.mDidEnter);
760fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        assertTrue(sm2.mDidExit);
761fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
762efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        if (sm2.isDbg()) tlog("testStateMachine2 X");
763fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    }
764fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
765fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    /**
766fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville     * Test that unhandled messages in a child are handled by the parent.
767fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville     * When TEST_CMD_2 is received.
768fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville     */
76964c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville    class StateMachine3 extends StateMachine {
770fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        StateMachine3(String name) {
771fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            super(name);
772fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            mThisSm = this;
773fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            setDbg(DBG);
774fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
775fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            // Setup the simplest hierarchy of two states
776fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            // mParentState and mChildState.
777fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            // (Use indentation to help visualize hierarchy)
778fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            addState(mParentState);
779fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                addState(mChildState, mParentState);
780fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
781fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            // Set the initial state will be the child
782fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            setInitialState(mChildState);
783efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville            if (DBG) log("StateMachine3: ctor X");
784fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        }
785fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
78664c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville        class ParentState extends State {
78764c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            @Override
78864c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            public boolean processMessage(Message message) {
789fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                if (message.what == TEST_CMD_2) {
790fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                    transitionToHaltingState();
791fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                }
792a4f3bec29c85ef9e0d07fdd551fe3c50f28b9adcWink Saville                return HANDLED;
793fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            }
794fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        }
795fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
79664c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville        class ChildState extends State {
79764c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            @Override
79864c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            public boolean processMessage(Message message) {
799a4f3bec29c85ef9e0d07fdd551fe3c50f28b9adcWink Saville                return NOT_HANDLED;
800fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            }
801fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        }
802fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
803fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        @Override
804bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        protected void onHalting() {
805fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            synchronized (mThisSm) {
806fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                mThisSm.notifyAll();
807fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            }
808fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        }
809fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
810fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        private StateMachine3 mThisSm;
811fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        private ParentState mParentState = new ParentState();
812fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        private ChildState mChildState = new ChildState();
813fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    }
814fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
815f76c56bcaa9df1d1afa711177f813dc63f399795Brett Chabot    @MediumTest
816fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    public void testStateMachine3() throws Exception {
817fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        StateMachine3 sm3 = new StateMachine3("sm3");
818fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        sm3.start();
819efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        if (sm3.isDbg()) tlog("testStateMachine3 E");
820fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
821fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        synchronized (sm3) {
822fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            // Send two messages
82391fbd56757751a7aca8ef2b4d936e587509e6eefWink Saville            sm3.sendMessage(TEST_CMD_1);
82491fbd56757751a7aca8ef2b4d936e587509e6eefWink Saville            sm3.sendMessage(TEST_CMD_2);
825fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
826fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            try {
827fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                // wait for the messages to be handled
828fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                sm3.wait();
829fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            } catch (InterruptedException e) {
830efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                tloge("testStateMachine3: exception while waiting " + e.getMessage());
831fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            }
832fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        }
833fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
834bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(2, sm3.getLogRecSize());
835fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
836bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        LogRec lr;
837bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        lr = sm3.getLogRec(0);
838bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(TEST_CMD_1, lr.getWhat());
839bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(sm3.mParentState, lr.getState());
840bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(sm3.mChildState, lr.getOriginalState());
841fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
842bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        lr = sm3.getLogRec(1);
843bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(TEST_CMD_2, lr.getWhat());
844bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(sm3.mParentState, lr.getState());
845bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(sm3.mChildState, lr.getOriginalState());
846fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
847efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        if (sm3.isDbg()) tlog("testStateMachine3 X");
848fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    }
849fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
850fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    /**
851fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville     * Test a hierarchy of 3 states a parent and two children
852fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville     * with transition from child 1 to child 2 and child 2
853fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville     * lets the parent handle the messages.
854fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville     */
85564c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville    class StateMachine4 extends StateMachine {
856fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        StateMachine4(String name) {
857fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            super(name);
858fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            mThisSm = this;
859fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            setDbg(DBG);
860fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
861fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            // Setup a hierarchy of three states
862fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            // mParentState, mChildState1 & mChildState2
863fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            // (Use indentation to help visualize hierarchy)
864fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            addState(mParentState);
865fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                addState(mChildState1, mParentState);
866fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                addState(mChildState2, mParentState);
867fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
868fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            // Set the initial state will be child 1
869fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            setInitialState(mChildState1);
870efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville            if (DBG) log("StateMachine4: ctor X");
871fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        }
872fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
87364c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville        class ParentState extends State {
87464c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            @Override
87564c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            public boolean processMessage(Message message) {
876fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                if (message.what == TEST_CMD_2) {
877fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                    transitionToHaltingState();
878fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                }
879a4f3bec29c85ef9e0d07fdd551fe3c50f28b9adcWink Saville                return HANDLED;
880fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            }
881fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        }
882fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
88364c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville        class ChildState1 extends State {
88464c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            @Override
88564c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            public boolean processMessage(Message message) {
886fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                transitionTo(mChildState2);
887a4f3bec29c85ef9e0d07fdd551fe3c50f28b9adcWink Saville                return HANDLED;
888fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            }
889fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        }
890fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
89164c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville        class ChildState2 extends State {
89264c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            @Override
89364c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            public boolean processMessage(Message message) {
894a4f3bec29c85ef9e0d07fdd551fe3c50f28b9adcWink Saville                return NOT_HANDLED;
895fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            }
896fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        }
897fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
898fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        @Override
899bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        protected void onHalting() {
900fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            synchronized (mThisSm) {
901fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                mThisSm.notifyAll();
902fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            }
903fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        }
904fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
905fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        private StateMachine4 mThisSm;
906fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        private ParentState mParentState = new ParentState();
907fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        private ChildState1 mChildState1 = new ChildState1();
908fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        private ChildState2 mChildState2 = new ChildState2();
909fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    }
910fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
911f76c56bcaa9df1d1afa711177f813dc63f399795Brett Chabot    @MediumTest
912fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    public void testStateMachine4() throws Exception {
913fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        StateMachine4 sm4 = new StateMachine4("sm4");
914fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        sm4.start();
915efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        if (sm4.isDbg()) tlog("testStateMachine4 E");
916fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
917fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        synchronized (sm4) {
918fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            // Send two messages
91991fbd56757751a7aca8ef2b4d936e587509e6eefWink Saville            sm4.sendMessage(TEST_CMD_1);
92091fbd56757751a7aca8ef2b4d936e587509e6eefWink Saville            sm4.sendMessage(TEST_CMD_2);
921fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
922fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            try {
923fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                // wait for the messages to be handled
924fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                sm4.wait();
925fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            } catch (InterruptedException e) {
926efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                tloge("testStateMachine4: exception while waiting " + e.getMessage());
927fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            }
928fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        }
929fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
930fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
931bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(2, sm4.getLogRecSize());
932fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
933bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        LogRec lr;
934bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        lr = sm4.getLogRec(0);
935bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(TEST_CMD_1, lr.getWhat());
936bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(sm4.mChildState1, lr.getState());
937bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(sm4.mChildState1, lr.getOriginalState());
938fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
939bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        lr = sm4.getLogRec(1);
940bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(TEST_CMD_2, lr.getWhat());
941bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(sm4.mParentState, lr.getState());
942bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(sm4.mChildState2, lr.getOriginalState());
943fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
944efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        if (sm4.isDbg()) tlog("testStateMachine4 X");
945fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    }
946fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
947fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    /**
948fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville     * Test transition from one child to another of a "complex"
949fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville     * hierarchy with two parents and multiple children.
950fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville     */
95164c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville    class StateMachine5 extends StateMachine {
952fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        StateMachine5(String name) {
953fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            super(name);
954fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            mThisSm = this;
955fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            setDbg(DBG);
956fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
957fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            // Setup a hierarchy with two parents and some children.
958fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            // (Use indentation to help visualize hierarchy)
959fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            addState(mParentState1);
960fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                addState(mChildState1, mParentState1);
961fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                addState(mChildState2, mParentState1);
962fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
963fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            addState(mParentState2);
964fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                addState(mChildState3, mParentState2);
965fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                addState(mChildState4, mParentState2);
966fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                    addState(mChildState5, mChildState4);
967fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
968fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            // Set the initial state will be the child
969fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            setInitialState(mChildState1);
970efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville            if (DBG) log("StateMachine5: ctor X");
971fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        }
972fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
97364c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville        class ParentState1 extends State {
97464c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            @Override
97564c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            public void enter() {
976fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                mParentState1EnterCount += 1;
977fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            }
97864c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            @Override
97964c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            public void exit() {
980fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                mParentState1ExitCount += 1;
981fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            }
98264c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            @Override
98364c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            public boolean processMessage(Message message) {
98464c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville                return HANDLED;
98564c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            }
986fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        }
987fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
98864c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville        class ChildState1 extends State {
98964c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            @Override
99064c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            public void enter() {
991fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                mChildState1EnterCount += 1;
992fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            }
99364c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            @Override
99464c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            public void exit() {
99564c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville                mChildState1ExitCount += 1;
99664c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            }
99764c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            @Override
99864c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            public boolean processMessage(Message message) {
999fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(1, mParentState1EnterCount);
1000fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(0, mParentState1ExitCount);
1001fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(1, mChildState1EnterCount);
1002fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(0, mChildState1ExitCount);
1003fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(0, mChildState2EnterCount);
1004fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(0, mChildState2ExitCount);
1005fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(0, mParentState2EnterCount);
1006fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(0, mParentState2ExitCount);
1007fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(0, mChildState3EnterCount);
1008fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(0, mChildState3ExitCount);
1009fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(0, mChildState4EnterCount);
1010fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(0, mChildState4ExitCount);
1011fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(0, mChildState5EnterCount);
1012fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(0, mChildState5ExitCount);
1013fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1014fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                transitionTo(mChildState2);
1015a4f3bec29c85ef9e0d07fdd551fe3c50f28b9adcWink Saville                return HANDLED;
1016fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            }
1017fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        }
1018fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
101964c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville        class ChildState2 extends State {
102064c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            @Override
102164c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            public void enter() {
1022fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                mChildState2EnterCount += 1;
1023fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            }
102464c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            @Override
102564c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            public void exit() {
102664c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville                mChildState2ExitCount += 1;
102764c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            }
102864c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            @Override
102964c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            public boolean processMessage(Message message) {
1030fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(1, mParentState1EnterCount);
1031fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(0, mParentState1ExitCount);
1032fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(1, mChildState1EnterCount);
1033fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(1, mChildState1ExitCount);
1034fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(1, mChildState2EnterCount);
1035fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(0, mChildState2ExitCount);
1036fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(0, mParentState2EnterCount);
1037fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(0, mParentState2ExitCount);
1038fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(0, mChildState3EnterCount);
1039fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(0, mChildState3ExitCount);
1040fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(0, mChildState4EnterCount);
1041fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(0, mChildState4ExitCount);
1042fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(0, mChildState5EnterCount);
1043fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(0, mChildState5ExitCount);
1044fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1045fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                transitionTo(mChildState5);
1046a4f3bec29c85ef9e0d07fdd551fe3c50f28b9adcWink Saville                return HANDLED;
1047fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            }
1048fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        }
1049fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
105064c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville        class ParentState2 extends State {
105164c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            @Override
105264c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            public void enter() {
1053fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                mParentState2EnterCount += 1;
1054fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            }
105564c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            @Override
105664c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            public void exit() {
105764c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville                mParentState2ExitCount += 1;
105864c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            }
105964c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            @Override
106064c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            public boolean processMessage(Message message) {
1061fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(1, mParentState1EnterCount);
1062fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(1, mParentState1ExitCount);
1063fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(1, mChildState1EnterCount);
1064fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(1, mChildState1ExitCount);
1065fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(1, mChildState2EnterCount);
1066fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(1, mChildState2ExitCount);
1067fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(2, mParentState2EnterCount);
1068fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(1, mParentState2ExitCount);
1069fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(1, mChildState3EnterCount);
1070fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(1, mChildState3ExitCount);
1071fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(2, mChildState4EnterCount);
1072fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(2, mChildState4ExitCount);
1073fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(1, mChildState5EnterCount);
1074fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(1, mChildState5ExitCount);
1075fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1076fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                transitionToHaltingState();
1077a4f3bec29c85ef9e0d07fdd551fe3c50f28b9adcWink Saville                return HANDLED;
1078fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            }
1079fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        }
1080fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
108164c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville        class ChildState3 extends State {
108264c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            @Override
108364c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            public void enter() {
1084fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                mChildState3EnterCount += 1;
1085fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            }
108664c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            @Override
108764c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            public void exit() {
108864c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville                mChildState3ExitCount += 1;
108964c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            }
109064c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            @Override
109164c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            public boolean processMessage(Message message) {
1092fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(1, mParentState1EnterCount);
1093fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(1, mParentState1ExitCount);
1094fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(1, mChildState1EnterCount);
1095fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(1, mChildState1ExitCount);
1096fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(1, mChildState2EnterCount);
1097fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(1, mChildState2ExitCount);
1098fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(1, mParentState2EnterCount);
1099fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(0, mParentState2ExitCount);
1100fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(1, mChildState3EnterCount);
1101fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(0, mChildState3ExitCount);
1102fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(1, mChildState4EnterCount);
1103fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(1, mChildState4ExitCount);
1104fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(1, mChildState5EnterCount);
1105fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(1, mChildState5ExitCount);
1106fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1107fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                transitionTo(mChildState4);
1108a4f3bec29c85ef9e0d07fdd551fe3c50f28b9adcWink Saville                return HANDLED;
1109fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            }
1110fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        }
1111fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
111264c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville        class ChildState4 extends State {
111364c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            @Override
111464c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            public void enter() {
1115fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                mChildState4EnterCount += 1;
1116fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            }
111764c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            @Override
111864c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            public void exit() {
111964c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville                mChildState4ExitCount += 1;
112064c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            }
112164c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            @Override
112264c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            public boolean processMessage(Message message) {
1123fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(1, mParentState1EnterCount);
1124fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(1, mParentState1ExitCount);
1125fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(1, mChildState1EnterCount);
1126fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(1, mChildState1ExitCount);
1127fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(1, mChildState2EnterCount);
1128fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(1, mChildState2ExitCount);
1129fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(1, mParentState2EnterCount);
1130fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(0, mParentState2ExitCount);
1131fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(1, mChildState3EnterCount);
1132fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(1, mChildState3ExitCount);
1133fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(2, mChildState4EnterCount);
1134fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(1, mChildState4ExitCount);
1135fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(1, mChildState5EnterCount);
1136fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(1, mChildState5ExitCount);
1137fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1138fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                transitionTo(mParentState2);
1139a4f3bec29c85ef9e0d07fdd551fe3c50f28b9adcWink Saville                return HANDLED;
1140fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            }
1141fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        }
1142fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
114364c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville        class ChildState5 extends State {
114464c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            @Override
114564c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            public void enter() {
1146fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                mChildState5EnterCount += 1;
1147fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            }
114864c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            @Override
114964c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            public void exit() {
115064c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville                mChildState5ExitCount += 1;
115164c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            }
115264c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            @Override
115364c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            public boolean processMessage(Message message) {
1154fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(1, mParentState1EnterCount);
1155fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(1, mParentState1ExitCount);
1156fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(1, mChildState1EnterCount);
1157fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(1, mChildState1ExitCount);
1158fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(1, mChildState2EnterCount);
1159fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(1, mChildState2ExitCount);
1160fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(1, mParentState2EnterCount);
1161fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(0, mParentState2ExitCount);
1162fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(0, mChildState3EnterCount);
1163fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(0, mChildState3ExitCount);
1164fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(1, mChildState4EnterCount);
1165fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(0, mChildState4ExitCount);
1166fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(1, mChildState5EnterCount);
1167fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(0, mChildState5ExitCount);
1168fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1169fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                transitionTo(mChildState3);
1170a4f3bec29c85ef9e0d07fdd551fe3c50f28b9adcWink Saville                return HANDLED;
1171fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            }
1172fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        }
1173fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1174fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        @Override
1175bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        protected void onHalting() {
1176fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            synchronized (mThisSm) {
1177fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                mThisSm.notifyAll();
1178fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            }
1179fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        }
1180fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1181fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        private StateMachine5 mThisSm;
1182fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        private ParentState1 mParentState1 = new ParentState1();
1183fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        private ChildState1 mChildState1 = new ChildState1();
1184fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        private ChildState2 mChildState2 = new ChildState2();
1185fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        private ParentState2 mParentState2 = new ParentState2();
1186fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        private ChildState3 mChildState3 = new ChildState3();
1187fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        private ChildState4 mChildState4 = new ChildState4();
1188fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        private ChildState5 mChildState5 = new ChildState5();
1189fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1190fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        private int mParentState1EnterCount = 0;
1191fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        private int mParentState1ExitCount = 0;
1192fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        private int mChildState1EnterCount = 0;
1193fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        private int mChildState1ExitCount = 0;
1194fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        private int mChildState2EnterCount = 0;
1195fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        private int mChildState2ExitCount = 0;
1196fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        private int mParentState2EnterCount = 0;
1197fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        private int mParentState2ExitCount = 0;
1198fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        private int mChildState3EnterCount = 0;
1199fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        private int mChildState3ExitCount = 0;
1200fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        private int mChildState4EnterCount = 0;
1201fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        private int mChildState4ExitCount = 0;
1202fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        private int mChildState5EnterCount = 0;
1203fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        private int mChildState5ExitCount = 0;
1204fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    }
1205fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1206f76c56bcaa9df1d1afa711177f813dc63f399795Brett Chabot    @MediumTest
1207fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    public void testStateMachine5() throws Exception {
1208fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        StateMachine5 sm5 = new StateMachine5("sm5");
1209fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        sm5.start();
1210efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        if (sm5.isDbg()) tlog("testStateMachine5 E");
1211fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1212fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        synchronized (sm5) {
1213fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            // Send 6 messages
121491fbd56757751a7aca8ef2b4d936e587509e6eefWink Saville            sm5.sendMessage(TEST_CMD_1);
121591fbd56757751a7aca8ef2b4d936e587509e6eefWink Saville            sm5.sendMessage(TEST_CMD_2);
121691fbd56757751a7aca8ef2b4d936e587509e6eefWink Saville            sm5.sendMessage(TEST_CMD_3);
121791fbd56757751a7aca8ef2b4d936e587509e6eefWink Saville            sm5.sendMessage(TEST_CMD_4);
121891fbd56757751a7aca8ef2b4d936e587509e6eefWink Saville            sm5.sendMessage(TEST_CMD_5);
121991fbd56757751a7aca8ef2b4d936e587509e6eefWink Saville            sm5.sendMessage(TEST_CMD_6);
1220fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1221fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            try {
1222fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                // wait for the messages to be handled
1223fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                sm5.wait();
1224fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            } catch (InterruptedException e) {
1225efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                tloge("testStateMachine5: exception while waiting " + e.getMessage());
1226fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            }
1227fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        }
1228fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1229fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1230bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(6, sm5.getLogRecSize());
1231fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1232fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        assertEquals(1, sm5.mParentState1EnterCount);
1233fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        assertEquals(1, sm5.mParentState1ExitCount);
1234fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        assertEquals(1, sm5.mChildState1EnterCount);
1235fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        assertEquals(1, sm5.mChildState1ExitCount);
1236fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        assertEquals(1, sm5.mChildState2EnterCount);
1237fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        assertEquals(1, sm5.mChildState2ExitCount);
1238fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        assertEquals(2, sm5.mParentState2EnterCount);
1239fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        assertEquals(2, sm5.mParentState2ExitCount);
1240fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        assertEquals(1, sm5.mChildState3EnterCount);
1241fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        assertEquals(1, sm5.mChildState3ExitCount);
1242fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        assertEquals(2, sm5.mChildState4EnterCount);
1243fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        assertEquals(2, sm5.mChildState4ExitCount);
1244fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        assertEquals(1, sm5.mChildState5EnterCount);
1245fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        assertEquals(1, sm5.mChildState5ExitCount);
1246fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1247bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        LogRec lr;
1248bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        lr = sm5.getLogRec(0);
1249bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(TEST_CMD_1, lr.getWhat());
1250bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(sm5.mChildState1, lr.getState());
1251bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(sm5.mChildState1, lr.getOriginalState());
1252bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville
1253bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        lr = sm5.getLogRec(1);
1254bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(TEST_CMD_2, lr.getWhat());
1255bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(sm5.mChildState2, lr.getState());
1256bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(sm5.mChildState2, lr.getOriginalState());
1257bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville
1258bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        lr = sm5.getLogRec(2);
1259bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(TEST_CMD_3, lr.getWhat());
1260bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(sm5.mChildState5, lr.getState());
1261bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(sm5.mChildState5, lr.getOriginalState());
1262bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville
1263bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        lr = sm5.getLogRec(3);
1264bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(TEST_CMD_4, lr.getWhat());
1265bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(sm5.mChildState3, lr.getState());
1266bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(sm5.mChildState3, lr.getOriginalState());
1267bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville
1268bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        lr = sm5.getLogRec(4);
1269bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(TEST_CMD_5, lr.getWhat());
1270bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(sm5.mChildState4, lr.getState());
1271bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(sm5.mChildState4, lr.getOriginalState());
1272bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville
1273bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        lr = sm5.getLogRec(5);
1274bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(TEST_CMD_6, lr.getWhat());
1275bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(sm5.mParentState2, lr.getState());
1276bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(sm5.mParentState2, lr.getOriginalState());
1277fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1278efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        if (sm5.isDbg()) tlog("testStateMachine5 X");
1279fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    }
1280fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1281fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    /**
1282fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville     * Test that the initial state enter is invoked immediately
1283fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville     * after construction and before any other messages arrive and that
1284fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville     * sendMessageDelayed works.
1285fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville     */
128664c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville    class StateMachine6 extends StateMachine {
1287fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        StateMachine6(String name) {
1288fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            super(name);
1289fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            mThisSm = this;
1290fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            setDbg(DBG);
1291fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1292fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            // Setup state machine with 1 state
1293fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            addState(mS1);
1294fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1295fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            // Set the initial state
1296fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            setInitialState(mS1);
1297efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville            if (DBG) log("StateMachine6: ctor X");
1298fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        }
1299fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
130064c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville        class S1 extends State {
130164c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            @Override
130264c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            public void enter() {
130391fbd56757751a7aca8ef2b4d936e587509e6eefWink Saville                sendMessage(TEST_CMD_1);
1304fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            }
130564c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            @Override
130664c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            public boolean processMessage(Message message) {
1307fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                if (message.what == TEST_CMD_1) {
1308fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                    mArrivalTimeMsg1 = SystemClock.elapsedRealtime();
1309fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                } else if (message.what == TEST_CMD_2) {
1310fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                    mArrivalTimeMsg2 = SystemClock.elapsedRealtime();
1311fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                    transitionToHaltingState();
1312fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                }
1313a4f3bec29c85ef9e0d07fdd551fe3c50f28b9adcWink Saville                return HANDLED;
1314fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            }
1315fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        }
1316fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1317fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        @Override
1318bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        protected void onHalting() {
1319fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            synchronized (mThisSm) {
1320fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                mThisSm.notifyAll();
1321fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            }
1322fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        }
1323fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1324fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        private StateMachine6 mThisSm;
1325fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        private S1 mS1 = new S1();
1326fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1327fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        private long mArrivalTimeMsg1;
1328fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        private long mArrivalTimeMsg2;
1329fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    }
1330fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1331f76c56bcaa9df1d1afa711177f813dc63f399795Brett Chabot    @MediumTest
1332fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    public void testStateMachine6() throws Exception {
1333fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        final int DELAY_TIME = 250;
1334fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        final int DELAY_FUDGE = 20;
1335fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1336fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        StateMachine6 sm6 = new StateMachine6("sm6");
1337fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        sm6.start();
1338efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        if (sm6.isDbg()) tlog("testStateMachine6 E");
1339fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1340fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        synchronized (sm6) {
1341fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            // Send a message
134291fbd56757751a7aca8ef2b4d936e587509e6eefWink Saville            sm6.sendMessageDelayed(TEST_CMD_2, DELAY_TIME);
1343fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1344fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            try {
1345fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                // wait for the messages to be handled
1346fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                sm6.wait();
1347fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            } catch (InterruptedException e) {
1348efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                tloge("testStateMachine6: exception while waiting " + e.getMessage());
1349fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            }
1350fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        }
1351fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1352fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        /**
1353fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville         * TEST_CMD_1 was sent in enter and must always have been processed
1354fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville         * immediately after construction and hence the arrival time difference
1355fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville         * should always >= to the DELAY_TIME
1356fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville         */
1357fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        long arrivalTimeDiff = sm6.mArrivalTimeMsg2 - sm6.mArrivalTimeMsg1;
1358fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        long expectedDelay = DELAY_TIME - DELAY_FUDGE;
1359efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        if (sm6.isDbg()) tlog("testStateMachine6: expect " + arrivalTimeDiff
1360fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                                    + " >= " + expectedDelay);
1361fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        assertTrue(arrivalTimeDiff >= expectedDelay);
1362fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1363efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        if (sm6.isDbg()) tlog("testStateMachine6 X");
1364fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    }
1365fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1366fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    /**
1367fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville     * Test that enter is invoked immediately after exit. This validates
1368fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville     * that enter can be used to send a watch dog message for its state.
1369fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville     */
137064c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville    class StateMachine7 extends StateMachine {
1371fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        private final int SM7_DELAY_TIME = 250;
1372fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1373fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        StateMachine7(String name) {
1374fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            super(name);
1375fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            mThisSm = this;
1376fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            setDbg(DBG);
1377fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1378fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            // Setup state machine with 1 state
1379fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            addState(mS1);
1380fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            addState(mS2);
1381fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1382fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            // Set the initial state
1383fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            setInitialState(mS1);
1384efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville            if (DBG) log("StateMachine7: ctor X");
1385fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        }
1386fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
138764c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville        class S1 extends State {
138864c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            @Override
138964c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            public void exit() {
139064c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville                sendMessage(TEST_CMD_2);
139164c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            }
139264c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            @Override
139364c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            public boolean processMessage(Message message) {
1394fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                transitionTo(mS2);
1395a4f3bec29c85ef9e0d07fdd551fe3c50f28b9adcWink Saville                return HANDLED;
1396fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            }
1397fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        }
1398fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
139964c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville        class S2 extends State {
140064c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            @Override
140164c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            public void enter() {
1402fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                // Send a delayed message as a watch dog
140391fbd56757751a7aca8ef2b4d936e587509e6eefWink Saville                sendMessageDelayed(TEST_CMD_3, SM7_DELAY_TIME);
1404fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            }
140564c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            @Override
140664c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            public boolean processMessage(Message message) {
1407fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                if (message.what == TEST_CMD_2) {
1408fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                    mMsgCount += 1;
1409fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                    mArrivalTimeMsg2 = SystemClock.elapsedRealtime();
1410fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                } else if (message.what == TEST_CMD_3) {
1411fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                    mMsgCount += 1;
1412fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                    mArrivalTimeMsg3 = SystemClock.elapsedRealtime();
1413fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                }
1414fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1415fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                if (mMsgCount == 2) {
1416fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                    transitionToHaltingState();
1417fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                }
1418a4f3bec29c85ef9e0d07fdd551fe3c50f28b9adcWink Saville                return HANDLED;
1419fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            }
1420fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        }
1421fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1422fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        @Override
1423bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        protected void onHalting() {
1424fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            synchronized (mThisSm) {
1425fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                mThisSm.notifyAll();
1426fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            }
1427fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        }
1428fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1429fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        private StateMachine7 mThisSm;
1430fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        private S1 mS1 = new S1();
1431fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        private S2 mS2 = new S2();
1432fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1433fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        private int mMsgCount = 0;
1434fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        private long mArrivalTimeMsg2;
1435fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        private long mArrivalTimeMsg3;
1436fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    }
1437fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1438f76c56bcaa9df1d1afa711177f813dc63f399795Brett Chabot    @MediumTest
1439fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    public void testStateMachine7() throws Exception {
1440fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        final int SM7_DELAY_FUDGE = 20;
1441fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1442fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        StateMachine7 sm7 = new StateMachine7("sm7");
1443fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        sm7.start();
1444efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        if (sm7.isDbg()) tlog("testStateMachine7 E");
1445fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1446fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        synchronized (sm7) {
1447fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            // Send a message
144891fbd56757751a7aca8ef2b4d936e587509e6eefWink Saville            sm7.sendMessage(TEST_CMD_1);
1449fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1450fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            try {
1451fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                // wait for the messages to be handled
1452fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                sm7.wait();
1453fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            } catch (InterruptedException e) {
1454efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                tloge("testStateMachine7: exception while waiting " + e.getMessage());
1455fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            }
1456fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        }
1457fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1458fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        /**
1459fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville         * TEST_CMD_3 was sent in S2.enter with a delay and must always have been
1460fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville         * processed immediately after S1.exit. Since S1.exit sent TEST_CMD_2
1461fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville         * without a delay the arrival time difference should always >= to SM7_DELAY_TIME.
1462fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville         */
1463fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        long arrivalTimeDiff = sm7.mArrivalTimeMsg3 - sm7.mArrivalTimeMsg2;
1464fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        long expectedDelay = sm7.SM7_DELAY_TIME - SM7_DELAY_FUDGE;
1465efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        if (sm7.isDbg()) tlog("testStateMachine7: expect " + arrivalTimeDiff
1466fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                                    + " >= " + expectedDelay);
1467fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        assertTrue(arrivalTimeDiff >= expectedDelay);
1468fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1469efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        if (sm7.isDbg()) tlog("testStateMachine7 X");
1470fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    }
1471fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1472fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    /**
1473fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville     * Test unhandledMessage.
1474fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville     */
147564c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville    class StateMachineUnhandledMessage extends StateMachine {
1476fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        StateMachineUnhandledMessage(String name) {
1477fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            super(name);
1478fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            mThisSm = this;
1479fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            setDbg(DBG);
1480fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1481fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            // Setup state machine with 1 state
1482fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            addState(mS1);
1483fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1484fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            // Set the initial state
1485fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            setInitialState(mS1);
1486fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        }
148764c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville        @Override
148864c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville        public void unhandledMessage(Message message) {
1489fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            mUnhandledMessageCount += 1;
1490fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        }
1491fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
149264c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville        class S1 extends State {
149364c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            @Override
149464c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            public boolean processMessage(Message message) {
1495fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                if (message.what == TEST_CMD_2) {
1496fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                    transitionToHaltingState();
1497fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                }
1498a4f3bec29c85ef9e0d07fdd551fe3c50f28b9adcWink Saville                return NOT_HANDLED;
1499fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            }
1500fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        }
1501fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1502fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        @Override
1503bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        protected void onHalting() {
1504fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            synchronized (mThisSm) {
1505fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                mThisSm.notifyAll();
1506fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            }
1507fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        }
1508fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1509fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        private StateMachineUnhandledMessage mThisSm;
1510fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        private int mUnhandledMessageCount;
1511fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        private S1 mS1 = new S1();
1512fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    }
1513fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1514fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    @SmallTest
1515fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    public void testStateMachineUnhandledMessage() throws Exception {
1516fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1517efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        StateMachineUnhandledMessage sm = new StateMachineUnhandledMessage("smUnhandledMessage");
1518fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        sm.start();
1519efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        if (sm.isDbg()) tlog("testStateMachineUnhandledMessage E");
1520fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1521fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        synchronized (sm) {
1522fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            // Send 2 messages
1523fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            for (int i = 1; i <= 2; i++) {
152491fbd56757751a7aca8ef2b4d936e587509e6eefWink Saville                sm.sendMessage(i);
1525fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            }
1526fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1527fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            try {
1528fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                // wait for the messages to be handled
1529fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                sm.wait();
1530fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            } catch (InterruptedException e) {
1531efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                tloge("testStateMachineUnhandledMessage: exception while waiting "
1532fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                        + e.getMessage());
1533fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            }
1534fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        }
1535fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1536efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        assertEquals(2, sm.getLogRecSize());
1537fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        assertEquals(2, sm.mUnhandledMessageCount);
1538fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1539efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        if (sm.isDbg()) tlog("testStateMachineUnhandledMessage X");
1540fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    }
1541fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1542fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    /**
1543fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville     * Test state machines sharing the same thread/looper. Multiple instances
1544fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville     * of the same state machine will be created. They will all share the
1545fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville     * same thread and thus each can update <code>sharedCounter</code> which
1546fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville     * will be used to notify testStateMachineSharedThread that the test is
1547fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville     * complete.
1548fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville     */
154964c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville    class StateMachineSharedThread extends StateMachine {
1550f0f566ec4607376583e59964a6a8a6dcb0265c20Wink Saville        StateMachineSharedThread(String name, Looper looper, int maxCount) {
1551f0f566ec4607376583e59964a6a8a6dcb0265c20Wink Saville            super(name, looper);
1552fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            mMaxCount = maxCount;
1553fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            setDbg(DBG);
1554fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1555fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            // Setup state machine with 1 state
1556fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            addState(mS1);
1557fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1558fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            // Set the initial state
1559fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            setInitialState(mS1);
1560fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        }
1561fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
156264c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville        class S1 extends State {
156364c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            @Override
156464c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            public boolean processMessage(Message message) {
1565fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                if (message.what == TEST_CMD_4) {
1566fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                    transitionToHaltingState();
1567fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                }
1568a4f3bec29c85ef9e0d07fdd551fe3c50f28b9adcWink Saville                return HANDLED;
1569fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            }
1570fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        }
1571fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1572fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        @Override
1573bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        protected void onHalting() {
1574fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            // Update the shared counter, which is OK since all state
1575fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            // machines are using the same thread.
1576fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            sharedCounter += 1;
1577fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            if (sharedCounter == mMaxCount) {
1578fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                synchronized (waitObject) {
1579fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                    waitObject.notifyAll();
1580fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                }
1581fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            }
1582fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        }
1583fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1584fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        private int mMaxCount;
1585fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        private S1 mS1 = new S1();
1586fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    }
1587fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    private static int sharedCounter = 0;
1588fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    private static Object waitObject = new Object();
1589fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1590f76c56bcaa9df1d1afa711177f813dc63f399795Brett Chabot    @MediumTest
1591fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    public void testStateMachineSharedThread() throws Exception {
1592efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        if (DBG) tlog("testStateMachineSharedThread E");
1593fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1594fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        // Create and start the handler thread
1595fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        HandlerThread smThread = new HandlerThread("testStateMachineSharedThread");
1596fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        smThread.start();
1597fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1598fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        // Create the state machines
1599fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        StateMachineSharedThread sms[] = new StateMachineSharedThread[10];
1600fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        for (int i = 0; i < sms.length; i++) {
1601efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville            sms[i] = new StateMachineSharedThread("smSharedThread",
1602efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                        smThread.getLooper(), sms.length);
1603fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            sms[i].start();
1604fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        }
1605fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1606fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        synchronized (waitObject) {
1607fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            // Send messages to each of the state machines
1608fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            for (StateMachineSharedThread sm : sms) {
1609fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                for (int i = 1; i <= 4; i++) {
161091fbd56757751a7aca8ef2b4d936e587509e6eefWink Saville                    sm.sendMessage(i);
1611fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                }
1612fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            }
1613fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1614fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            // Wait for the last state machine to notify its done
1615fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            try {
1616fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                waitObject.wait();
1617fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            } catch (InterruptedException e) {
1618efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                tloge("testStateMachineSharedThread: exception while waiting "
1619fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                        + e.getMessage());
1620fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            }
1621fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        }
1622fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1623fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        for (StateMachineSharedThread sm : sms) {
1624efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville            assertEquals(4, sm.getLogRecCount());
1625efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville            for (int i = 0; i < sm.getLogRecSize(); i++) {
1626bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville                LogRec lr = sm.getLogRec(i);
1627bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville                assertEquals(i+1, lr.getWhat());
1628bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville                assertEquals(sm.mS1, lr.getState());
1629bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville                assertEquals(sm.mS1, lr.getOriginalState());
1630fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            }
1631fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        }
1632fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1633efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        if (DBG) tlog("testStateMachineSharedThread X");
1634efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville    }
1635efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville
1636efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville    static class Hsm1 extends StateMachine {
1637efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        private static final String HSM1_TAG = "hsm1";
1638efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville
1639efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        public static final int CMD_1 = 1;
1640efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        public static final int CMD_2 = 2;
1641efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        public static final int CMD_3 = 3;
1642efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        public static final int CMD_4 = 4;
1643efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        public static final int CMD_5 = 5;
1644efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville
1645efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        public static Hsm1 makeHsm1() {
1646efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville            Log.d(HSM1_TAG, "makeHsm1 E");
1647efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville            Hsm1 sm = new Hsm1(HSM1_TAG);
1648efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville            sm.start();
1649efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville            Log.d(HSM1_TAG, "makeHsm1 X");
1650efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville            return sm;
1651efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        }
1652efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville
1653efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        Hsm1(String name) {
1654efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville            super(name);
1655efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville            log("ctor E");
1656efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville
1657efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville            // Add states, use indentation to show hierarchy
1658efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville            addState(mP1);
1659efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                addState(mS1, mP1);
1660efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                addState(mS2, mP1);
1661efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville            addState(mP2);
1662efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville
1663efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville            // Set the initial state
1664efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville            setInitialState(mS1);
1665efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville            log("ctor X");
1666efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        }
1667efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville
1668efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        class P1 extends State {
1669efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville            @Override
1670efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville            public void enter() {
1671efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                log("P1.enter");
1672efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville            }
1673efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville            @Override
1674efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville            public void exit() {
1675efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                log("P1.exit");
1676efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville            }
1677efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville            @Override
1678efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville            public boolean processMessage(Message message) {
1679efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                boolean retVal;
1680efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                log("P1.processMessage what=" + message.what);
1681efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                switch(message.what) {
1682efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                case CMD_2:
1683efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                    // CMD_2 will arrive in mS2 before CMD_3
1684efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                    sendMessage(CMD_3);
1685efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                    deferMessage(message);
1686efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                    transitionTo(mS2);
1687efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                    retVal = true;
1688efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                    break;
1689efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                default:
1690efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                    // Any message we don't understand in this state invokes unhandledMessage
1691efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                    retVal = false;
1692efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                    break;
1693efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                }
1694efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                return retVal;
1695efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville            }
1696efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        }
1697efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville
1698efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        class S1 extends State {
1699efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville            @Override
1700efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville            public void enter() {
1701efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                log("S1.enter");
1702efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville            }
1703efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville            @Override
1704efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville            public void exit() {
1705efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                log("S1.exit");
1706efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville            }
1707efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville            @Override
1708efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville            public boolean processMessage(Message message) {
1709efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                log("S1.processMessage what=" + message.what);
1710efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                if (message.what == CMD_1) {
1711efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                    // Transition to ourself to show that enter/exit is called
1712efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                    transitionTo(mS1);
1713efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                    return HANDLED;
1714efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                } else {
1715efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                    // Let parent process all other messages
1716efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                    return NOT_HANDLED;
1717efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                }
1718efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville            }
1719efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        }
1720efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville
1721efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        class S2 extends State {
1722efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville            @Override
1723efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville            public void enter() {
1724efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                log("S2.enter");
1725efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville            }
1726efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville            @Override
1727efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville            public void exit() {
1728efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                log("S2.exit");
1729efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville            }
1730efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville            @Override
1731efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville            public boolean processMessage(Message message) {
1732efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                boolean retVal;
1733efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                log("S2.processMessage what=" + message.what);
1734efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                switch(message.what) {
1735efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                case(CMD_2):
1736efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                    sendMessage(CMD_4);
1737efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                    retVal = true;
1738efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                    break;
1739efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                case(CMD_3):
1740efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                    deferMessage(message);
1741efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                    transitionTo(mP2);
1742efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                    retVal = true;
1743efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                    break;
1744efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                default:
1745efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                    retVal = false;
1746efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                    break;
1747efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                }
1748efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                return retVal;
1749efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville            }
1750efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        }
1751efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville
1752efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        class P2 extends State {
1753efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville            @Override
1754efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville            public void enter() {
1755efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                log("P2.enter");
1756efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                sendMessage(CMD_5);
1757efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville            }
1758efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville            @Override
1759efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville            public void exit() {
1760efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                log("P2.exit");
1761efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville            }
1762efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville            @Override
1763efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville            public boolean processMessage(Message message) {
1764efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                log("P2.processMessage what=" + message.what);
1765efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                switch(message.what) {
1766efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                case(CMD_3):
1767efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                    break;
1768efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                case(CMD_4):
1769efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                    break;
1770efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                case(CMD_5):
1771efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                    transitionToHaltingState();
1772efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                    break;
1773efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                }
1774efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                return HANDLED;
1775efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville            }
1776efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        }
1777efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville
1778efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        @Override
1779efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        protected void onHalting() {
1780efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville            log("halting");
1781efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville            synchronized (this) {
1782efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                this.notifyAll();
1783efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville            }
1784efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        }
1785efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville
1786efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        P1 mP1 = new P1();
1787efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        S1 mS1 = new S1();
1788efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        S2 mS2 = new S2();
1789efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        P2 mP2 = new P2();
1790fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    }
1791fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1792f76c56bcaa9df1d1afa711177f813dc63f399795Brett Chabot    @MediumTest
1793fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    public void testHsm1() throws Exception {
1794efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        if (DBG) tlog("testHsm1 E");
1795fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1796fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        Hsm1 sm = Hsm1.makeHsm1();
1797fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1798fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        // Send messages
179991fbd56757751a7aca8ef2b4d936e587509e6eefWink Saville        sm.sendMessage(Hsm1.CMD_1);
180091fbd56757751a7aca8ef2b4d936e587509e6eefWink Saville        sm.sendMessage(Hsm1.CMD_2);
1801fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1802fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        synchronized (sm) {
1803fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            // Wait for the last state machine to notify its done
1804fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            try {
1805fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                sm.wait();
1806fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            } catch (InterruptedException e) {
1807efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                tloge("testHsm1: exception while waiting " + e.getMessage());
1808fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            }
1809fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        }
1810fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1811efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        dumpLogRecs(sm);
1812efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville
1813bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(7, sm.getLogRecCount());
1814efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville
1815bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        LogRec lr = sm.getLogRec(0);
1816bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(Hsm1.CMD_1, lr.getWhat());
1817bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(sm.mS1, lr.getState());
1818bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(sm.mS1, lr.getOriginalState());
1819fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1820bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        lr = sm.getLogRec(1);
1821bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(Hsm1.CMD_2, lr.getWhat());
1822bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(sm.mP1, lr.getState());
1823bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(sm.mS1, lr.getOriginalState());
1824fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1825bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        lr = sm.getLogRec(2);
1826bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(Hsm1.CMD_2, lr.getWhat());
1827bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(sm.mS2, lr.getState());
1828bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(sm.mS2, lr.getOriginalState());
1829fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1830bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        lr = sm.getLogRec(3);
1831bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(Hsm1.CMD_3, lr.getWhat());
1832bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(sm.mS2, lr.getState());
1833bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(sm.mS2, lr.getOriginalState());
1834fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1835bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        lr = sm.getLogRec(4);
1836bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(Hsm1.CMD_3, lr.getWhat());
1837bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(sm.mP2, lr.getState());
1838bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(sm.mP2, lr.getOriginalState());
1839fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1840bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        lr = sm.getLogRec(5);
1841bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(Hsm1.CMD_4, lr.getWhat());
1842bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(sm.mP2, lr.getState());
1843bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(sm.mP2, lr.getOriginalState());
1844fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1845bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        lr = sm.getLogRec(6);
1846bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(Hsm1.CMD_5, lr.getWhat());
1847bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(sm.mP2, lr.getState());
1848bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(sm.mP2, lr.getOriginalState());
1849fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1850efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        if (DBG) tlog("testStateMachineSharedThread X");
1851fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    }
1852fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1853efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville    private void tlog(String s) {
1854efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        Log.d(TAG, s);
1855fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    }
1856fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1857efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville    private void tloge(String s) {
1858efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        Log.e(TAG, s);
1859fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    }
1860fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville}
1861