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
28f90177629a5b69ca3a80466c0ab55abfeb6d26b2Abodunrinwa Tokiimport android.test.suitebuilder.annotation.Suppress;
2964c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Savilleimport com.android.internal.util.State;
3064c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Savilleimport com.android.internal.util.StateMachine;
31bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Savilleimport com.android.internal.util.StateMachine.LogRec;
32fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
33f76c56bcaa9df1d1afa711177f813dc63f399795Brett Chabotimport android.test.suitebuilder.annotation.MediumTest;
34fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Savilleimport android.test.suitebuilder.annotation.SmallTest;
35fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Savilleimport android.util.Log;
36fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
37f76c56bcaa9df1d1afa711177f813dc63f399795Brett Chabotimport junit.framework.TestCase;
38fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
39fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville/**
4064c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville * Test for StateMachine.
41fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville */
42f90177629a5b69ca3a80466c0ab55abfeb6d26b2Abodunrinwa Toki@Suppress // Failing
4364c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Savillepublic class StateMachineTest extends TestCase {
44bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville    private static final String ENTER = "enter";
45bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville    private static final String EXIT = "exit";
46bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville    private static final String ON_QUITTING = "ON_QUITTING";
47bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville
48fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    private static final int TEST_CMD_1 = 1;
49fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    private static final int TEST_CMD_2 = 2;
50fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    private static final int TEST_CMD_3 = 3;
51fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    private static final int TEST_CMD_4 = 4;
52fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    private static final int TEST_CMD_5 = 5;
53fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    private static final int TEST_CMD_6 = 6;
54fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
55fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    private static final boolean DBG = true;
566b888d98f7fffe5b87b3d5421d2f9a119899c7ddWink Saville    private static final boolean WAIT_FOR_DEBUGGER = false;
5764c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville    private static final String TAG = "StateMachineTest";
58fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
59bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville    private void sleep(int millis) {
60bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        try {
61bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville            Thread.sleep(millis);
62bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        } catch(InterruptedException e) {
63bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        }
64bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville    }
65bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville
66efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville    private void dumpLogRecs(StateMachine sm) {
67efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        int size = sm.getLogRecSize();
68efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        tlog("size=" + size + " count=" + sm.getLogRecCount());
69efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        for (int i = 0; i < size; i++) {
70efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville            LogRec lr = sm.getLogRec(i);
71efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville            tlog(lr.toString());
72efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        }
73efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville    }
74efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville
75efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville    private void dumpLogRecs(Collection<LogRec> clr) {
76efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        int size = clr.size();
77efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        tlog("size=" + size);
78efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        for (LogRec lr : clr) {
79efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville            tlog(lr.toString());
80efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        }
81efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville    }
82efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville
83fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    /**
84bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville     * Tests {@link StateMachine#quit()}.
851b8b98b3db5dcf0b01d1a632aafea076cc91f5a4Wink Saville     */
8664c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville    class StateMachineQuitTest extends StateMachine {
87efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        Collection<LogRec> mLogRecs;
881b8b98b3db5dcf0b01d1a632aafea076cc91f5a4Wink Saville
891b8b98b3db5dcf0b01d1a632aafea076cc91f5a4Wink Saville        StateMachineQuitTest(String name) {
901b8b98b3db5dcf0b01d1a632aafea076cc91f5a4Wink Saville            super(name);
911b8b98b3db5dcf0b01d1a632aafea076cc91f5a4Wink Saville            mThisSm = this;
921b8b98b3db5dcf0b01d1a632aafea076cc91f5a4Wink Saville            setDbg(DBG);
931b8b98b3db5dcf0b01d1a632aafea076cc91f5a4Wink Saville
941b8b98b3db5dcf0b01d1a632aafea076cc91f5a4Wink Saville            // Setup state machine with 1 state
951b8b98b3db5dcf0b01d1a632aafea076cc91f5a4Wink Saville            addState(mS1);
961b8b98b3db5dcf0b01d1a632aafea076cc91f5a4Wink Saville
971b8b98b3db5dcf0b01d1a632aafea076cc91f5a4Wink Saville            // Set the initial state
981b8b98b3db5dcf0b01d1a632aafea076cc91f5a4Wink Saville            setInitialState(mS1);
991b8b98b3db5dcf0b01d1a632aafea076cc91f5a4Wink Saville        }
1001b8b98b3db5dcf0b01d1a632aafea076cc91f5a4Wink Saville
101bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        @Override
102bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        public void onQuitting() {
103efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville            log("onQuitting");
104bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville            addLogRec(ON_QUITTING);
105efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville            mLogRecs = mThisSm.copyLogRecs();
106bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville            synchronized (mThisSm) {
107bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville                mThisSm.notifyAll();
108bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville            }
109bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        }
110bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville
11164c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville        class S1 extends State {
112efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville            @Override
113bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville            public void exit() {
114efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                log("S1.exit");
115efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                addLogRec(EXIT);
116bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville            }
11764c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            @Override
11864c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            public boolean processMessage(Message message) {
119bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville                switch(message.what) {
120bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville                    // Sleep and assume the other messages will be queued up.
121bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville                    case TEST_CMD_1: {
122efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                        log("TEST_CMD_1");
123bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville                        sleep(500);
124bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville                        quit();
125bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville                        break;
126bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville                    }
127bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville                    default: {
128efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                        log("default what=" + message.what);
129bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville                        break;
1301b8b98b3db5dcf0b01d1a632aafea076cc91f5a4Wink Saville                    }
1311b8b98b3db5dcf0b01d1a632aafea076cc91f5a4Wink Saville                }
132bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville                return HANDLED;
1331b8b98b3db5dcf0b01d1a632aafea076cc91f5a4Wink Saville            }
1341b8b98b3db5dcf0b01d1a632aafea076cc91f5a4Wink Saville        }
1351b8b98b3db5dcf0b01d1a632aafea076cc91f5a4Wink Saville
1361b8b98b3db5dcf0b01d1a632aafea076cc91f5a4Wink Saville        private StateMachineQuitTest mThisSm;
1371b8b98b3db5dcf0b01d1a632aafea076cc91f5a4Wink Saville        private S1 mS1 = new S1();
1381b8b98b3db5dcf0b01d1a632aafea076cc91f5a4Wink Saville    }
1391b8b98b3db5dcf0b01d1a632aafea076cc91f5a4Wink Saville
1401b8b98b3db5dcf0b01d1a632aafea076cc91f5a4Wink Saville    @SmallTest
141bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville    public void testStateMachineQuit() throws Exception {
1426b888d98f7fffe5b87b3d5421d2f9a119899c7ddWink Saville        if (WAIT_FOR_DEBUGGER) Debug.waitForDebugger();
1431b8b98b3db5dcf0b01d1a632aafea076cc91f5a4Wink Saville
1441b8b98b3db5dcf0b01d1a632aafea076cc91f5a4Wink Saville        StateMachineQuitTest smQuitTest = new StateMachineQuitTest("smQuitTest");
1451b8b98b3db5dcf0b01d1a632aafea076cc91f5a4Wink Saville        smQuitTest.start();
146efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        if (smQuitTest.isDbg()) tlog("testStateMachineQuit E");
1471b8b98b3db5dcf0b01d1a632aafea076cc91f5a4Wink Saville
1481b8b98b3db5dcf0b01d1a632aafea076cc91f5a4Wink Saville        synchronized (smQuitTest) {
149bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville
150bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville            // Send 6 message we'll quit on the first but all 6 should be processed before quitting.
1511b8b98b3db5dcf0b01d1a632aafea076cc91f5a4Wink Saville            for (int i = 1; i <= 6; i++) {
152bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville                smQuitTest.sendMessage(smQuitTest.obtainMessage(i));
153bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville            }
154bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville
155bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville            try {
156bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville                // wait for the messages to be handled
157bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville                smQuitTest.wait();
158bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville            } catch (InterruptedException e) {
159efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                tloge("testStateMachineQuit: exception while waiting " + e.getMessage());
160bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville            }
161bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        }
162bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville
163efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        dumpLogRecs(smQuitTest.mLogRecs);
164efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        assertEquals(8, smQuitTest.mLogRecs.size());
165bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville
166bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        LogRec lr;
167efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        Iterator<LogRec> itr = smQuitTest.mLogRecs.iterator();
168efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        for (int i = 1; i <= 6; i++) {
169efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville            lr = itr.next();
170efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville            assertEquals(i, lr.getWhat());
171bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville            assertEquals(smQuitTest.mS1, lr.getState());
172bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville            assertEquals(smQuitTest.mS1, lr.getOriginalState());
173bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        }
174efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        lr = itr.next();
175bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(EXIT, lr.getInfo());
176bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(smQuitTest.mS1, lr.getState());
177bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville
178efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        lr = itr.next();
179bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(ON_QUITTING, lr.getInfo());
180bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville
181efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        if (smQuitTest.isDbg()) tlog("testStateMachineQuit X");
182bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville    }
183bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville
184bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville    /**
185bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville     * Tests {@link StateMachine#quitNow()}
186bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville     */
187bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville    class StateMachineQuitNowTest extends StateMachine {
188efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        public Collection<LogRec> mLogRecs = null;
189bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville
190bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        StateMachineQuitNowTest(String name) {
191bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville            super(name);
192bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville            mThisSm = this;
193bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville            setDbg(DBG);
194bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville
195bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville            // Setup state machine with 1 state
196bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville            addState(mS1);
197bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville
198bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville            // Set the initial state
199bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville            setInitialState(mS1);
200bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        }
201bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville
202bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        @Override
203bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        public void onQuitting() {
204efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville            log("onQuitting");
205bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville            addLogRec(ON_QUITTING);
206efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville            // Get a copy of the log records since we're quitting and they will disappear
207efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville            mLogRecs = mThisSm.copyLogRecs();
208efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville
209bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville            synchronized (mThisSm) {
210bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville                mThisSm.notifyAll();
211bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville            }
212bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        }
213bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville
214bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        class S1 extends State {
215efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville            @Override
216bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville            public void exit() {
217efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                log("S1.exit");
218efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                addLogRec(EXIT);
2191b8b98b3db5dcf0b01d1a632aafea076cc91f5a4Wink Saville            }
220bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville            @Override
221bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville            public boolean processMessage(Message message) {
222bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville                switch(message.what) {
223bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville                    // Sleep and assume the other messages will be queued up.
224bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville                    case TEST_CMD_1: {
225efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                        log("TEST_CMD_1");
226bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville                        sleep(500);
227bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville                        quitNow();
228bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville                        break;
229bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville                    }
230bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville                    default: {
231efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                        log("default what=" + message.what);
232bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville                        break;
233bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville                    }
234bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville                }
235bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville                return HANDLED;
236bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville            }
237bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        }
238bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville
239bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        private StateMachineQuitNowTest mThisSm;
240bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        private S1 mS1 = new S1();
241bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville    }
2421b8b98b3db5dcf0b01d1a632aafea076cc91f5a4Wink Saville
243bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville    @SmallTest
244bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville    public void testStateMachineQuitNow() throws Exception {
245bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        if (WAIT_FOR_DEBUGGER) Debug.waitForDebugger();
2461b8b98b3db5dcf0b01d1a632aafea076cc91f5a4Wink Saville
247bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        StateMachineQuitNowTest smQuitNowTest = new StateMachineQuitNowTest("smQuitNowTest");
248bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        smQuitNowTest.start();
249efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        if (smQuitNowTest.isDbg()) tlog("testStateMachineQuitNow E");
250bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville
251bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        synchronized (smQuitNowTest) {
252bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville
253efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville            // Send 6 message we'll QuitNow on the first even though
254bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville            // we send 6 only one will be processed.
255bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville            for (int i = 1; i <= 6; i++) {
256bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville                smQuitNowTest.sendMessage(smQuitNowTest.obtainMessage(i));
257bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville            }
2581b8b98b3db5dcf0b01d1a632aafea076cc91f5a4Wink Saville
2591b8b98b3db5dcf0b01d1a632aafea076cc91f5a4Wink Saville            try {
2601b8b98b3db5dcf0b01d1a632aafea076cc91f5a4Wink Saville                // wait for the messages to be handled
261bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville                smQuitNowTest.wait();
2621b8b98b3db5dcf0b01d1a632aafea076cc91f5a4Wink Saville            } catch (InterruptedException e) {
263efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                tloge("testStateMachineQuitNow: exception while waiting " + e.getMessage());
2641b8b98b3db5dcf0b01d1a632aafea076cc91f5a4Wink Saville            }
2651b8b98b3db5dcf0b01d1a632aafea076cc91f5a4Wink Saville        }
2661b8b98b3db5dcf0b01d1a632aafea076cc91f5a4Wink Saville
267efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        tlog("testStateMachineQuiteNow: logRecs=" + smQuitNowTest.mLogRecs);
268efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        assertEquals(3, smQuitNowTest.mLogRecs.size());
2691b8b98b3db5dcf0b01d1a632aafea076cc91f5a4Wink Saville
270efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        Iterator<LogRec> itr = smQuitNowTest.mLogRecs.iterator();
271efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        LogRec lr = itr.next();
272bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(1, lr.getWhat());
273bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(smQuitNowTest.mS1, lr.getState());
274bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(smQuitNowTest.mS1, lr.getOriginalState());
2751b8b98b3db5dcf0b01d1a632aafea076cc91f5a4Wink Saville
276efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        lr = itr.next();
277bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(EXIT, lr.getInfo());
278bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(smQuitNowTest.mS1, lr.getState());
2791b8b98b3db5dcf0b01d1a632aafea076cc91f5a4Wink Saville
280efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        lr = itr.next();
281bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(ON_QUITTING, lr.getInfo());
2821b8b98b3db5dcf0b01d1a632aafea076cc91f5a4Wink Saville
283efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        if (smQuitNowTest.isDbg()) tlog("testStateMachineQuitNow X");
2841b8b98b3db5dcf0b01d1a632aafea076cc91f5a4Wink Saville    }
2851b8b98b3db5dcf0b01d1a632aafea076cc91f5a4Wink Saville
2861b8b98b3db5dcf0b01d1a632aafea076cc91f5a4Wink Saville    /**
287e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville     * Test enter/exit can use transitionTo
288e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville     */
28964c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville    class StateMachineEnterExitTransitionToTest extends StateMachine {
290bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville
291e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville        StateMachineEnterExitTransitionToTest(String name) {
292e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville            super(name);
293e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville            mThisSm = this;
294e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville            setDbg(DBG);
295e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville
296e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville            // Setup state machine with 1 state
297e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville            addState(mS1);
298e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville            addState(mS2);
299e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville            addState(mS3);
300e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville            addState(mS4);
301e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville
302e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville            // Set the initial state
303e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville            setInitialState(mS1);
304e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville        }
305e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville
30664c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville        class S1 extends State {
30764c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            @Override
30864c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            public void enter() {
309bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville                // Test transitions in enter on the initial state work
310efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                addLogRec(ENTER);
311e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville                transitionTo(mS2);
312efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                log("S1.enter");
313e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville            }
31464c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            @Override
31564c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            public void exit() {
316efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                addLogRec(EXIT);
317efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                log("S1.exit");
318e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville            }
319e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville        }
320e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville
32164c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville        class S2 extends State {
32264c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            @Override
32364c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            public void enter() {
324efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                addLogRec(ENTER);
325efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                log("S2.enter");
326e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville            }
32764c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            @Override
32864c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            public void exit() {
329e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville                // Test transition in exit work
330e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville                transitionTo(mS4);
331efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville
332efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                assertEquals(TEST_CMD_1, getCurrentMessage().what);
333efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                addLogRec(EXIT);
334efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville
335efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                log("S2.exit");
336e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville            }
33764c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            @Override
33864c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            public boolean processMessage(Message message) {
339e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville                // Start a transition to S3 but it will be
340a4f3bec29c85ef9e0d07fdd551fe3c50f28b9adcWink Saville                // changed to a transition to S4 in exit
341e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville                transitionTo(mS3);
342efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                log("S2.processMessage");
343a4f3bec29c85ef9e0d07fdd551fe3c50f28b9adcWink Saville                return HANDLED;
344e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville            }
345e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville        }
346e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville
34764c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville        class S3 extends State {
34864c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            @Override
34964c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            public void enter() {
350efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                addLogRec(ENTER);
351efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                log("S3.enter");
352e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville            }
35364c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            @Override
35464c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            public void exit() {
355efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                addLogRec(EXIT);
356efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                log("S3.exit");
357e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville            }
358e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville        }
359e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville
36064c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville        class S4 extends State {
36164c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            @Override
36264c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            public void enter() {
363efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                addLogRec(ENTER);
364e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville                // Test that we can do halting in an enter/exit
365e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville                transitionToHaltingState();
366efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                log("S4.enter");
367e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville            }
36864c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            @Override
36964c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            public void exit() {
370efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                addLogRec(EXIT);
371efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                log("S4.exit");
372e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville            }
373e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville        }
374e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville
375e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville        @Override
376bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        protected void onHalting() {
377e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville            synchronized (mThisSm) {
378e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville                mThisSm.notifyAll();
379e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville            }
380e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville        }
381e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville
382e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville        private StateMachineEnterExitTransitionToTest mThisSm;
383e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville        private S1 mS1 = new S1();
384e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville        private S2 mS2 = new S2();
385e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville        private S3 mS3 = new S3();
386e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville        private S4 mS4 = new S4();
387e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville    }
388e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville
389e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville    @SmallTest
390e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville    public void testStateMachineEnterExitTransitionToTest() throws Exception {
391e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville        //if (WAIT_FOR_DEBUGGER) Debug.waitForDebugger();
392e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville
393e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville        StateMachineEnterExitTransitionToTest smEnterExitTranstionToTest =
394e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville            new StateMachineEnterExitTransitionToTest("smEnterExitTranstionToTest");
395e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville        smEnterExitTranstionToTest.start();
396e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville        if (smEnterExitTranstionToTest.isDbg()) {
397efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville            tlog("testStateMachineEnterExitTransitionToTest E");
398e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville        }
399e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville
400e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville        synchronized (smEnterExitTranstionToTest) {
401a4f3bec29c85ef9e0d07fdd551fe3c50f28b9adcWink Saville            smEnterExitTranstionToTest.sendMessage(TEST_CMD_1);
402e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville
403e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville            try {
404e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville                // wait for the messages to be handled
405e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville                smEnterExitTranstionToTest.wait();
406e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville            } catch (InterruptedException e) {
407efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                tloge("testStateMachineEnterExitTransitionToTest: exception while waiting "
408e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville                    + e.getMessage());
409e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville            }
410e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville        }
411e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville
412efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        dumpLogRecs(smEnterExitTranstionToTest);
413bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville
414efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        assertEquals(9, smEnterExitTranstionToTest.getLogRecCount());
415bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        LogRec lr;
416bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville
417bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        lr = smEnterExitTranstionToTest.getLogRec(0);
418bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(ENTER, lr.getInfo());
419bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(smEnterExitTranstionToTest.mS1, lr.getState());
420bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville
421bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        lr = smEnterExitTranstionToTest.getLogRec(1);
422bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(EXIT, lr.getInfo());
423bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(smEnterExitTranstionToTest.mS1, lr.getState());
424bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville
425bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        lr = smEnterExitTranstionToTest.getLogRec(2);
426bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(ENTER, lr.getInfo());
427bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(smEnterExitTranstionToTest.mS2, lr.getState());
428bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville
429bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        lr = smEnterExitTranstionToTest.getLogRec(3);
430bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(TEST_CMD_1, lr.getWhat());
431bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(smEnterExitTranstionToTest.mS2, lr.getState());
432bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(smEnterExitTranstionToTest.mS2, lr.getOriginalState());
433efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        assertEquals(smEnterExitTranstionToTest.mS3, lr.getDestState());
434bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville
435bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        lr = smEnterExitTranstionToTest.getLogRec(4);
436efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        assertEquals(TEST_CMD_1, lr.getWhat());
437bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(smEnterExitTranstionToTest.mS2, lr.getState());
438efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        assertEquals(smEnterExitTranstionToTest.mS2, lr.getOriginalState());
439efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        assertEquals(smEnterExitTranstionToTest.mS4, lr.getDestState());
440efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        assertEquals(EXIT, lr.getInfo());
441bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville
442bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        lr = smEnterExitTranstionToTest.getLogRec(5);
443efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        assertEquals(TEST_CMD_1, lr.getWhat());
444bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(ENTER, lr.getInfo());
445bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(smEnterExitTranstionToTest.mS3, lr.getState());
446efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        assertEquals(smEnterExitTranstionToTest.mS3, lr.getOriginalState());
447efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        assertEquals(smEnterExitTranstionToTest.mS4, lr.getDestState());
448e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville
449bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        lr = smEnterExitTranstionToTest.getLogRec(6);
450efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        assertEquals(TEST_CMD_1, lr.getWhat());
451bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(EXIT, lr.getInfo());
452bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(smEnterExitTranstionToTest.mS3, lr.getState());
453efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        assertEquals(smEnterExitTranstionToTest.mS3, lr.getOriginalState());
454efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        assertEquals(smEnterExitTranstionToTest.mS4, lr.getDestState());
455e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville
456bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        lr = smEnterExitTranstionToTest.getLogRec(7);
457efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        assertEquals(TEST_CMD_1, lr.getWhat());
458bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(ENTER, lr.getInfo());
459bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(smEnterExitTranstionToTest.mS4, lr.getState());
460efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        assertEquals(smEnterExitTranstionToTest.mS4, lr.getOriginalState());
461efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        assertEquals(smEnterExitTranstionToTest.mS4, lr.getDestState());
462e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville
463bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        lr = smEnterExitTranstionToTest.getLogRec(8);
464efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        assertEquals(TEST_CMD_1, lr.getWhat());
465bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(EXIT, lr.getInfo());
466bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(smEnterExitTranstionToTest.mS4, lr.getState());
467efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        assertEquals(smEnterExitTranstionToTest.mS4, lr.getOriginalState());
468e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville
469e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville        if (smEnterExitTranstionToTest.isDbg()) {
470efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville            tlog("testStateMachineEnterExitTransitionToTest X");
471e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville        }
472e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville    }
473e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville
474e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville    /**
475fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville     * Tests that ProcessedMessage works as a circular buffer.
476fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville     */
47764c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville    class StateMachine0 extends StateMachine {
478fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        StateMachine0(String name) {
479fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            super(name);
480fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            mThisSm = this;
481fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            setDbg(DBG);
482bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville            setLogRecSize(3);
483fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
484fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            // Setup state machine with 1 state
485fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            addState(mS1);
486fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
487fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            // Set the initial state
488fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            setInitialState(mS1);
489fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        }
490fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
49164c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville        class S1 extends State {
49264c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            @Override
49364c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            public boolean processMessage(Message message) {
494fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                if (message.what == TEST_CMD_6) {
495fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                    transitionToHaltingState();
496fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                }
497a4f3bec29c85ef9e0d07fdd551fe3c50f28b9adcWink Saville                return HANDLED;
498fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            }
499fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        }
500fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
501fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        @Override
502bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        protected void onHalting() {
503fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            synchronized (mThisSm) {
504fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                mThisSm.notifyAll();
505fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            }
506fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        }
507fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
508fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        private StateMachine0 mThisSm;
509fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        private S1 mS1 = new S1();
510fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    }
511fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
512fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    @SmallTest
513fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    public void testStateMachine0() throws Exception {
5141b8b98b3db5dcf0b01d1a632aafea076cc91f5a4Wink Saville        //if (WAIT_FOR_DEBUGGER) Debug.waitForDebugger();
515fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
516fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        StateMachine0 sm0 = new StateMachine0("sm0");
517fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        sm0.start();
518efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        if (sm0.isDbg()) tlog("testStateMachine0 E");
519fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
520fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        synchronized (sm0) {
521fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            // Send 6 messages
522fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            for (int i = 1; i <= 6; i++) {
523fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                sm0.sendMessage(sm0.obtainMessage(i));
524fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            }
525fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
526fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            try {
527fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                // wait for the messages to be handled
528fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                sm0.wait();
529fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            } catch (InterruptedException e) {
530efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                tloge("testStateMachine0: exception while waiting " + e.getMessage());
531fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            }
532fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        }
533fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
534bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(6, sm0.getLogRecCount());
535bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(3, sm0.getLogRecSize());
536fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
537efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        dumpLogRecs(sm0);
538efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville
539bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        LogRec lr;
540bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        lr = sm0.getLogRec(0);
541bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(TEST_CMD_4, lr.getWhat());
542bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(sm0.mS1, lr.getState());
543bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(sm0.mS1, lr.getOriginalState());
544fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
545bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        lr = sm0.getLogRec(1);
546bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(TEST_CMD_5, lr.getWhat());
547bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(sm0.mS1, lr.getState());
548bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(sm0.mS1, lr.getOriginalState());
549fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
550bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        lr = sm0.getLogRec(2);
551bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(TEST_CMD_6, lr.getWhat());
552bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(sm0.mS1, lr.getState());
553bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(sm0.mS1, lr.getOriginalState());
554fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
555efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        if (sm0.isDbg()) tlog("testStateMachine0 X");
556fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    }
557fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
558fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    /**
559fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville     * This tests enter/exit and transitions to the same state.
560fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville     * The state machine has one state, it receives two messages
561fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville     * in state mS1. With the first message it transitions to
562fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville     * itself which causes it to be exited and reentered.
563fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville     */
56464c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville    class StateMachine1 extends StateMachine {
565fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        StateMachine1(String name) {
566fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            super(name);
567fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            mThisSm = this;
568fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            setDbg(DBG);
569fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
570fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            // Setup state machine with 1 state
571fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            addState(mS1);
572fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
573fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            // Set the initial state
574fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            setInitialState(mS1);
575efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville            if (DBG) log("StateMachine1: ctor X");
576fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        }
577fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
57864c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville        class S1 extends State {
57964c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            @Override
58064c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            public void enter() {
581fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                mEnterCount++;
582fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            }
58364c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            @Override
58464c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            public void exit() {
58564c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville                mExitCount++;
58664c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            }
58764c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            @Override
58864c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            public boolean processMessage(Message message) {
589fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                if (message.what == TEST_CMD_1) {
590fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                    assertEquals(1, mEnterCount);
591fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                    assertEquals(0, mExitCount);
592fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                    transitionTo(mS1);
593fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                } else if (message.what == TEST_CMD_2) {
594fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                    assertEquals(2, mEnterCount);
595fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                    assertEquals(1, mExitCount);
596fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                    transitionToHaltingState();
597fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                }
598a4f3bec29c85ef9e0d07fdd551fe3c50f28b9adcWink Saville                return HANDLED;
599fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            }
600fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        }
601fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
602fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        @Override
603bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        protected void onHalting() {
604fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            synchronized (mThisSm) {
605fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                mThisSm.notifyAll();
606fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            }
607fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        }
608fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
609fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        private StateMachine1 mThisSm;
610fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        private S1 mS1 = new S1();
611fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
612fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        private int mEnterCount;
613fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        private int mExitCount;
614fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    }
615fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
616f76c56bcaa9df1d1afa711177f813dc63f399795Brett Chabot    @MediumTest
617fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    public void testStateMachine1() throws Exception {
618fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        StateMachine1 sm1 = new StateMachine1("sm1");
619fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        sm1.start();
620efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        if (sm1.isDbg()) tlog("testStateMachine1 E");
621fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
622fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        synchronized (sm1) {
623fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            // Send two messages
62491fbd56757751a7aca8ef2b4d936e587509e6eefWink Saville            sm1.sendMessage(TEST_CMD_1);
62591fbd56757751a7aca8ef2b4d936e587509e6eefWink Saville            sm1.sendMessage(TEST_CMD_2);
626fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
627fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            try {
628fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                // wait for the messages to be handled
629fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                sm1.wait();
630fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            } catch (InterruptedException e) {
631efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                tloge("testStateMachine1: exception while waiting " + e.getMessage());
632fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            }
633fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        }
634fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
635fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        assertEquals(2, sm1.mEnterCount);
636fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        assertEquals(2, sm1.mExitCount);
637fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
638bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(2, sm1.getLogRecSize());
639fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
640bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        LogRec lr;
641bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        lr = sm1.getLogRec(0);
642bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(TEST_CMD_1, lr.getWhat());
643bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(sm1.mS1, lr.getState());
644bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(sm1.mS1, lr.getOriginalState());
645fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
646bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        lr = sm1.getLogRec(1);
647bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(TEST_CMD_2, lr.getWhat());
648bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(sm1.mS1, lr.getState());
649bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(sm1.mS1, lr.getOriginalState());
650fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
651fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        assertEquals(2, sm1.mEnterCount);
652fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        assertEquals(2, sm1.mExitCount);
653fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
654efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        if (sm1.isDbg()) tlog("testStateMachine1 X");
655fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    }
656fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
657fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    /**
658fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville     * Test deferring messages and states with no parents. The state machine
659fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville     * has two states, it receives two messages in state mS1 deferring them
660fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville     * until what == TEST_CMD_2 and then transitions to state mS2. State
661fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville     * mS2 then receives both of the deferred messages first TEST_CMD_1 and
662fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville     * then TEST_CMD_2.
663fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville     */
66464c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville    class StateMachine2 extends StateMachine {
665fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        StateMachine2(String name) {
666fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            super(name);
667fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            mThisSm = this;
668fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            setDbg(DBG);
669fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
670fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            // Setup the hierarchy
671fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            addState(mS1);
672fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            addState(mS2);
673fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
674fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            // Set the initial state
675fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            setInitialState(mS1);
676efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville            if (DBG) log("StateMachine2: ctor X");
677fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        }
678fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
67964c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville        class S1 extends State {
68064c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            @Override
68164c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            public void enter() {
682fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                mDidEnter = true;
683fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            }
68464c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            @Override
68564c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            public void exit() {
68664c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville                mDidExit = true;
68764c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            }
68864c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            @Override
68964c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            public boolean processMessage(Message message) {
690fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                deferMessage(message);
691fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                if (message.what == TEST_CMD_2) {
692fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                    transitionTo(mS2);
693fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                }
694a4f3bec29c85ef9e0d07fdd551fe3c50f28b9adcWink Saville                return HANDLED;
695fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            }
696fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        }
697fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
69864c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville        class S2 extends State {
69964c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            @Override
70064c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            public boolean processMessage(Message message) {
701fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                if (message.what == TEST_CMD_2) {
702fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                    transitionToHaltingState();
703fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                }
704a4f3bec29c85ef9e0d07fdd551fe3c50f28b9adcWink Saville                return HANDLED;
705fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            }
706fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        }
707fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
708fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        @Override
709bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        protected void onHalting() {
710fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            synchronized (mThisSm) {
711fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                mThisSm.notifyAll();
712fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            }
713fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        }
714fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
715fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        private StateMachine2 mThisSm;
716fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        private S1 mS1 = new S1();
717fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        private S2 mS2 = new S2();
718fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
719fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        private boolean mDidEnter = false;
720fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        private boolean mDidExit = false;
721fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    }
722fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
723f76c56bcaa9df1d1afa711177f813dc63f399795Brett Chabot    @MediumTest
724fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    public void testStateMachine2() throws Exception {
725fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        StateMachine2 sm2 = new StateMachine2("sm2");
726fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        sm2.start();
727efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        if (sm2.isDbg()) tlog("testStateMachine2 E");
728fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
729fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        synchronized (sm2) {
730fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            // Send two messages
73191fbd56757751a7aca8ef2b4d936e587509e6eefWink Saville            sm2.sendMessage(TEST_CMD_1);
73291fbd56757751a7aca8ef2b4d936e587509e6eefWink Saville            sm2.sendMessage(TEST_CMD_2);
733fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
734fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            try {
735fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                // wait for the messages to be handled
736fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                sm2.wait();
737fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            } catch (InterruptedException e) {
738efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                tloge("testStateMachine2: exception while waiting " + e.getMessage());
739fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            }
740fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        }
741fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
742bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(4, sm2.getLogRecSize());
743fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
744bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        LogRec lr;
745bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        lr = sm2.getLogRec(0);
746bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(TEST_CMD_1, lr.getWhat());
747bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(sm2.mS1, lr.getState());
748fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
749bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        lr = sm2.getLogRec(1);
750bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(TEST_CMD_2, lr.getWhat());
751bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(sm2.mS1, lr.getState());
752fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
753bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        lr = sm2.getLogRec(2);
754bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(TEST_CMD_1, lr.getWhat());
755bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(sm2.mS2, lr.getState());
756fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
757bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        lr = sm2.getLogRec(3);
758bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(TEST_CMD_2, lr.getWhat());
759bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(sm2.mS2, lr.getState());
760fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
761fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        assertTrue(sm2.mDidEnter);
762fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        assertTrue(sm2.mDidExit);
763fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
764efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        if (sm2.isDbg()) tlog("testStateMachine2 X");
765fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    }
766fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
767fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    /**
768fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville     * Test that unhandled messages in a child are handled by the parent.
769fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville     * When TEST_CMD_2 is received.
770fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville     */
77164c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville    class StateMachine3 extends StateMachine {
772fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        StateMachine3(String name) {
773fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            super(name);
774fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            mThisSm = this;
775fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            setDbg(DBG);
776fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
777fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            // Setup the simplest hierarchy of two states
778fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            // mParentState and mChildState.
779fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            // (Use indentation to help visualize hierarchy)
780fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            addState(mParentState);
781fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                addState(mChildState, mParentState);
782fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
783fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            // Set the initial state will be the child
784fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            setInitialState(mChildState);
785efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville            if (DBG) log("StateMachine3: ctor X");
786fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        }
787fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
78864c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville        class ParentState extends State {
78964c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            @Override
79064c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            public boolean processMessage(Message message) {
791fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                if (message.what == TEST_CMD_2) {
792fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                    transitionToHaltingState();
793fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                }
794a4f3bec29c85ef9e0d07fdd551fe3c50f28b9adcWink Saville                return HANDLED;
795fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            }
796fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        }
797fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
79864c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville        class ChildState extends State {
79964c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            @Override
80064c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            public boolean processMessage(Message message) {
801a4f3bec29c85ef9e0d07fdd551fe3c50f28b9adcWink Saville                return NOT_HANDLED;
802fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            }
803fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        }
804fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
805fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        @Override
806bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        protected void onHalting() {
807fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            synchronized (mThisSm) {
808fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                mThisSm.notifyAll();
809fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            }
810fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        }
811fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
812fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        private StateMachine3 mThisSm;
813fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        private ParentState mParentState = new ParentState();
814fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        private ChildState mChildState = new ChildState();
815fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    }
816fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
817f76c56bcaa9df1d1afa711177f813dc63f399795Brett Chabot    @MediumTest
818fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    public void testStateMachine3() throws Exception {
819fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        StateMachine3 sm3 = new StateMachine3("sm3");
820fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        sm3.start();
821efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        if (sm3.isDbg()) tlog("testStateMachine3 E");
822fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
823fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        synchronized (sm3) {
824fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            // Send two messages
82591fbd56757751a7aca8ef2b4d936e587509e6eefWink Saville            sm3.sendMessage(TEST_CMD_1);
82691fbd56757751a7aca8ef2b4d936e587509e6eefWink Saville            sm3.sendMessage(TEST_CMD_2);
827fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
828fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            try {
829fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                // wait for the messages to be handled
830fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                sm3.wait();
831fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            } catch (InterruptedException e) {
832efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                tloge("testStateMachine3: exception while waiting " + e.getMessage());
833fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            }
834fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        }
835fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
836bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(2, sm3.getLogRecSize());
837fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
838bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        LogRec lr;
839bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        lr = sm3.getLogRec(0);
840bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(TEST_CMD_1, lr.getWhat());
841bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(sm3.mParentState, lr.getState());
842bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(sm3.mChildState, lr.getOriginalState());
843fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
844bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        lr = sm3.getLogRec(1);
845bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(TEST_CMD_2, lr.getWhat());
846bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(sm3.mParentState, lr.getState());
847bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(sm3.mChildState, lr.getOriginalState());
848fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
849efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        if (sm3.isDbg()) tlog("testStateMachine3 X");
850fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    }
851fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
852fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    /**
853fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville     * Test a hierarchy of 3 states a parent and two children
854fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville     * with transition from child 1 to child 2 and child 2
855fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville     * lets the parent handle the messages.
856fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville     */
85764c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville    class StateMachine4 extends StateMachine {
858fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        StateMachine4(String name) {
859fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            super(name);
860fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            mThisSm = this;
861fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            setDbg(DBG);
862fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
863fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            // Setup a hierarchy of three states
864fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            // mParentState, mChildState1 & mChildState2
865fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            // (Use indentation to help visualize hierarchy)
866fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            addState(mParentState);
867fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                addState(mChildState1, mParentState);
868fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                addState(mChildState2, mParentState);
869fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
870fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            // Set the initial state will be child 1
871fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            setInitialState(mChildState1);
872efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville            if (DBG) log("StateMachine4: ctor X");
873fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        }
874fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
87564c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville        class ParentState extends State {
87664c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            @Override
87764c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            public boolean processMessage(Message message) {
878fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                if (message.what == TEST_CMD_2) {
879fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                    transitionToHaltingState();
880fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                }
881a4f3bec29c85ef9e0d07fdd551fe3c50f28b9adcWink Saville                return HANDLED;
882fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            }
883fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        }
884fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
88564c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville        class ChildState1 extends State {
88664c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            @Override
88764c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            public boolean processMessage(Message message) {
888fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                transitionTo(mChildState2);
889a4f3bec29c85ef9e0d07fdd551fe3c50f28b9adcWink Saville                return HANDLED;
890fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            }
891fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        }
892fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
89364c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville        class ChildState2 extends State {
89464c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            @Override
89564c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            public boolean processMessage(Message message) {
896a4f3bec29c85ef9e0d07fdd551fe3c50f28b9adcWink Saville                return NOT_HANDLED;
897fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            }
898fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        }
899fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
900fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        @Override
901bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        protected void onHalting() {
902fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            synchronized (mThisSm) {
903fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                mThisSm.notifyAll();
904fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            }
905fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        }
906fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
907fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        private StateMachine4 mThisSm;
908fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        private ParentState mParentState = new ParentState();
909fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        private ChildState1 mChildState1 = new ChildState1();
910fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        private ChildState2 mChildState2 = new ChildState2();
911fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    }
912fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
913f76c56bcaa9df1d1afa711177f813dc63f399795Brett Chabot    @MediumTest
914fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    public void testStateMachine4() throws Exception {
915fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        StateMachine4 sm4 = new StateMachine4("sm4");
916fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        sm4.start();
917efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        if (sm4.isDbg()) tlog("testStateMachine4 E");
918fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
919fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        synchronized (sm4) {
920fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            // Send two messages
92191fbd56757751a7aca8ef2b4d936e587509e6eefWink Saville            sm4.sendMessage(TEST_CMD_1);
92291fbd56757751a7aca8ef2b4d936e587509e6eefWink Saville            sm4.sendMessage(TEST_CMD_2);
923fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
924fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            try {
925fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                // wait for the messages to be handled
926fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                sm4.wait();
927fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            } catch (InterruptedException e) {
928efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                tloge("testStateMachine4: exception while waiting " + e.getMessage());
929fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            }
930fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        }
931fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
932fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
933bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(2, sm4.getLogRecSize());
934fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
935bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        LogRec lr;
936bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        lr = sm4.getLogRec(0);
937bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(TEST_CMD_1, lr.getWhat());
938bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(sm4.mChildState1, lr.getState());
939bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(sm4.mChildState1, lr.getOriginalState());
940fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
941bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        lr = sm4.getLogRec(1);
942bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(TEST_CMD_2, lr.getWhat());
943bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(sm4.mParentState, lr.getState());
944bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(sm4.mChildState2, lr.getOriginalState());
945fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
946efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        if (sm4.isDbg()) tlog("testStateMachine4 X");
947fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    }
948fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
949fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    /**
950fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville     * Test transition from one child to another of a "complex"
951fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville     * hierarchy with two parents and multiple children.
952fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville     */
95364c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville    class StateMachine5 extends StateMachine {
954fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        StateMachine5(String name) {
955fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            super(name);
956fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            mThisSm = this;
957fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            setDbg(DBG);
958fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
959fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            // Setup a hierarchy with two parents and some children.
960fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            // (Use indentation to help visualize hierarchy)
961fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            addState(mParentState1);
962fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                addState(mChildState1, mParentState1);
963fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                addState(mChildState2, mParentState1);
964fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
965fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            addState(mParentState2);
966fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                addState(mChildState3, mParentState2);
967fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                addState(mChildState4, mParentState2);
968fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                    addState(mChildState5, mChildState4);
969fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
970fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            // Set the initial state will be the child
971fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            setInitialState(mChildState1);
972efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville            if (DBG) log("StateMachine5: ctor X");
973fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        }
974fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
97564c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville        class ParentState1 extends State {
97664c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            @Override
97764c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            public void enter() {
978fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                mParentState1EnterCount += 1;
979fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            }
98064c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            @Override
98164c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            public void exit() {
982fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                mParentState1ExitCount += 1;
983fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            }
98464c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            @Override
98564c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            public boolean processMessage(Message message) {
98664c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville                return HANDLED;
98764c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            }
988fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        }
989fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
99064c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville        class ChildState1 extends State {
99164c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            @Override
99264c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            public void enter() {
993fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                mChildState1EnterCount += 1;
994fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            }
99564c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            @Override
99664c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            public void exit() {
99764c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville                mChildState1ExitCount += 1;
99864c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            }
99964c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            @Override
100064c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            public boolean processMessage(Message message) {
1001fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(1, mParentState1EnterCount);
1002fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(0, mParentState1ExitCount);
1003fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(1, mChildState1EnterCount);
1004fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(0, mChildState1ExitCount);
1005fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(0, mChildState2EnterCount);
1006fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(0, mChildState2ExitCount);
1007fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(0, mParentState2EnterCount);
1008fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(0, mParentState2ExitCount);
1009fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(0, mChildState3EnterCount);
1010fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(0, mChildState3ExitCount);
1011fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(0, mChildState4EnterCount);
1012fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(0, mChildState4ExitCount);
1013fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(0, mChildState5EnterCount);
1014fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(0, mChildState5ExitCount);
1015fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1016fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                transitionTo(mChildState2);
1017a4f3bec29c85ef9e0d07fdd551fe3c50f28b9adcWink Saville                return HANDLED;
1018fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            }
1019fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        }
1020fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
102164c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville        class ChildState2 extends State {
102264c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            @Override
102364c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            public void enter() {
1024fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                mChildState2EnterCount += 1;
1025fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            }
102664c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            @Override
102764c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            public void exit() {
102864c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville                mChildState2ExitCount += 1;
102964c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            }
103064c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            @Override
103164c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            public boolean processMessage(Message message) {
1032fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(1, mParentState1EnterCount);
1033fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(0, mParentState1ExitCount);
1034fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(1, mChildState1EnterCount);
1035fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(1, mChildState1ExitCount);
1036fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(1, mChildState2EnterCount);
1037fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(0, mChildState2ExitCount);
1038fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(0, mParentState2EnterCount);
1039fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(0, mParentState2ExitCount);
1040fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(0, mChildState3EnterCount);
1041fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(0, mChildState3ExitCount);
1042fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(0, mChildState4EnterCount);
1043fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(0, mChildState4ExitCount);
1044fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(0, mChildState5EnterCount);
1045fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(0, mChildState5ExitCount);
1046fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1047fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                transitionTo(mChildState5);
1048a4f3bec29c85ef9e0d07fdd551fe3c50f28b9adcWink Saville                return HANDLED;
1049fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            }
1050fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        }
1051fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
105264c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville        class ParentState2 extends State {
105364c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            @Override
105464c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            public void enter() {
1055fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                mParentState2EnterCount += 1;
1056fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            }
105764c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            @Override
105864c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            public void exit() {
105964c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville                mParentState2ExitCount += 1;
106064c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            }
106164c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            @Override
106264c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            public boolean processMessage(Message message) {
1063fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(1, mParentState1EnterCount);
1064fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(1, mParentState1ExitCount);
1065fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(1, mChildState1EnterCount);
1066fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(1, mChildState1ExitCount);
1067fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(1, mChildState2EnterCount);
1068fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(1, mChildState2ExitCount);
1069fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(2, mParentState2EnterCount);
1070fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(1, mParentState2ExitCount);
1071fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(1, mChildState3EnterCount);
1072fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(1, mChildState3ExitCount);
1073fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(2, mChildState4EnterCount);
1074fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(2, mChildState4ExitCount);
1075fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(1, mChildState5EnterCount);
1076fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(1, mChildState5ExitCount);
1077fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1078fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                transitionToHaltingState();
1079a4f3bec29c85ef9e0d07fdd551fe3c50f28b9adcWink Saville                return HANDLED;
1080fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            }
1081fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        }
1082fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
108364c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville        class ChildState3 extends State {
108464c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            @Override
108564c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            public void enter() {
1086fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                mChildState3EnterCount += 1;
1087fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            }
108864c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            @Override
108964c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            public void exit() {
109064c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville                mChildState3ExitCount += 1;
109164c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            }
109264c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            @Override
109364c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            public boolean processMessage(Message message) {
1094fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(1, mParentState1EnterCount);
1095fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(1, mParentState1ExitCount);
1096fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(1, mChildState1EnterCount);
1097fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(1, mChildState1ExitCount);
1098fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(1, mChildState2EnterCount);
1099fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(1, mChildState2ExitCount);
1100fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(1, mParentState2EnterCount);
1101fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(0, mParentState2ExitCount);
1102fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(1, mChildState3EnterCount);
1103fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(0, mChildState3ExitCount);
1104fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(1, mChildState4EnterCount);
1105fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(1, mChildState4ExitCount);
1106fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(1, mChildState5EnterCount);
1107fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(1, mChildState5ExitCount);
1108fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1109fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                transitionTo(mChildState4);
1110a4f3bec29c85ef9e0d07fdd551fe3c50f28b9adcWink Saville                return HANDLED;
1111fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            }
1112fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        }
1113fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
111464c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville        class ChildState4 extends State {
111564c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            @Override
111664c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            public void enter() {
1117fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                mChildState4EnterCount += 1;
1118fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            }
111964c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            @Override
112064c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            public void exit() {
112164c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville                mChildState4ExitCount += 1;
112264c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            }
112364c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            @Override
112464c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            public boolean processMessage(Message message) {
1125fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(1, mParentState1EnterCount);
1126fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(1, mParentState1ExitCount);
1127fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(1, mChildState1EnterCount);
1128fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(1, mChildState1ExitCount);
1129fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(1, mChildState2EnterCount);
1130fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(1, mChildState2ExitCount);
1131fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(1, mParentState2EnterCount);
1132fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(0, mParentState2ExitCount);
1133fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(1, mChildState3EnterCount);
1134fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(1, mChildState3ExitCount);
1135fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(2, mChildState4EnterCount);
1136fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(1, mChildState4ExitCount);
1137fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(1, mChildState5EnterCount);
1138fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(1, mChildState5ExitCount);
1139fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1140fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                transitionTo(mParentState2);
1141a4f3bec29c85ef9e0d07fdd551fe3c50f28b9adcWink Saville                return HANDLED;
1142fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            }
1143fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        }
1144fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
114564c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville        class ChildState5 extends State {
114664c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            @Override
114764c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            public void enter() {
1148fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                mChildState5EnterCount += 1;
1149fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            }
115064c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            @Override
115164c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            public void exit() {
115264c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville                mChildState5ExitCount += 1;
115364c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            }
115464c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            @Override
115564c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            public boolean processMessage(Message message) {
1156fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(1, mParentState1EnterCount);
1157fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(1, mParentState1ExitCount);
1158fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(1, mChildState1EnterCount);
1159fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(1, mChildState1ExitCount);
1160fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(1, mChildState2EnterCount);
1161fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(1, mChildState2ExitCount);
1162fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(1, mParentState2EnterCount);
1163fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(0, mParentState2ExitCount);
1164fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(0, mChildState3EnterCount);
1165fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(0, mChildState3ExitCount);
1166fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(1, mChildState4EnterCount);
1167fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(0, mChildState4ExitCount);
1168fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(1, mChildState5EnterCount);
1169fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                assertEquals(0, mChildState5ExitCount);
1170fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1171fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                transitionTo(mChildState3);
1172a4f3bec29c85ef9e0d07fdd551fe3c50f28b9adcWink Saville                return HANDLED;
1173fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            }
1174fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        }
1175fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1176fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        @Override
1177bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        protected void onHalting() {
1178fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            synchronized (mThisSm) {
1179fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                mThisSm.notifyAll();
1180fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            }
1181fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        }
1182fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1183fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        private StateMachine5 mThisSm;
1184fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        private ParentState1 mParentState1 = new ParentState1();
1185fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        private ChildState1 mChildState1 = new ChildState1();
1186fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        private ChildState2 mChildState2 = new ChildState2();
1187fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        private ParentState2 mParentState2 = new ParentState2();
1188fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        private ChildState3 mChildState3 = new ChildState3();
1189fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        private ChildState4 mChildState4 = new ChildState4();
1190fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        private ChildState5 mChildState5 = new ChildState5();
1191fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1192fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        private int mParentState1EnterCount = 0;
1193fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        private int mParentState1ExitCount = 0;
1194fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        private int mChildState1EnterCount = 0;
1195fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        private int mChildState1ExitCount = 0;
1196fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        private int mChildState2EnterCount = 0;
1197fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        private int mChildState2ExitCount = 0;
1198fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        private int mParentState2EnterCount = 0;
1199fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        private int mParentState2ExitCount = 0;
1200fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        private int mChildState3EnterCount = 0;
1201fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        private int mChildState3ExitCount = 0;
1202fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        private int mChildState4EnterCount = 0;
1203fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        private int mChildState4ExitCount = 0;
1204fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        private int mChildState5EnterCount = 0;
1205fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        private int mChildState5ExitCount = 0;
1206fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    }
1207fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1208f76c56bcaa9df1d1afa711177f813dc63f399795Brett Chabot    @MediumTest
1209fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    public void testStateMachine5() throws Exception {
1210fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        StateMachine5 sm5 = new StateMachine5("sm5");
1211fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        sm5.start();
1212efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        if (sm5.isDbg()) tlog("testStateMachine5 E");
1213fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1214fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        synchronized (sm5) {
1215fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            // Send 6 messages
121691fbd56757751a7aca8ef2b4d936e587509e6eefWink Saville            sm5.sendMessage(TEST_CMD_1);
121791fbd56757751a7aca8ef2b4d936e587509e6eefWink Saville            sm5.sendMessage(TEST_CMD_2);
121891fbd56757751a7aca8ef2b4d936e587509e6eefWink Saville            sm5.sendMessage(TEST_CMD_3);
121991fbd56757751a7aca8ef2b4d936e587509e6eefWink Saville            sm5.sendMessage(TEST_CMD_4);
122091fbd56757751a7aca8ef2b4d936e587509e6eefWink Saville            sm5.sendMessage(TEST_CMD_5);
122191fbd56757751a7aca8ef2b4d936e587509e6eefWink Saville            sm5.sendMessage(TEST_CMD_6);
1222fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1223fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            try {
1224fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                // wait for the messages to be handled
1225fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                sm5.wait();
1226fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            } catch (InterruptedException e) {
1227efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                tloge("testStateMachine5: exception while waiting " + e.getMessage());
1228fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            }
1229fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        }
1230fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1231fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1232bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(6, sm5.getLogRecSize());
1233fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1234fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        assertEquals(1, sm5.mParentState1EnterCount);
1235fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        assertEquals(1, sm5.mParentState1ExitCount);
1236fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        assertEquals(1, sm5.mChildState1EnterCount);
1237fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        assertEquals(1, sm5.mChildState1ExitCount);
1238fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        assertEquals(1, sm5.mChildState2EnterCount);
1239fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        assertEquals(1, sm5.mChildState2ExitCount);
1240fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        assertEquals(2, sm5.mParentState2EnterCount);
1241fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        assertEquals(2, sm5.mParentState2ExitCount);
1242fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        assertEquals(1, sm5.mChildState3EnterCount);
1243fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        assertEquals(1, sm5.mChildState3ExitCount);
1244fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        assertEquals(2, sm5.mChildState4EnterCount);
1245fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        assertEquals(2, sm5.mChildState4ExitCount);
1246fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        assertEquals(1, sm5.mChildState5EnterCount);
1247fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        assertEquals(1, sm5.mChildState5ExitCount);
1248fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1249bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        LogRec lr;
1250bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        lr = sm5.getLogRec(0);
1251bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(TEST_CMD_1, lr.getWhat());
1252bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(sm5.mChildState1, lr.getState());
1253bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(sm5.mChildState1, lr.getOriginalState());
1254bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville
1255bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        lr = sm5.getLogRec(1);
1256bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(TEST_CMD_2, lr.getWhat());
1257bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(sm5.mChildState2, lr.getState());
1258bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(sm5.mChildState2, lr.getOriginalState());
1259bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville
1260bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        lr = sm5.getLogRec(2);
1261bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(TEST_CMD_3, lr.getWhat());
1262bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(sm5.mChildState5, lr.getState());
1263bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(sm5.mChildState5, lr.getOriginalState());
1264bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville
1265bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        lr = sm5.getLogRec(3);
1266bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(TEST_CMD_4, lr.getWhat());
1267bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(sm5.mChildState3, lr.getState());
1268bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(sm5.mChildState3, lr.getOriginalState());
1269bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville
1270bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        lr = sm5.getLogRec(4);
1271bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(TEST_CMD_5, lr.getWhat());
1272bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(sm5.mChildState4, lr.getState());
1273bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(sm5.mChildState4, lr.getOriginalState());
1274bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville
1275bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        lr = sm5.getLogRec(5);
1276bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(TEST_CMD_6, lr.getWhat());
1277bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(sm5.mParentState2, lr.getState());
1278bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(sm5.mParentState2, lr.getOriginalState());
1279fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1280efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        if (sm5.isDbg()) tlog("testStateMachine5 X");
1281fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    }
1282fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1283fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    /**
1284fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville     * Test that the initial state enter is invoked immediately
1285fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville     * after construction and before any other messages arrive and that
1286fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville     * sendMessageDelayed works.
1287fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville     */
128864c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville    class StateMachine6 extends StateMachine {
1289fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        StateMachine6(String name) {
1290fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            super(name);
1291fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            mThisSm = this;
1292fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            setDbg(DBG);
1293fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1294fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            // Setup state machine with 1 state
1295fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            addState(mS1);
1296fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1297fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            // Set the initial state
1298fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            setInitialState(mS1);
1299efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville            if (DBG) log("StateMachine6: ctor X");
1300fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        }
1301fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
130264c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville        class S1 extends State {
130364c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            @Override
130464c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            public void enter() {
130591fbd56757751a7aca8ef2b4d936e587509e6eefWink Saville                sendMessage(TEST_CMD_1);
1306fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            }
130764c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            @Override
130864c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            public boolean processMessage(Message message) {
1309fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                if (message.what == TEST_CMD_1) {
1310fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                    mArrivalTimeMsg1 = SystemClock.elapsedRealtime();
1311fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                } else if (message.what == TEST_CMD_2) {
1312fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                    mArrivalTimeMsg2 = SystemClock.elapsedRealtime();
1313fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                    transitionToHaltingState();
1314fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                }
1315a4f3bec29c85ef9e0d07fdd551fe3c50f28b9adcWink Saville                return HANDLED;
1316fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            }
1317fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        }
1318fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1319fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        @Override
1320bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        protected void onHalting() {
1321fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            synchronized (mThisSm) {
1322fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                mThisSm.notifyAll();
1323fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            }
1324fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        }
1325fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1326fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        private StateMachine6 mThisSm;
1327fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        private S1 mS1 = new S1();
1328fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1329fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        private long mArrivalTimeMsg1;
1330fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        private long mArrivalTimeMsg2;
1331fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    }
1332fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1333f76c56bcaa9df1d1afa711177f813dc63f399795Brett Chabot    @MediumTest
1334fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    public void testStateMachine6() throws Exception {
1335fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        final int DELAY_TIME = 250;
1336fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        final int DELAY_FUDGE = 20;
1337fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1338fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        StateMachine6 sm6 = new StateMachine6("sm6");
1339fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        sm6.start();
1340efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        if (sm6.isDbg()) tlog("testStateMachine6 E");
1341fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1342fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        synchronized (sm6) {
1343fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            // Send a message
134491fbd56757751a7aca8ef2b4d936e587509e6eefWink Saville            sm6.sendMessageDelayed(TEST_CMD_2, DELAY_TIME);
1345fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1346fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            try {
1347fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                // wait for the messages to be handled
1348fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                sm6.wait();
1349fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            } catch (InterruptedException e) {
1350efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                tloge("testStateMachine6: exception while waiting " + e.getMessage());
1351fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            }
1352fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        }
1353fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1354fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        /**
1355fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville         * TEST_CMD_1 was sent in enter and must always have been processed
1356fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville         * immediately after construction and hence the arrival time difference
1357fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville         * should always >= to the DELAY_TIME
1358fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville         */
1359fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        long arrivalTimeDiff = sm6.mArrivalTimeMsg2 - sm6.mArrivalTimeMsg1;
1360fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        long expectedDelay = DELAY_TIME - DELAY_FUDGE;
1361efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        if (sm6.isDbg()) tlog("testStateMachine6: expect " + arrivalTimeDiff
1362fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                                    + " >= " + expectedDelay);
1363fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        assertTrue(arrivalTimeDiff >= expectedDelay);
1364fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1365efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        if (sm6.isDbg()) tlog("testStateMachine6 X");
1366fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    }
1367fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1368fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    /**
1369fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville     * Test that enter is invoked immediately after exit. This validates
1370fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville     * that enter can be used to send a watch dog message for its state.
1371fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville     */
137264c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville    class StateMachine7 extends StateMachine {
1373fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        private final int SM7_DELAY_TIME = 250;
1374fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1375fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        StateMachine7(String name) {
1376fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            super(name);
1377fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            mThisSm = this;
1378fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            setDbg(DBG);
1379fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1380fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            // Setup state machine with 1 state
1381fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            addState(mS1);
1382fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            addState(mS2);
1383fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1384fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            // Set the initial state
1385fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            setInitialState(mS1);
1386efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville            if (DBG) log("StateMachine7: ctor X");
1387fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        }
1388fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
138964c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville        class S1 extends State {
139064c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            @Override
139164c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            public void exit() {
139264c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville                sendMessage(TEST_CMD_2);
139364c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            }
139464c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            @Override
139564c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            public boolean processMessage(Message message) {
1396fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                transitionTo(mS2);
1397a4f3bec29c85ef9e0d07fdd551fe3c50f28b9adcWink Saville                return HANDLED;
1398fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            }
1399fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        }
1400fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
140164c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville        class S2 extends State {
140264c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            @Override
140364c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            public void enter() {
1404fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                // Send a delayed message as a watch dog
140591fbd56757751a7aca8ef2b4d936e587509e6eefWink Saville                sendMessageDelayed(TEST_CMD_3, SM7_DELAY_TIME);
1406fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            }
140764c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            @Override
140864c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            public boolean processMessage(Message message) {
1409fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                if (message.what == TEST_CMD_2) {
1410fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                    mMsgCount += 1;
1411fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                    mArrivalTimeMsg2 = SystemClock.elapsedRealtime();
1412fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                } else if (message.what == TEST_CMD_3) {
1413fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                    mMsgCount += 1;
1414fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                    mArrivalTimeMsg3 = SystemClock.elapsedRealtime();
1415fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                }
1416fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1417fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                if (mMsgCount == 2) {
1418fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                    transitionToHaltingState();
1419fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                }
1420a4f3bec29c85ef9e0d07fdd551fe3c50f28b9adcWink Saville                return HANDLED;
1421fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            }
1422fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        }
1423fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1424fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        @Override
1425bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        protected void onHalting() {
1426fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            synchronized (mThisSm) {
1427fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                mThisSm.notifyAll();
1428fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            }
1429fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        }
1430fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1431fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        private StateMachine7 mThisSm;
1432fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        private S1 mS1 = new S1();
1433fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        private S2 mS2 = new S2();
1434fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1435fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        private int mMsgCount = 0;
1436fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        private long mArrivalTimeMsg2;
1437fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        private long mArrivalTimeMsg3;
1438fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    }
1439fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1440f76c56bcaa9df1d1afa711177f813dc63f399795Brett Chabot    @MediumTest
1441fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    public void testStateMachine7() throws Exception {
1442fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        final int SM7_DELAY_FUDGE = 20;
1443fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1444fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        StateMachine7 sm7 = new StateMachine7("sm7");
1445fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        sm7.start();
1446efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        if (sm7.isDbg()) tlog("testStateMachine7 E");
1447fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1448fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        synchronized (sm7) {
1449fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            // Send a message
145091fbd56757751a7aca8ef2b4d936e587509e6eefWink Saville            sm7.sendMessage(TEST_CMD_1);
1451fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1452fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            try {
1453fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                // wait for the messages to be handled
1454fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                sm7.wait();
1455fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            } catch (InterruptedException e) {
1456efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                tloge("testStateMachine7: exception while waiting " + e.getMessage());
1457fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            }
1458fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        }
1459fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1460fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        /**
1461fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville         * TEST_CMD_3 was sent in S2.enter with a delay and must always have been
1462fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville         * processed immediately after S1.exit. Since S1.exit sent TEST_CMD_2
1463fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville         * without a delay the arrival time difference should always >= to SM7_DELAY_TIME.
1464fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville         */
1465fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        long arrivalTimeDiff = sm7.mArrivalTimeMsg3 - sm7.mArrivalTimeMsg2;
1466fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        long expectedDelay = sm7.SM7_DELAY_TIME - SM7_DELAY_FUDGE;
1467efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        if (sm7.isDbg()) tlog("testStateMachine7: expect " + arrivalTimeDiff
1468fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                                    + " >= " + expectedDelay);
1469fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        assertTrue(arrivalTimeDiff >= expectedDelay);
1470fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1471efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        if (sm7.isDbg()) tlog("testStateMachine7 X");
1472fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    }
1473fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1474fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    /**
1475fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville     * Test unhandledMessage.
1476fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville     */
147764c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville    class StateMachineUnhandledMessage extends StateMachine {
1478fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        StateMachineUnhandledMessage(String name) {
1479fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            super(name);
1480fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            mThisSm = this;
1481fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            setDbg(DBG);
1482fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1483fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            // Setup state machine with 1 state
1484fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            addState(mS1);
1485fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1486fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            // Set the initial state
1487fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            setInitialState(mS1);
1488fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        }
148964c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville        @Override
149064c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville        public void unhandledMessage(Message message) {
1491fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            mUnhandledMessageCount += 1;
1492fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        }
1493fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
149464c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville        class S1 extends State {
149564c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            @Override
149664c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            public boolean processMessage(Message message) {
1497fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                if (message.what == TEST_CMD_2) {
1498fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                    transitionToHaltingState();
1499fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                }
1500a4f3bec29c85ef9e0d07fdd551fe3c50f28b9adcWink Saville                return NOT_HANDLED;
1501fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            }
1502fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        }
1503fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1504fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        @Override
1505bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        protected void onHalting() {
1506fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            synchronized (mThisSm) {
1507fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                mThisSm.notifyAll();
1508fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            }
1509fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        }
1510fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1511fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        private StateMachineUnhandledMessage mThisSm;
1512fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        private int mUnhandledMessageCount;
1513fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        private S1 mS1 = new S1();
1514fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    }
1515fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1516fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    @SmallTest
1517fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    public void testStateMachineUnhandledMessage() throws Exception {
1518fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1519efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        StateMachineUnhandledMessage sm = new StateMachineUnhandledMessage("smUnhandledMessage");
1520fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        sm.start();
1521efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        if (sm.isDbg()) tlog("testStateMachineUnhandledMessage E");
1522fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1523fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        synchronized (sm) {
1524fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            // Send 2 messages
1525fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            for (int i = 1; i <= 2; i++) {
152691fbd56757751a7aca8ef2b4d936e587509e6eefWink Saville                sm.sendMessage(i);
1527fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            }
1528fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1529fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            try {
1530fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                // wait for the messages to be handled
1531fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                sm.wait();
1532fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            } catch (InterruptedException e) {
1533efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                tloge("testStateMachineUnhandledMessage: exception while waiting "
1534fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                        + e.getMessage());
1535fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            }
1536fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        }
1537fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1538efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        assertEquals(2, sm.getLogRecSize());
1539fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        assertEquals(2, sm.mUnhandledMessageCount);
1540fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1541efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        if (sm.isDbg()) tlog("testStateMachineUnhandledMessage X");
1542fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    }
1543fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1544fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    /**
1545fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville     * Test state machines sharing the same thread/looper. Multiple instances
1546fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville     * of the same state machine will be created. They will all share the
1547fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville     * same thread and thus each can update <code>sharedCounter</code> which
1548fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville     * will be used to notify testStateMachineSharedThread that the test is
1549fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville     * complete.
1550fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville     */
155164c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville    class StateMachineSharedThread extends StateMachine {
1552f0f566ec4607376583e59964a6a8a6dcb0265c20Wink Saville        StateMachineSharedThread(String name, Looper looper, int maxCount) {
1553f0f566ec4607376583e59964a6a8a6dcb0265c20Wink Saville            super(name, looper);
1554fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            mMaxCount = maxCount;
1555fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            setDbg(DBG);
1556fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1557fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            // Setup state machine with 1 state
1558fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            addState(mS1);
1559fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1560fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            // Set the initial state
1561fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            setInitialState(mS1);
1562fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        }
1563fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
156464c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville        class S1 extends State {
156564c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            @Override
156664c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            public boolean processMessage(Message message) {
1567fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                if (message.what == TEST_CMD_4) {
1568fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                    transitionToHaltingState();
1569fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                }
1570a4f3bec29c85ef9e0d07fdd551fe3c50f28b9adcWink Saville                return HANDLED;
1571fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            }
1572fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        }
1573fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1574fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        @Override
1575bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        protected void onHalting() {
1576fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            // Update the shared counter, which is OK since all state
1577fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            // machines are using the same thread.
1578fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            sharedCounter += 1;
1579fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            if (sharedCounter == mMaxCount) {
1580fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                synchronized (waitObject) {
1581fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                    waitObject.notifyAll();
1582fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                }
1583fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            }
1584fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        }
1585fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1586fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        private int mMaxCount;
1587fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        private S1 mS1 = new S1();
1588fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    }
1589fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    private static int sharedCounter = 0;
1590fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    private static Object waitObject = new Object();
1591fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1592f76c56bcaa9df1d1afa711177f813dc63f399795Brett Chabot    @MediumTest
1593fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    public void testStateMachineSharedThread() throws Exception {
1594efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        if (DBG) tlog("testStateMachineSharedThread E");
1595fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1596fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        // Create and start the handler thread
1597fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        HandlerThread smThread = new HandlerThread("testStateMachineSharedThread");
1598fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        smThread.start();
1599fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1600fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        // Create the state machines
1601fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        StateMachineSharedThread sms[] = new StateMachineSharedThread[10];
1602fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        for (int i = 0; i < sms.length; i++) {
1603efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville            sms[i] = new StateMachineSharedThread("smSharedThread",
1604efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                        smThread.getLooper(), sms.length);
1605fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            sms[i].start();
1606fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        }
1607fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1608fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        synchronized (waitObject) {
1609fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            // Send messages to each of the state machines
1610fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            for (StateMachineSharedThread sm : sms) {
1611fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                for (int i = 1; i <= 4; i++) {
161291fbd56757751a7aca8ef2b4d936e587509e6eefWink Saville                    sm.sendMessage(i);
1613fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                }
1614fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            }
1615fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1616fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            // Wait for the last state machine to notify its done
1617fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            try {
1618fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                waitObject.wait();
1619fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            } catch (InterruptedException e) {
1620efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                tloge("testStateMachineSharedThread: exception while waiting "
1621fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                        + e.getMessage());
1622fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            }
1623fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        }
1624fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1625fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        for (StateMachineSharedThread sm : sms) {
1626efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville            assertEquals(4, sm.getLogRecCount());
1627efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville            for (int i = 0; i < sm.getLogRecSize(); i++) {
1628bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville                LogRec lr = sm.getLogRec(i);
1629bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville                assertEquals(i+1, lr.getWhat());
1630bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville                assertEquals(sm.mS1, lr.getState());
1631bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville                assertEquals(sm.mS1, lr.getOriginalState());
1632fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            }
1633fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        }
1634fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1635efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        if (DBG) tlog("testStateMachineSharedThread X");
1636efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville    }
1637efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville
1638efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville    static class Hsm1 extends StateMachine {
1639efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        private static final String HSM1_TAG = "hsm1";
1640efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville
1641efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        public static final int CMD_1 = 1;
1642efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        public static final int CMD_2 = 2;
1643efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        public static final int CMD_3 = 3;
1644efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        public static final int CMD_4 = 4;
1645efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        public static final int CMD_5 = 5;
1646efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville
1647efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        public static Hsm1 makeHsm1() {
1648efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville            Log.d(HSM1_TAG, "makeHsm1 E");
1649efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville            Hsm1 sm = new Hsm1(HSM1_TAG);
1650efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville            sm.start();
1651efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville            Log.d(HSM1_TAG, "makeHsm1 X");
1652efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville            return sm;
1653efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        }
1654efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville
1655efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        Hsm1(String name) {
1656efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville            super(name);
1657efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville            log("ctor E");
1658efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville
1659efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville            // Add states, use indentation to show hierarchy
1660efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville            addState(mP1);
1661efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                addState(mS1, mP1);
1662efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                addState(mS2, mP1);
1663efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville            addState(mP2);
1664efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville
1665efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville            // Set the initial state
1666efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville            setInitialState(mS1);
1667efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville            log("ctor X");
1668efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        }
1669efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville
1670efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        class P1 extends State {
1671efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville            @Override
1672efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville            public void enter() {
1673efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                log("P1.enter");
1674efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville            }
1675efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville            @Override
1676efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville            public void exit() {
1677efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                log("P1.exit");
1678efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville            }
1679efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville            @Override
1680efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville            public boolean processMessage(Message message) {
1681efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                boolean retVal;
1682efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                log("P1.processMessage what=" + message.what);
1683efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                switch(message.what) {
1684efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                case CMD_2:
1685efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                    // CMD_2 will arrive in mS2 before CMD_3
1686efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                    sendMessage(CMD_3);
1687efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                    deferMessage(message);
1688efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                    transitionTo(mS2);
1689efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                    retVal = true;
1690efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                    break;
1691efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                default:
1692efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                    // Any message we don't understand in this state invokes unhandledMessage
1693efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                    retVal = false;
1694efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                    break;
1695efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                }
1696efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                return retVal;
1697efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville            }
1698efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        }
1699efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville
1700efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        class S1 extends State {
1701efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville            @Override
1702efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville            public void enter() {
1703efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                log("S1.enter");
1704efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville            }
1705efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville            @Override
1706efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville            public void exit() {
1707efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                log("S1.exit");
1708efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville            }
1709efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville            @Override
1710efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville            public boolean processMessage(Message message) {
1711efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                log("S1.processMessage what=" + message.what);
1712efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                if (message.what == CMD_1) {
1713efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                    // Transition to ourself to show that enter/exit is called
1714efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                    transitionTo(mS1);
1715efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                    return HANDLED;
1716efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                } else {
1717efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                    // Let parent process all other messages
1718efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                    return NOT_HANDLED;
1719efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                }
1720efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville            }
1721efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        }
1722efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville
1723efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        class S2 extends State {
1724efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville            @Override
1725efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville            public void enter() {
1726efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                log("S2.enter");
1727efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville            }
1728efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville            @Override
1729efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville            public void exit() {
1730efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                log("S2.exit");
1731efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville            }
1732efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville            @Override
1733efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville            public boolean processMessage(Message message) {
1734efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                boolean retVal;
1735efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                log("S2.processMessage what=" + message.what);
1736efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                switch(message.what) {
1737efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                case(CMD_2):
1738efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                    sendMessage(CMD_4);
1739efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                    retVal = true;
1740efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                    break;
1741efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                case(CMD_3):
1742efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                    deferMessage(message);
1743efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                    transitionTo(mP2);
1744efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                    retVal = true;
1745efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                    break;
1746efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                default:
1747efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                    retVal = false;
1748efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                    break;
1749efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                }
1750efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                return retVal;
1751efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville            }
1752efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        }
1753efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville
1754efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        class P2 extends State {
1755efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville            @Override
1756efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville            public void enter() {
1757efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                log("P2.enter");
1758efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                sendMessage(CMD_5);
1759efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville            }
1760efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville            @Override
1761efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville            public void exit() {
1762efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                log("P2.exit");
1763efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville            }
1764efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville            @Override
1765efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville            public boolean processMessage(Message message) {
1766efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                log("P2.processMessage what=" + message.what);
1767efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                switch(message.what) {
1768efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                case(CMD_3):
1769efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                    break;
1770efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                case(CMD_4):
1771efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                    break;
1772efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                case(CMD_5):
1773efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                    transitionToHaltingState();
1774efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                    break;
1775efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                }
1776efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                return HANDLED;
1777efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville            }
1778efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        }
1779efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville
1780efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        @Override
1781efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        protected void onHalting() {
1782efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville            log("halting");
1783efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville            synchronized (this) {
1784efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                this.notifyAll();
1785efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville            }
1786efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        }
1787efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville
1788efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        P1 mP1 = new P1();
1789efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        S1 mS1 = new S1();
1790efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        S2 mS2 = new S2();
1791efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        P2 mP2 = new P2();
1792fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    }
1793fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1794f76c56bcaa9df1d1afa711177f813dc63f399795Brett Chabot    @MediumTest
1795fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    public void testHsm1() throws Exception {
1796efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        if (DBG) tlog("testHsm1 E");
1797fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1798fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        Hsm1 sm = Hsm1.makeHsm1();
1799fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1800fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        // Send messages
180191fbd56757751a7aca8ef2b4d936e587509e6eefWink Saville        sm.sendMessage(Hsm1.CMD_1);
180291fbd56757751a7aca8ef2b4d936e587509e6eefWink Saville        sm.sendMessage(Hsm1.CMD_2);
1803fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1804fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        synchronized (sm) {
1805fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            // Wait for the last state machine to notify its done
1806fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            try {
1807fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                sm.wait();
1808fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            } catch (InterruptedException e) {
1809efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                tloge("testHsm1: exception while waiting " + e.getMessage());
1810fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            }
1811fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        }
1812fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1813efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        dumpLogRecs(sm);
1814efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville
1815bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(7, sm.getLogRecCount());
1816efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville
1817bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        LogRec lr = sm.getLogRec(0);
1818bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(Hsm1.CMD_1, lr.getWhat());
1819bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(sm.mS1, lr.getState());
1820bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(sm.mS1, lr.getOriginalState());
1821fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1822bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        lr = sm.getLogRec(1);
1823bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(Hsm1.CMD_2, lr.getWhat());
1824bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(sm.mP1, lr.getState());
1825bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(sm.mS1, lr.getOriginalState());
1826fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1827bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        lr = sm.getLogRec(2);
1828bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(Hsm1.CMD_2, lr.getWhat());
1829bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(sm.mS2, lr.getState());
1830bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(sm.mS2, lr.getOriginalState());
1831fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1832bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        lr = sm.getLogRec(3);
1833bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(Hsm1.CMD_3, lr.getWhat());
1834bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(sm.mS2, lr.getState());
1835bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(sm.mS2, lr.getOriginalState());
1836fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1837bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        lr = sm.getLogRec(4);
1838bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(Hsm1.CMD_3, lr.getWhat());
1839bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(sm.mP2, lr.getState());
1840bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(sm.mP2, lr.getOriginalState());
1841fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1842bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        lr = sm.getLogRec(5);
1843bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(Hsm1.CMD_4, lr.getWhat());
1844bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(sm.mP2, lr.getState());
1845bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(sm.mP2, lr.getOriginalState());
1846fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1847bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        lr = sm.getLogRec(6);
1848bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(Hsm1.CMD_5, lr.getWhat());
1849bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(sm.mP2, lr.getState());
1850bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        assertEquals(sm.mP2, lr.getOriginalState());
1851fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1852efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        if (DBG) tlog("testStateMachineSharedThread X");
1853fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    }
1854fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1855efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville    private void tlog(String s) {
1856efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        Log.d(TAG, s);
1857fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    }
1858fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1859efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville    private void tloge(String s) {
1860efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        Log.e(TAG, s);
1861fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    }
1862fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville}
1863