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
17fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Savillepackage com.android.internal.util;
18fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
19fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Savilleimport android.os.Handler;
20fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Savilleimport android.os.HandlerThread;
21fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Savilleimport android.os.Looper;
22fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Savilleimport android.os.Message;
23583eaaa57c51b28bf14da2a5cc94a2e6091cccf5Wink Savilleimport android.text.TextUtils;
24fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Savilleimport android.util.Log;
25fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
26583eaaa57c51b28bf14da2a5cc94a2e6091cccf5Wink Savilleimport java.io.FileDescriptor;
27583eaaa57c51b28bf14da2a5cc94a2e6091cccf5Wink Savilleimport java.io.PrintWriter;
2854b1b1a07ad3edd1df060889aad453aa0e1cc79aWink Savilleimport java.io.StringWriter;
29fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Savilleimport java.util.ArrayList;
30583eaaa57c51b28bf14da2a5cc94a2e6091cccf5Wink Savilleimport java.util.Calendar;
31efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Savilleimport java.util.Collection;
32fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Savilleimport java.util.HashMap;
33d3059487abd526b91b912f70939c1c6994eecf52Wink Savilleimport java.util.Vector;
34fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
35fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville/**
36fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville * {@hide}
37fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville *
3864c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville * <p>The state machine defined here is a hierarchical state machine which processes messages
3933c54e3365d621fcc5b9f7564f18b33dc1e300dfWink Saville * and can have states arranged hierarchically.</p>
4058c73c3f76c231cf128041aefadd4b6a6bcefac2Wink Saville *
4164c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville * <p>A state is a <code>State</code> object and must implement
4233c54e3365d621fcc5b9f7564f18b33dc1e300dfWink Saville * <code>processMessage</code> and optionally <code>enter/exit/getName</code>.
43fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville * The enter/exit methods are equivalent to the construction and destruction
44fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville * in Object Oriented programming and are used to perform initialization and
45fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville * cleanup of the state respectively. The <code>getName</code> method returns the
46fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville * name of the state the default implementation returns the class name it may be
47fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville * desirable to have this return the name of the state instance name instead.
4833c54e3365d621fcc5b9f7564f18b33dc1e300dfWink Saville * In particular if a particular state class has multiple instances.</p>
49fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville *
5033c54e3365d621fcc5b9f7564f18b33dc1e300dfWink Saville * <p>When a state machine is created <code>addState</code> is used to build the
51fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville * hierarchy and <code>setInitialState</code> is used to identify which of these
52fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville * is the initial state. After construction the programmer calls <code>start</code>
53cea056f5894543819898a0e62f98dc7870b27758Wink Saville * which initializes and starts the state machine. The first action the StateMachine
54cea056f5894543819898a0e62f98dc7870b27758Wink Saville * is to the invoke <code>enter</code> for all of the initial state's hierarchy,
55cea056f5894543819898a0e62f98dc7870b27758Wink Saville * starting at its eldest parent. The calls to enter will be done in the context
56cea056f5894543819898a0e62f98dc7870b27758Wink Saville * of the StateMachines Handler not in the context of the call to start and they
57cea056f5894543819898a0e62f98dc7870b27758Wink Saville * will be invoked before any messages are processed. For example, given the simple
58cea056f5894543819898a0e62f98dc7870b27758Wink Saville * state machine below mP1.enter will be invoked and then mS1.enter. Finally,
59cea056f5894543819898a0e62f98dc7870b27758Wink Saville * messages sent to the state machine will be processed by the current state,
60cea056f5894543819898a0e62f98dc7870b27758Wink Saville * in our simple state machine below that would initially be mS1.processMessage.</p>
61fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville<code>
62fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        mP1
63fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville       /   \
64fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville      mS2   mS1 ----> initial state
65fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville</code>
6633c54e3365d621fcc5b9f7564f18b33dc1e300dfWink Saville * <p>After the state machine is created and started, messages are sent to a state
67a4f3bec29c85ef9e0d07fdd551fe3c50f28b9adcWink Saville * machine using <code>sendMessage</code> and the messages are created using
68fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville * <code>obtainMessage</code>. When the state machine receives a message the
69fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville * current state's <code>processMessage</code> is invoked. In the above example
70fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville * mS1.processMessage will be invoked first. The state may use <code>transitionTo</code>
7133c54e3365d621fcc5b9f7564f18b33dc1e300dfWink Saville * to change the current state to a new state</p>
72fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville *
7333c54e3365d621fcc5b9f7564f18b33dc1e300dfWink Saville * <p>Each state in the state machine may have a zero or one parent states and if
74fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville * a child state is unable to handle a message it may have the message processed
75a4f3bec29c85ef9e0d07fdd551fe3c50f28b9adcWink Saville * by its parent by returning false or NOT_HANDLED. If a message is never processed
76a4f3bec29c85ef9e0d07fdd551fe3c50f28b9adcWink Saville * <code>unhandledMessage</code> will be invoked to give one last chance for the state machine
7733c54e3365d621fcc5b9f7564f18b33dc1e300dfWink Saville * to process the message.</p>
78fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville *
7933c54e3365d621fcc5b9f7564f18b33dc1e300dfWink Saville * <p>When all processing is completed a state machine may choose to call
80fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville * <code>transitionToHaltingState</code>. When the current <code>processingMessage</code>
81fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville * returns the state machine will transfer to an internal <code>HaltingState</code>
82fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville * and invoke <code>halting</code>. Any message subsequently received by the state
8333c54e3365d621fcc5b9f7564f18b33dc1e300dfWink Saville * machine will cause <code>haltedProcessMessage</code> to be invoked.</p>
84fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville *
85bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville * <p>If it is desirable to completely stop the state machine call <code>quit</code> or
86efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville * <code>quitNow</code>. These will call <code>exit</code> of the current state and its parents,
87efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville * call <code>onQuiting</code> and then exit Thread/Loopers.</p>
881b8b98b3db5dcf0b01d1a632aafea076cc91f5a4Wink Saville *
8964c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville * <p>In addition to <code>processMessage</code> each <code>State</code> has
9033c54e3365d621fcc5b9f7564f18b33dc1e300dfWink Saville * an <code>enter</code> method and <code>exit</exit> method which may be overridden.</p>
91fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville *
9233c54e3365d621fcc5b9f7564f18b33dc1e300dfWink Saville * <p>Since the states are arranged in a hierarchy transitioning to a new state
93fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville * causes current states to be exited and new states to be entered. To determine
94fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville * the list of states to be entered/exited the common parent closest to
95fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville * the current state is found. We then exit from the current state and its
96fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville * parent's up to but not including the common parent state and then enter all
97fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville * of the new states below the common parent down to the destination state.
98fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville * If there is no common parent all states are exited and then the new states
9933c54e3365d621fcc5b9f7564f18b33dc1e300dfWink Saville * are entered.</p>
100fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville *
10133c54e3365d621fcc5b9f7564f18b33dc1e300dfWink Saville * <p>Two other methods that states can use are <code>deferMessage</code> and
102fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville * <code>sendMessageAtFrontOfQueue</code>. The <code>sendMessageAtFrontOfQueue</code> sends
103fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville * a message but places it on the front of the queue rather than the back. The
104fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville * <code>deferMessage</code> causes the message to be saved on a list until a
105fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville * transition is made to a new state. At which time all of the deferred messages
106fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville * will be put on the front of the state machine queue with the oldest message
107fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville * at the front. These will then be processed by the new current state before
108fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville * any other messages that are on the queue or might be added later. Both of
10933c54e3365d621fcc5b9f7564f18b33dc1e300dfWink Saville * these are protected and may only be invoked from within a state machine.</p>
110fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville *
11133c54e3365d621fcc5b9f7564f18b33dc1e300dfWink Saville * <p>To illustrate some of these properties we'll use state machine with an 8
11233c54e3365d621fcc5b9f7564f18b33dc1e300dfWink Saville * state hierarchy:</p>
113fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville<code>
114fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville          mP0
115fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville         /   \
116fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        mP1   mS0
117fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville       /   \
118fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville      mS2   mS1
119fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville     /  \    \
120fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    mS3  mS4  mS5  ---> initial state
121fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville</code>
12233c54e3365d621fcc5b9f7564f18b33dc1e300dfWink Saville * <p>After starting mS5 the list of active states is mP0, mP1, mS1 and mS5.
123fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville * So the order of calling processMessage when a message is received is mS5,
124a4f3bec29c85ef9e0d07fdd551fe3c50f28b9adcWink Saville * mS1, mP1, mP0 assuming each processMessage indicates it can't handle this
12533c54e3365d621fcc5b9f7564f18b33dc1e300dfWink Saville * message by returning false or NOT_HANDLED.</p>
126fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville *
12733c54e3365d621fcc5b9f7564f18b33dc1e300dfWink Saville * <p>Now assume mS5.processMessage receives a message it can handle, and during
128a4f3bec29c85ef9e0d07fdd551fe3c50f28b9adcWink Saville * the handling determines the machine should change states. It could call
129a4f3bec29c85ef9e0d07fdd551fe3c50f28b9adcWink Saville * transitionTo(mS4) and return true or HANDLED. Immediately after returning from
130fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville * processMessage the state machine runtime will find the common parent,
131fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville * which is mP1. It will then call mS5.exit, mS1.exit, mS2.enter and then
132fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville * mS4.enter. The new list of active states is mP0, mP1, mS2 and mS4. So
13333c54e3365d621fcc5b9f7564f18b33dc1e300dfWink Saville * when the next message is received mS4.processMessage will be invoked.</p>
134fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville *
13564c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville * <p>Now for some concrete examples, here is the canonical HelloWorld as a state machine.
13633c54e3365d621fcc5b9f7564f18b33dc1e300dfWink Saville * It responds with "Hello World" being printed to the log for every message.</p>
137fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville<code>
13864c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Savilleclass HelloWorld extends StateMachine {
13964c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville    HelloWorld(String name) {
140fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        super(name);
141fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        addState(mState1);
142fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        setInitialState(mState1);
143fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    }
144fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
145fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    public static HelloWorld makeHelloWorld() {
146fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        HelloWorld hw = new HelloWorld("hw");
147fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        hw.start();
148fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        return hw;
149fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    }
150fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
15164c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville    class State1 extends State {
1520b6232da8995d6fa556d55ea2067dab3c1180919Joe Onorato        &#64;Override public boolean processMessage(Message message) {
15358c73c3f76c231cf128041aefadd4b6a6bcefac2Wink Saville            log("Hello World");
154a4f3bec29c85ef9e0d07fdd551fe3c50f28b9adcWink Saville            return HANDLED;
155fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        }
156fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    }
157fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    State1 mState1 = new State1();
158fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville}
159fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
160fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Savillevoid testHelloWorld() {
161fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    HelloWorld hw = makeHelloWorld();
162fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    hw.sendMessage(hw.obtainMessage());
163fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville}
164fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville</code>
16533c54e3365d621fcc5b9f7564f18b33dc1e300dfWink Saville * <p>A more interesting state machine is one with four states
16633c54e3365d621fcc5b9f7564f18b33dc1e300dfWink Saville * with two independent parent states.</p>
167fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville<code>
168fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        mP1      mP2
169fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville       /   \
170fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville      mS2   mS1
171fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville</code>
17233c54e3365d621fcc5b9f7564f18b33dc1e300dfWink Saville * <p>Here is a description of this state machine using pseudo code.</p>
17333c54e3365d621fcc5b9f7564f18b33dc1e300dfWink Saville <code>
17433c54e3365d621fcc5b9f7564f18b33dc1e300dfWink Savillestate mP1 {
17533c54e3365d621fcc5b9f7564f18b33dc1e300dfWink Saville     enter { log("mP1.enter"); }
17633c54e3365d621fcc5b9f7564f18b33dc1e300dfWink Saville     exit { log("mP1.exit");  }
17733c54e3365d621fcc5b9f7564f18b33dc1e300dfWink Saville     on msg {
17833c54e3365d621fcc5b9f7564f18b33dc1e300dfWink Saville         CMD_2 {
17933c54e3365d621fcc5b9f7564f18b33dc1e300dfWink Saville             send(CMD_3);
18033c54e3365d621fcc5b9f7564f18b33dc1e300dfWink Saville             defer(msg);
18133c54e3365d621fcc5b9f7564f18b33dc1e300dfWink Saville             transitonTo(mS2);
18233c54e3365d621fcc5b9f7564f18b33dc1e300dfWink Saville             return HANDLED;
18333c54e3365d621fcc5b9f7564f18b33dc1e300dfWink Saville         }
18433c54e3365d621fcc5b9f7564f18b33dc1e300dfWink Saville         return NOT_HANDLED;
18533c54e3365d621fcc5b9f7564f18b33dc1e300dfWink Saville     }
18633c54e3365d621fcc5b9f7564f18b33dc1e300dfWink Saville}
18733c54e3365d621fcc5b9f7564f18b33dc1e300dfWink Saville
18833c54e3365d621fcc5b9f7564f18b33dc1e300dfWink SavilleINITIAL
18933c54e3365d621fcc5b9f7564f18b33dc1e300dfWink Savillestate mS1 parent mP1 {
19033c54e3365d621fcc5b9f7564f18b33dc1e300dfWink Saville     enter { log("mS1.enter"); }
19133c54e3365d621fcc5b9f7564f18b33dc1e300dfWink Saville     exit  { log("mS1.exit");  }
19233c54e3365d621fcc5b9f7564f18b33dc1e300dfWink Saville     on msg {
19333c54e3365d621fcc5b9f7564f18b33dc1e300dfWink Saville         CMD_1 {
19433c54e3365d621fcc5b9f7564f18b33dc1e300dfWink Saville             transitionTo(mS1);
19533c54e3365d621fcc5b9f7564f18b33dc1e300dfWink Saville             return HANDLED;
19633c54e3365d621fcc5b9f7564f18b33dc1e300dfWink Saville         }
19733c54e3365d621fcc5b9f7564f18b33dc1e300dfWink Saville         return NOT_HANDLED;
19833c54e3365d621fcc5b9f7564f18b33dc1e300dfWink Saville     }
19933c54e3365d621fcc5b9f7564f18b33dc1e300dfWink Saville}
20033c54e3365d621fcc5b9f7564f18b33dc1e300dfWink Saville
20133c54e3365d621fcc5b9f7564f18b33dc1e300dfWink Savillestate mS2 parent mP1 {
20233c54e3365d621fcc5b9f7564f18b33dc1e300dfWink Saville     enter { log("mS2.enter"); }
20333c54e3365d621fcc5b9f7564f18b33dc1e300dfWink Saville     exit  { log("mS2.exit");  }
20433c54e3365d621fcc5b9f7564f18b33dc1e300dfWink Saville     on msg {
20533c54e3365d621fcc5b9f7564f18b33dc1e300dfWink Saville         CMD_2 {
20633c54e3365d621fcc5b9f7564f18b33dc1e300dfWink Saville             send(CMD_4);
20733c54e3365d621fcc5b9f7564f18b33dc1e300dfWink Saville             return HANDLED;
20833c54e3365d621fcc5b9f7564f18b33dc1e300dfWink Saville         }
20933c54e3365d621fcc5b9f7564f18b33dc1e300dfWink Saville         CMD_3 {
21033c54e3365d621fcc5b9f7564f18b33dc1e300dfWink Saville             defer(msg);
21133c54e3365d621fcc5b9f7564f18b33dc1e300dfWink Saville             transitionTo(mP2);
21233c54e3365d621fcc5b9f7564f18b33dc1e300dfWink Saville             return HANDLED;
21333c54e3365d621fcc5b9f7564f18b33dc1e300dfWink Saville         }
21433c54e3365d621fcc5b9f7564f18b33dc1e300dfWink Saville         return NOT_HANDLED;
21533c54e3365d621fcc5b9f7564f18b33dc1e300dfWink Saville     }
21633c54e3365d621fcc5b9f7564f18b33dc1e300dfWink Saville}
21733c54e3365d621fcc5b9f7564f18b33dc1e300dfWink Saville
21833c54e3365d621fcc5b9f7564f18b33dc1e300dfWink Savillestate mP2 {
21933c54e3365d621fcc5b9f7564f18b33dc1e300dfWink Saville     enter {
22033c54e3365d621fcc5b9f7564f18b33dc1e300dfWink Saville         log("mP2.enter");
22133c54e3365d621fcc5b9f7564f18b33dc1e300dfWink Saville         send(CMD_5);
22233c54e3365d621fcc5b9f7564f18b33dc1e300dfWink Saville     }
22333c54e3365d621fcc5b9f7564f18b33dc1e300dfWink Saville     exit { log("mP2.exit"); }
22433c54e3365d621fcc5b9f7564f18b33dc1e300dfWink Saville     on msg {
22533c54e3365d621fcc5b9f7564f18b33dc1e300dfWink Saville         CMD_3, CMD_4 { return HANDLED; }
22633c54e3365d621fcc5b9f7564f18b33dc1e300dfWink Saville         CMD_5 {
22733c54e3365d621fcc5b9f7564f18b33dc1e300dfWink Saville             transitionTo(HaltingState);
22833c54e3365d621fcc5b9f7564f18b33dc1e300dfWink Saville             return HANDLED;
22933c54e3365d621fcc5b9f7564f18b33dc1e300dfWink Saville         }
23033c54e3365d621fcc5b9f7564f18b33dc1e300dfWink Saville         return NOT_HANDLED;
23133c54e3365d621fcc5b9f7564f18b33dc1e300dfWink Saville     }
23233c54e3365d621fcc5b9f7564f18b33dc1e300dfWink Saville}
23333c54e3365d621fcc5b9f7564f18b33dc1e300dfWink Saville</code>
23464c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville * <p>The implementation is below and also in StateMachineTest:</p>
235fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville<code>
23664c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Savilleclass Hsm1 extends StateMachine {
237fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    public static final int CMD_1 = 1;
238fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    public static final int CMD_2 = 2;
239fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    public static final int CMD_3 = 3;
240fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    public static final int CMD_4 = 4;
241fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    public static final int CMD_5 = 5;
242fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
243fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    public static Hsm1 makeHsm1() {
24458c73c3f76c231cf128041aefadd4b6a6bcefac2Wink Saville        log("makeHsm1 E");
245fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        Hsm1 sm = new Hsm1("hsm1");
246fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        sm.start();
24758c73c3f76c231cf128041aefadd4b6a6bcefac2Wink Saville        log("makeHsm1 X");
248fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        return sm;
249fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    }
250fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
251fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    Hsm1(String name) {
252fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        super(name);
25358c73c3f76c231cf128041aefadd4b6a6bcefac2Wink Saville        log("ctor E");
254fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
255fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        // Add states, use indentation to show hierarchy
256fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        addState(mP1);
257fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            addState(mS1, mP1);
258fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            addState(mS2, mP1);
259fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        addState(mP2);
260fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
261fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        // Set the initial state
262fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        setInitialState(mS1);
26358c73c3f76c231cf128041aefadd4b6a6bcefac2Wink Saville        log("ctor X");
264fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    }
265fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
26664c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville    class P1 extends State {
2670b6232da8995d6fa556d55ea2067dab3c1180919Joe Onorato        &#64;Override public void enter() {
26858c73c3f76c231cf128041aefadd4b6a6bcefac2Wink Saville            log("mP1.enter");
269fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        }
2700b6232da8995d6fa556d55ea2067dab3c1180919Joe Onorato        &#64;Override public boolean processMessage(Message message) {
271fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            boolean retVal;
27258c73c3f76c231cf128041aefadd4b6a6bcefac2Wink Saville            log("mP1.processMessage what=" + message.what);
273fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            switch(message.what) {
274fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            case CMD_2:
275fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                // CMD_2 will arrive in mS2 before CMD_3
276fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                sendMessage(obtainMessage(CMD_3));
277fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                deferMessage(message);
278fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                transitionTo(mS2);
279a4f3bec29c85ef9e0d07fdd551fe3c50f28b9adcWink Saville                retVal = HANDLED;
280fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                break;
281fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            default:
282fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                // Any message we don't understand in this state invokes unhandledMessage
283a4f3bec29c85ef9e0d07fdd551fe3c50f28b9adcWink Saville                retVal = NOT_HANDLED;
284fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                break;
285fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            }
286fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            return retVal;
287fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        }
2880b6232da8995d6fa556d55ea2067dab3c1180919Joe Onorato        &#64;Override public void exit() {
28958c73c3f76c231cf128041aefadd4b6a6bcefac2Wink Saville            log("mP1.exit");
290fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        }
291fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    }
292fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
29364c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville    class S1 extends State {
2940b6232da8995d6fa556d55ea2067dab3c1180919Joe Onorato        &#64;Override public void enter() {
29558c73c3f76c231cf128041aefadd4b6a6bcefac2Wink Saville            log("mS1.enter");
296fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        }
2970b6232da8995d6fa556d55ea2067dab3c1180919Joe Onorato        &#64;Override public boolean processMessage(Message message) {
29858c73c3f76c231cf128041aefadd4b6a6bcefac2Wink Saville            log("S1.processMessage what=" + message.what);
299fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            if (message.what == CMD_1) {
300fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                // Transition to ourself to show that enter/exit is called
301fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                transitionTo(mS1);
302a4f3bec29c85ef9e0d07fdd551fe3c50f28b9adcWink Saville                return HANDLED;
303fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            } else {
304fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                // Let parent process all other messages
305a4f3bec29c85ef9e0d07fdd551fe3c50f28b9adcWink Saville                return NOT_HANDLED;
306fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            }
307fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        }
3080b6232da8995d6fa556d55ea2067dab3c1180919Joe Onorato        &#64;Override public void exit() {
30958c73c3f76c231cf128041aefadd4b6a6bcefac2Wink Saville            log("mS1.exit");
310fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        }
311fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    }
312fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
31364c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville    class S2 extends State {
3140b6232da8995d6fa556d55ea2067dab3c1180919Joe Onorato        &#64;Override public void enter() {
31558c73c3f76c231cf128041aefadd4b6a6bcefac2Wink Saville            log("mS2.enter");
316fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        }
3170b6232da8995d6fa556d55ea2067dab3c1180919Joe Onorato        &#64;Override public boolean processMessage(Message message) {
318fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            boolean retVal;
31958c73c3f76c231cf128041aefadd4b6a6bcefac2Wink Saville            log("mS2.processMessage what=" + message.what);
320fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            switch(message.what) {
321fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            case(CMD_2):
322fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                sendMessage(obtainMessage(CMD_4));
323a4f3bec29c85ef9e0d07fdd551fe3c50f28b9adcWink Saville                retVal = HANDLED;
324fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                break;
325fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            case(CMD_3):
326fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                deferMessage(message);
327fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                transitionTo(mP2);
328a4f3bec29c85ef9e0d07fdd551fe3c50f28b9adcWink Saville                retVal = HANDLED;
329fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                break;
330fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            default:
331a4f3bec29c85ef9e0d07fdd551fe3c50f28b9adcWink Saville                retVal = NOT_HANDLED;
332fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                break;
333fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            }
334fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            return retVal;
335fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        }
3360b6232da8995d6fa556d55ea2067dab3c1180919Joe Onorato        &#64;Override public void exit() {
33758c73c3f76c231cf128041aefadd4b6a6bcefac2Wink Saville            log("mS2.exit");
338fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        }
339fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    }
340fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
34164c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville    class P2 extends State {
3420b6232da8995d6fa556d55ea2067dab3c1180919Joe Onorato        &#64;Override public void enter() {
34358c73c3f76c231cf128041aefadd4b6a6bcefac2Wink Saville            log("mP2.enter");
344fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            sendMessage(obtainMessage(CMD_5));
345fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        }
3460b6232da8995d6fa556d55ea2067dab3c1180919Joe Onorato        &#64;Override public boolean processMessage(Message message) {
34758c73c3f76c231cf128041aefadd4b6a6bcefac2Wink Saville            log("P2.processMessage what=" + message.what);
348fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            switch(message.what) {
349fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            case(CMD_3):
350fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                break;
351fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            case(CMD_4):
352fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                break;
353fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            case(CMD_5):
354fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                transitionToHaltingState();
355fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                break;
356fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            }
357a4f3bec29c85ef9e0d07fdd551fe3c50f28b9adcWink Saville            return HANDLED;
358fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        }
3590b6232da8995d6fa556d55ea2067dab3c1180919Joe Onorato        &#64;Override public void exit() {
36058c73c3f76c231cf128041aefadd4b6a6bcefac2Wink Saville            log("mP2.exit");
361fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        }
362fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    }
363fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
3640b6232da8995d6fa556d55ea2067dab3c1180919Joe Onorato    &#64;Override
365bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville    void onHalting() {
36658c73c3f76c231cf128041aefadd4b6a6bcefac2Wink Saville        log("halting");
367fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        synchronized (this) {
368fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            this.notifyAll();
369fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        }
370fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    }
371fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
372fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    P1 mP1 = new P1();
373fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    S1 mS1 = new S1();
374fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    S2 mS2 = new S2();
375fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    P2 mP2 = new P2();
376fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville}
377fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville</code>
37833c54e3365d621fcc5b9f7564f18b33dc1e300dfWink Saville * <p>If this is executed by sending two messages CMD_1 and CMD_2
37933c54e3365d621fcc5b9f7564f18b33dc1e300dfWink Saville * (Note the synchronize is only needed because we use hsm.wait())</p>
38033c54e3365d621fcc5b9f7564f18b33dc1e300dfWink Saville<code>
38133c54e3365d621fcc5b9f7564f18b33dc1e300dfWink SavilleHsm1 hsm = makeHsm1();
38233c54e3365d621fcc5b9f7564f18b33dc1e300dfWink Savillesynchronize(hsm) {
38333c54e3365d621fcc5b9f7564f18b33dc1e300dfWink Saville     hsm.sendMessage(obtainMessage(hsm.CMD_1));
38433c54e3365d621fcc5b9f7564f18b33dc1e300dfWink Saville     hsm.sendMessage(obtainMessage(hsm.CMD_2));
38533c54e3365d621fcc5b9f7564f18b33dc1e300dfWink Saville     try {
38633c54e3365d621fcc5b9f7564f18b33dc1e300dfWink Saville          // wait for the messages to be handled
38733c54e3365d621fcc5b9f7564f18b33dc1e300dfWink Saville          hsm.wait();
38833c54e3365d621fcc5b9f7564f18b33dc1e300dfWink Saville     } catch (InterruptedException e) {
38958c73c3f76c231cf128041aefadd4b6a6bcefac2Wink Saville          loge("exception while waiting " + e.getMessage());
39033c54e3365d621fcc5b9f7564f18b33dc1e300dfWink Saville     }
39133c54e3365d621fcc5b9f7564f18b33dc1e300dfWink Saville}
39233c54e3365d621fcc5b9f7564f18b33dc1e300dfWink Saville</code>
39333c54e3365d621fcc5b9f7564f18b33dc1e300dfWink Saville * <p>The output is:</p>
39433c54e3365d621fcc5b9f7564f18b33dc1e300dfWink Saville<code>
39533c54e3365d621fcc5b9f7564f18b33dc1e300dfWink SavilleD/hsm1    ( 1999): makeHsm1 E
39633c54e3365d621fcc5b9f7564f18b33dc1e300dfWink SavilleD/hsm1    ( 1999): ctor E
39733c54e3365d621fcc5b9f7564f18b33dc1e300dfWink SavilleD/hsm1    ( 1999): ctor X
39833c54e3365d621fcc5b9f7564f18b33dc1e300dfWink SavilleD/hsm1    ( 1999): mP1.enter
39933c54e3365d621fcc5b9f7564f18b33dc1e300dfWink SavilleD/hsm1    ( 1999): mS1.enter
40033c54e3365d621fcc5b9f7564f18b33dc1e300dfWink SavilleD/hsm1    ( 1999): makeHsm1 X
40133c54e3365d621fcc5b9f7564f18b33dc1e300dfWink SavilleD/hsm1    ( 1999): mS1.processMessage what=1
40233c54e3365d621fcc5b9f7564f18b33dc1e300dfWink SavilleD/hsm1    ( 1999): mS1.exit
40333c54e3365d621fcc5b9f7564f18b33dc1e300dfWink SavilleD/hsm1    ( 1999): mS1.enter
40433c54e3365d621fcc5b9f7564f18b33dc1e300dfWink SavilleD/hsm1    ( 1999): mS1.processMessage what=2
40533c54e3365d621fcc5b9f7564f18b33dc1e300dfWink SavilleD/hsm1    ( 1999): mP1.processMessage what=2
40633c54e3365d621fcc5b9f7564f18b33dc1e300dfWink SavilleD/hsm1    ( 1999): mS1.exit
40733c54e3365d621fcc5b9f7564f18b33dc1e300dfWink SavilleD/hsm1    ( 1999): mS2.enter
40833c54e3365d621fcc5b9f7564f18b33dc1e300dfWink SavilleD/hsm1    ( 1999): mS2.processMessage what=2
40933c54e3365d621fcc5b9f7564f18b33dc1e300dfWink SavilleD/hsm1    ( 1999): mS2.processMessage what=3
41033c54e3365d621fcc5b9f7564f18b33dc1e300dfWink SavilleD/hsm1    ( 1999): mS2.exit
41133c54e3365d621fcc5b9f7564f18b33dc1e300dfWink SavilleD/hsm1    ( 1999): mP1.exit
41233c54e3365d621fcc5b9f7564f18b33dc1e300dfWink SavilleD/hsm1    ( 1999): mP2.enter
41333c54e3365d621fcc5b9f7564f18b33dc1e300dfWink SavilleD/hsm1    ( 1999): mP2.processMessage what=3
41433c54e3365d621fcc5b9f7564f18b33dc1e300dfWink SavilleD/hsm1    ( 1999): mP2.processMessage what=4
41533c54e3365d621fcc5b9f7564f18b33dc1e300dfWink SavilleD/hsm1    ( 1999): mP2.processMessage what=5
41633c54e3365d621fcc5b9f7564f18b33dc1e300dfWink SavilleD/hsm1    ( 1999): mP2.exit
41733c54e3365d621fcc5b9f7564f18b33dc1e300dfWink SavilleD/hsm1    ( 1999): halting
41833c54e3365d621fcc5b9f7564f18b33dc1e300dfWink Saville</code>
419fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville */
42064c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Savillepublic class StateMachine {
42158c73c3f76c231cf128041aefadd4b6a6bcefac2Wink Saville    // Name of the state machine and used as logging tag
422fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    private String mName;
423fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
424a4f3bec29c85ef9e0d07fdd551fe3c50f28b9adcWink Saville    /** Message.what value when quitting */
425bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville    private static final int SM_QUIT_CMD = -1;
4261b8b98b3db5dcf0b01d1a632aafea076cc91f5a4Wink Saville
427a4f3bec29c85ef9e0d07fdd551fe3c50f28b9adcWink Saville    /** Message.what value when initializing */
428bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville    private static final int SM_INIT_CMD = -2;
429a4f3bec29c85ef9e0d07fdd551fe3c50f28b9adcWink Saville
430a4f3bec29c85ef9e0d07fdd551fe3c50f28b9adcWink Saville    /**
431a4f3bec29c85ef9e0d07fdd551fe3c50f28b9adcWink Saville     * Convenience constant that maybe returned by processMessage
432a4f3bec29c85ef9e0d07fdd551fe3c50f28b9adcWink Saville     * to indicate the the message was processed and is not to be
433a4f3bec29c85ef9e0d07fdd551fe3c50f28b9adcWink Saville     * processed by parent states
434a4f3bec29c85ef9e0d07fdd551fe3c50f28b9adcWink Saville     */
435a4f3bec29c85ef9e0d07fdd551fe3c50f28b9adcWink Saville    public static final boolean HANDLED = true;
436a4f3bec29c85ef9e0d07fdd551fe3c50f28b9adcWink Saville
437a4f3bec29c85ef9e0d07fdd551fe3c50f28b9adcWink Saville    /**
438a4f3bec29c85ef9e0d07fdd551fe3c50f28b9adcWink Saville     * Convenience constant that maybe returned by processMessage
439a4f3bec29c85ef9e0d07fdd551fe3c50f28b9adcWink Saville     * to indicate the the message was NOT processed and is to be
440a4f3bec29c85ef9e0d07fdd551fe3c50f28b9adcWink Saville     * processed by parent states
441a4f3bec29c85ef9e0d07fdd551fe3c50f28b9adcWink Saville     */
442a4f3bec29c85ef9e0d07fdd551fe3c50f28b9adcWink Saville    public static final boolean NOT_HANDLED = false;
443a4f3bec29c85ef9e0d07fdd551fe3c50f28b9adcWink Saville
444d3059487abd526b91b912f70939c1c6994eecf52Wink Saville    /**
445bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville     * StateMachine logging record.
446d3059487abd526b91b912f70939c1c6994eecf52Wink Saville     * {@hide}
447d3059487abd526b91b912f70939c1c6994eecf52Wink Saville     */
448bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville    public static class LogRec {
449efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        private StateMachine mSm;
450583eaaa57c51b28bf14da2a5cc94a2e6091cccf5Wink Saville        private long mTime;
451583eaaa57c51b28bf14da2a5cc94a2e6091cccf5Wink Saville        private int mWhat;
452583eaaa57c51b28bf14da2a5cc94a2e6091cccf5Wink Saville        private String mInfo;
453efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        private IState mState;
454efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        private IState mOrgState;
455efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        private IState mDstState;
456d3059487abd526b91b912f70939c1c6994eecf52Wink Saville
457d3059487abd526b91b912f70939c1c6994eecf52Wink Saville        /**
458d3059487abd526b91b912f70939c1c6994eecf52Wink Saville         * Constructor
459bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville         *
460bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville         * @param msg
461ef8da9fe0b70fdbbb54bb0645ac66f75f58f31b8Irfan Sheriff         * @param state the state which handled the message
462d3059487abd526b91b912f70939c1c6994eecf52Wink Saville         * @param orgState is the first state the received the message but
463d3059487abd526b91b912f70939c1c6994eecf52Wink Saville         * did not processes the message.
464ef8da9fe0b70fdbbb54bb0645ac66f75f58f31b8Irfan Sheriff         * @param transToState is the state that was transitioned to after the message was
465ef8da9fe0b70fdbbb54bb0645ac66f75f58f31b8Irfan Sheriff         * processed.
466d3059487abd526b91b912f70939c1c6994eecf52Wink Saville         */
467efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        LogRec(StateMachine sm, Message msg, String info, IState state, IState orgState,
468efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                IState transToState) {
469efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville            update(sm, msg, info, state, orgState, transToState);
470d3059487abd526b91b912f70939c1c6994eecf52Wink Saville        }
471d3059487abd526b91b912f70939c1c6994eecf52Wink Saville
472d3059487abd526b91b912f70939c1c6994eecf52Wink Saville        /**
473d3059487abd526b91b912f70939c1c6994eecf52Wink Saville         * Update the information in the record.
474d3059487abd526b91b912f70939c1c6994eecf52Wink Saville         * @param state that handled the message
475efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville         * @param orgState is the first state the received the message
476efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville         * @param dstState is the state that was the transition target when logging
477d3059487abd526b91b912f70939c1c6994eecf52Wink Saville         */
478efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        public void update(StateMachine sm, Message msg, String info, IState state, IState orgState,
479efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                IState dstState) {
480efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville            mSm = sm;
481583eaaa57c51b28bf14da2a5cc94a2e6091cccf5Wink Saville            mTime = System.currentTimeMillis();
482bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville            mWhat = (msg != null) ? msg.what : 0;
483583eaaa57c51b28bf14da2a5cc94a2e6091cccf5Wink Saville            mInfo = info;
484583eaaa57c51b28bf14da2a5cc94a2e6091cccf5Wink Saville            mState = state;
485583eaaa57c51b28bf14da2a5cc94a2e6091cccf5Wink Saville            mOrgState = orgState;
486efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville            mDstState = dstState;
487583eaaa57c51b28bf14da2a5cc94a2e6091cccf5Wink Saville        }
488583eaaa57c51b28bf14da2a5cc94a2e6091cccf5Wink Saville
489583eaaa57c51b28bf14da2a5cc94a2e6091cccf5Wink Saville        /**
490583eaaa57c51b28bf14da2a5cc94a2e6091cccf5Wink Saville         * @return time stamp
491583eaaa57c51b28bf14da2a5cc94a2e6091cccf5Wink Saville         */
492583eaaa57c51b28bf14da2a5cc94a2e6091cccf5Wink Saville        public long getTime() {
493583eaaa57c51b28bf14da2a5cc94a2e6091cccf5Wink Saville            return mTime;
494583eaaa57c51b28bf14da2a5cc94a2e6091cccf5Wink Saville        }
495583eaaa57c51b28bf14da2a5cc94a2e6091cccf5Wink Saville
496583eaaa57c51b28bf14da2a5cc94a2e6091cccf5Wink Saville        /**
497583eaaa57c51b28bf14da2a5cc94a2e6091cccf5Wink Saville         * @return msg.what
498583eaaa57c51b28bf14da2a5cc94a2e6091cccf5Wink Saville         */
499583eaaa57c51b28bf14da2a5cc94a2e6091cccf5Wink Saville        public long getWhat() {
500583eaaa57c51b28bf14da2a5cc94a2e6091cccf5Wink Saville            return mWhat;
501d3059487abd526b91b912f70939c1c6994eecf52Wink Saville        }
502d3059487abd526b91b912f70939c1c6994eecf52Wink Saville
503d3059487abd526b91b912f70939c1c6994eecf52Wink Saville        /**
504d3059487abd526b91b912f70939c1c6994eecf52Wink Saville         * @return the command that was executing
505d3059487abd526b91b912f70939c1c6994eecf52Wink Saville         */
506583eaaa57c51b28bf14da2a5cc94a2e6091cccf5Wink Saville        public String getInfo() {
507583eaaa57c51b28bf14da2a5cc94a2e6091cccf5Wink Saville            return mInfo;
508d3059487abd526b91b912f70939c1c6994eecf52Wink Saville        }
509d3059487abd526b91b912f70939c1c6994eecf52Wink Saville
510d3059487abd526b91b912f70939c1c6994eecf52Wink Saville        /**
511d3059487abd526b91b912f70939c1c6994eecf52Wink Saville         * @return the state that handled this message
512d3059487abd526b91b912f70939c1c6994eecf52Wink Saville         */
513efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        public IState getState() {
514583eaaa57c51b28bf14da2a5cc94a2e6091cccf5Wink Saville            return mState;
515d3059487abd526b91b912f70939c1c6994eecf52Wink Saville        }
516d3059487abd526b91b912f70939c1c6994eecf52Wink Saville
517d3059487abd526b91b912f70939c1c6994eecf52Wink Saville        /**
518efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville         * @return the state destination state if a transition is occurring or null if none.
519d3059487abd526b91b912f70939c1c6994eecf52Wink Saville         */
520efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        public IState getDestState() {
521efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville            return mDstState;
522d3059487abd526b91b912f70939c1c6994eecf52Wink Saville        }
523d3059487abd526b91b912f70939c1c6994eecf52Wink Saville
524d3059487abd526b91b912f70939c1c6994eecf52Wink Saville        /**
525efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville         * @return the original state that received the message.
526d3059487abd526b91b912f70939c1c6994eecf52Wink Saville         */
527efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        public IState getOriginalState() {
528efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville            return mOrgState;
529efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        }
530efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville
531efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        @Override
532efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        public String toString() {
533d3059487abd526b91b912f70939c1c6994eecf52Wink Saville            StringBuilder sb = new StringBuilder();
534583eaaa57c51b28bf14da2a5cc94a2e6091cccf5Wink Saville            sb.append("time=");
535583eaaa57c51b28bf14da2a5cc94a2e6091cccf5Wink Saville            Calendar c = Calendar.getInstance();
536583eaaa57c51b28bf14da2a5cc94a2e6091cccf5Wink Saville            c.setTimeInMillis(mTime);
537583eaaa57c51b28bf14da2a5cc94a2e6091cccf5Wink Saville            sb.append(String.format("%tm-%td %tH:%tM:%tS.%tL", c, c, c, c, c, c));
538ef8da9fe0b70fdbbb54bb0645ac66f75f58f31b8Irfan Sheriff            sb.append(" processed=");
539583eaaa57c51b28bf14da2a5cc94a2e6091cccf5Wink Saville            sb.append(mState == null ? "<null>" : mState.getName());
540ef8da9fe0b70fdbbb54bb0645ac66f75f58f31b8Irfan Sheriff            sb.append(" org=");
541583eaaa57c51b28bf14da2a5cc94a2e6091cccf5Wink Saville            sb.append(mOrgState == null ? "<null>" : mOrgState.getName());
542ef8da9fe0b70fdbbb54bb0645ac66f75f58f31b8Irfan Sheriff            sb.append(" dest=");
543efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville            sb.append(mDstState == null ? "<null>" : mDstState.getName());
544583eaaa57c51b28bf14da2a5cc94a2e6091cccf5Wink Saville            sb.append(" what=");
545efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville            String what = mSm != null ? mSm.getWhatToString(mWhat) : "";
546bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville            if (TextUtils.isEmpty(what)) {
547bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville                sb.append(mWhat);
548bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville                sb.append("(0x");
549bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville                sb.append(Integer.toHexString(mWhat));
550bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville                sb.append(")");
551bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville            } else {
552bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville                sb.append(what);
553bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville            }
554ff4fcdb98c9575642c48f1daeafff4b257769e81Wink Saville            if (!TextUtils.isEmpty(mInfo)) {
555583eaaa57c51b28bf14da2a5cc94a2e6091cccf5Wink Saville                sb.append(" ");
556583eaaa57c51b28bf14da2a5cc94a2e6091cccf5Wink Saville                sb.append(mInfo);
557d3059487abd526b91b912f70939c1c6994eecf52Wink Saville            }
558583eaaa57c51b28bf14da2a5cc94a2e6091cccf5Wink Saville            return sb.toString();
559d3059487abd526b91b912f70939c1c6994eecf52Wink Saville        }
560d3059487abd526b91b912f70939c1c6994eecf52Wink Saville    }
561d3059487abd526b91b912f70939c1c6994eecf52Wink Saville
562d3059487abd526b91b912f70939c1c6994eecf52Wink Saville    /**
563bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville     * A list of log records including messages recently processed by the state machine.
564d3059487abd526b91b912f70939c1c6994eecf52Wink Saville     *
565bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville     * The class maintains a list of log records including messages
566d3059487abd526b91b912f70939c1c6994eecf52Wink Saville     * recently processed. The list is finite and may be set in the
567d3059487abd526b91b912f70939c1c6994eecf52Wink Saville     * constructor or by calling setSize. The public interface also
568bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville     * includes size which returns the number of recent records,
569bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville     * count which is the number of records processed since the
570bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville     * the last setSize, get which returns a record and
571bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville     * add which adds a record.
572d3059487abd526b91b912f70939c1c6994eecf52Wink Saville     */
573bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville    private static class LogRecords {
574d3059487abd526b91b912f70939c1c6994eecf52Wink Saville
575d3059487abd526b91b912f70939c1c6994eecf52Wink Saville        private static final int DEFAULT_SIZE = 20;
576d3059487abd526b91b912f70939c1c6994eecf52Wink Saville
577ef8da9fe0b70fdbbb54bb0645ac66f75f58f31b8Irfan Sheriff        private Vector<LogRec> mLogRecVector = new Vector<LogRec>();
578d3059487abd526b91b912f70939c1c6994eecf52Wink Saville        private int mMaxSize = DEFAULT_SIZE;
579d3059487abd526b91b912f70939c1c6994eecf52Wink Saville        private int mOldestIndex = 0;
580d3059487abd526b91b912f70939c1c6994eecf52Wink Saville        private int mCount = 0;
581ef8da9fe0b70fdbbb54bb0645ac66f75f58f31b8Irfan Sheriff        private boolean mLogOnlyTransitions = false;
582d3059487abd526b91b912f70939c1c6994eecf52Wink Saville
583d3059487abd526b91b912f70939c1c6994eecf52Wink Saville        /**
584583eaaa57c51b28bf14da2a5cc94a2e6091cccf5Wink Saville         * private constructor use add
585d3059487abd526b91b912f70939c1c6994eecf52Wink Saville         */
586bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        private LogRecords() {
587d3059487abd526b91b912f70939c1c6994eecf52Wink Saville        }
588d3059487abd526b91b912f70939c1c6994eecf52Wink Saville
589d3059487abd526b91b912f70939c1c6994eecf52Wink Saville        /**
590bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville         * Set size of messages to maintain and clears all current records.
591d3059487abd526b91b912f70939c1c6994eecf52Wink Saville         *
592bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville         * @param maxSize number of records to maintain at anyone time.
593d3059487abd526b91b912f70939c1c6994eecf52Wink Saville        */
594bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        synchronized void setSize(int maxSize) {
595d3059487abd526b91b912f70939c1c6994eecf52Wink Saville            mMaxSize = maxSize;
596d3059487abd526b91b912f70939c1c6994eecf52Wink Saville            mCount = 0;
597ef8da9fe0b70fdbbb54bb0645ac66f75f58f31b8Irfan Sheriff            mLogRecVector.clear();
598ef8da9fe0b70fdbbb54bb0645ac66f75f58f31b8Irfan Sheriff        }
599ef8da9fe0b70fdbbb54bb0645ac66f75f58f31b8Irfan Sheriff
600ef8da9fe0b70fdbbb54bb0645ac66f75f58f31b8Irfan Sheriff        synchronized void setLogOnlyTransitions(boolean enable) {
601ef8da9fe0b70fdbbb54bb0645ac66f75f58f31b8Irfan Sheriff            mLogOnlyTransitions = enable;
602ef8da9fe0b70fdbbb54bb0645ac66f75f58f31b8Irfan Sheriff        }
603ef8da9fe0b70fdbbb54bb0645ac66f75f58f31b8Irfan Sheriff
604ef8da9fe0b70fdbbb54bb0645ac66f75f58f31b8Irfan Sheriff        synchronized boolean logOnlyTransitions() {
605ef8da9fe0b70fdbbb54bb0645ac66f75f58f31b8Irfan Sheriff            return mLogOnlyTransitions;
606d3059487abd526b91b912f70939c1c6994eecf52Wink Saville        }
607d3059487abd526b91b912f70939c1c6994eecf52Wink Saville
608d3059487abd526b91b912f70939c1c6994eecf52Wink Saville        /**
609bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville         * @return the number of recent records.
610d3059487abd526b91b912f70939c1c6994eecf52Wink Saville         */
611bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        synchronized int size() {
612ef8da9fe0b70fdbbb54bb0645ac66f75f58f31b8Irfan Sheriff            return mLogRecVector.size();
613d3059487abd526b91b912f70939c1c6994eecf52Wink Saville        }
614d3059487abd526b91b912f70939c1c6994eecf52Wink Saville
615d3059487abd526b91b912f70939c1c6994eecf52Wink Saville        /**
616bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville         * @return the total number of records processed since size was set.
617d3059487abd526b91b912f70939c1c6994eecf52Wink Saville         */
618bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        synchronized int count() {
619d3059487abd526b91b912f70939c1c6994eecf52Wink Saville            return mCount;
620d3059487abd526b91b912f70939c1c6994eecf52Wink Saville        }
621d3059487abd526b91b912f70939c1c6994eecf52Wink Saville
622d3059487abd526b91b912f70939c1c6994eecf52Wink Saville        /**
623bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville         * Clear the list of records.
6246f9a61651e7949a5d63a4b44314d435c0105a51fJaikumar Ganesh         */
625bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        synchronized void cleanup() {
626ef8da9fe0b70fdbbb54bb0645ac66f75f58f31b8Irfan Sheriff            mLogRecVector.clear();
6276f9a61651e7949a5d63a4b44314d435c0105a51fJaikumar Ganesh        }
6286f9a61651e7949a5d63a4b44314d435c0105a51fJaikumar Ganesh
6296f9a61651e7949a5d63a4b44314d435c0105a51fJaikumar Ganesh        /**
630d3059487abd526b91b912f70939c1c6994eecf52Wink Saville         * @return the information on a particular record. 0 is the oldest
631d3059487abd526b91b912f70939c1c6994eecf52Wink Saville         * record and size()-1 is the newest record. If the index is to
632d3059487abd526b91b912f70939c1c6994eecf52Wink Saville         * large null is returned.
633d3059487abd526b91b912f70939c1c6994eecf52Wink Saville         */
634bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        synchronized LogRec get(int index) {
635d3059487abd526b91b912f70939c1c6994eecf52Wink Saville            int nextIndex = mOldestIndex + index;
636d3059487abd526b91b912f70939c1c6994eecf52Wink Saville            if (nextIndex >= mMaxSize) {
637d3059487abd526b91b912f70939c1c6994eecf52Wink Saville                nextIndex -= mMaxSize;
638d3059487abd526b91b912f70939c1c6994eecf52Wink Saville            }
639d3059487abd526b91b912f70939c1c6994eecf52Wink Saville            if (nextIndex >= size()) {
640d3059487abd526b91b912f70939c1c6994eecf52Wink Saville                return null;
641d3059487abd526b91b912f70939c1c6994eecf52Wink Saville            } else {
642ef8da9fe0b70fdbbb54bb0645ac66f75f58f31b8Irfan Sheriff                return mLogRecVector.get(nextIndex);
643d3059487abd526b91b912f70939c1c6994eecf52Wink Saville            }
644d3059487abd526b91b912f70939c1c6994eecf52Wink Saville        }
645d3059487abd526b91b912f70939c1c6994eecf52Wink Saville
646d3059487abd526b91b912f70939c1c6994eecf52Wink Saville        /**
647d3059487abd526b91b912f70939c1c6994eecf52Wink Saville         * Add a processed message.
648d3059487abd526b91b912f70939c1c6994eecf52Wink Saville         *
649583eaaa57c51b28bf14da2a5cc94a2e6091cccf5Wink Saville         * @param msg
650583eaaa57c51b28bf14da2a5cc94a2e6091cccf5Wink Saville         * @param messageInfo to be stored
651d3059487abd526b91b912f70939c1c6994eecf52Wink Saville         * @param state that handled the message
652d3059487abd526b91b912f70939c1c6994eecf52Wink Saville         * @param orgState is the first state the received the message but
653d3059487abd526b91b912f70939c1c6994eecf52Wink Saville         * did not processes the message.
654ef8da9fe0b70fdbbb54bb0645ac66f75f58f31b8Irfan Sheriff         * @param transToState is the state that was transitioned to after the message was
655ef8da9fe0b70fdbbb54bb0645ac66f75f58f31b8Irfan Sheriff         * processed.
656ef8da9fe0b70fdbbb54bb0645ac66f75f58f31b8Irfan Sheriff         *
657d3059487abd526b91b912f70939c1c6994eecf52Wink Saville         */
658efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        synchronized void add(StateMachine sm, Message msg, String messageInfo, IState state,
659ff4fcdb98c9575642c48f1daeafff4b257769e81Wink Saville                IState orgState, IState transToState) {
660d3059487abd526b91b912f70939c1c6994eecf52Wink Saville            mCount += 1;
661ef8da9fe0b70fdbbb54bb0645ac66f75f58f31b8Irfan Sheriff            if (mLogRecVector.size() < mMaxSize) {
662efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                mLogRecVector.add(new LogRec(sm, msg, messageInfo, state, orgState, transToState));
663d3059487abd526b91b912f70939c1c6994eecf52Wink Saville            } else {
664ef8da9fe0b70fdbbb54bb0645ac66f75f58f31b8Irfan Sheriff                LogRec pmi = mLogRecVector.get(mOldestIndex);
665d3059487abd526b91b912f70939c1c6994eecf52Wink Saville                mOldestIndex += 1;
666d3059487abd526b91b912f70939c1c6994eecf52Wink Saville                if (mOldestIndex >= mMaxSize) {
667d3059487abd526b91b912f70939c1c6994eecf52Wink Saville                    mOldestIndex = 0;
668d3059487abd526b91b912f70939c1c6994eecf52Wink Saville                }
669efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                pmi.update(sm, msg, messageInfo, state, orgState, transToState);
670d3059487abd526b91b912f70939c1c6994eecf52Wink Saville            }
671d3059487abd526b91b912f70939c1c6994eecf52Wink Saville        }
672d3059487abd526b91b912f70939c1c6994eecf52Wink Saville    }
673d3059487abd526b91b912f70939c1c6994eecf52Wink Saville
67464c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville    private static class SmHandler extends Handler {
675fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
67603812c7894bd51ffc27aece5933791e4a00d679bWink Saville        /** true if StateMachine has quit */
67703812c7894bd51ffc27aece5933791e4a00d679bWink Saville        private boolean mHasQuit = false;
67803812c7894bd51ffc27aece5933791e4a00d679bWink Saville
679fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        /** The debug flag */
680fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        private boolean mDbg = false;
681fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
682cea056f5894543819898a0e62f98dc7870b27758Wink Saville        /** The SmHandler object, identifies that message is internal */
683cea056f5894543819898a0e62f98dc7870b27758Wink Saville        private static final Object mSmHandlerObj = new Object();
6841b8b98b3db5dcf0b01d1a632aafea076cc91f5a4Wink Saville
685a4f3bec29c85ef9e0d07fdd551fe3c50f28b9adcWink Saville        /** The current message */
686a4f3bec29c85ef9e0d07fdd551fe3c50f28b9adcWink Saville        private Message mMsg;
687a4f3bec29c85ef9e0d07fdd551fe3c50f28b9adcWink Saville
688bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        /** A list of log records including messages this state machine has processed */
689bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        private LogRecords mLogRecords = new LogRecords();
690fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
691fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        /** true if construction of the state machine has not been completed */
692fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        private boolean mIsConstructionCompleted;
693fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
694fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        /** Stack used to manage the current hierarchy of states */
695fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        private StateInfo mStateStack[];
696fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
697fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        /** Top of mStateStack */
698fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        private int mStateStackTopIndex = -1;
699fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
700fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        /** A temporary stack used to manage the state stack */
701fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        private StateInfo mTempStateStack[];
702fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
703fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        /** The top of the mTempStateStack */
704fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        private int mTempStateStackCount;
705fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
706fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        /** State used when state machine is halted */
707fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        private HaltingState mHaltingState = new HaltingState();
708fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
7091b8b98b3db5dcf0b01d1a632aafea076cc91f5a4Wink Saville        /** State used when state machine is quitting */
7101b8b98b3db5dcf0b01d1a632aafea076cc91f5a4Wink Saville        private QuittingState mQuittingState = new QuittingState();
7111b8b98b3db5dcf0b01d1a632aafea076cc91f5a4Wink Saville
71264c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville        /** Reference to the StateMachine */
71364c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville        private StateMachine mSm;
714fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
715fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        /**
716fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville         * Information about a state.
717fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville         * Used to maintain the hierarchy.
718fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville         */
719fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        private class StateInfo {
720fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            /** The state */
72164c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            State state;
722fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
723fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            /** The parent of this state, null if there is no parent */
724fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            StateInfo parentStateInfo;
725fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
726fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            /** True when the state has been entered and on the stack */
727fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            boolean active;
728fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
729fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            /**
730fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville             * Convert StateInfo to string
731fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville             */
732fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            @Override
733fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            public String toString() {
734ff4fcdb98c9575642c48f1daeafff4b257769e81Wink Saville                return "state=" + state.getName() + ",active=" + active + ",parent="
735ff4fcdb98c9575642c48f1daeafff4b257769e81Wink Saville                        + ((parentStateInfo == null) ? "null" : parentStateInfo.state.getName());
736fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            }
737fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        }
738fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
739fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        /** The map of all of the states in the state machine */
740ff4fcdb98c9575642c48f1daeafff4b257769e81Wink Saville        private HashMap<State, StateInfo> mStateInfo = new HashMap<State, StateInfo>();
741fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
742fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        /** The initial state that will process the first message */
74364c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville        private State mInitialState;
744fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
745fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        /** The destination state when transitionTo has been invoked */
74664c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville        private State mDestState;
747fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
748fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        /** The list of deferred messages */
749fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        private ArrayList<Message> mDeferredMessages = new ArrayList<Message>();
750fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
751fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        /**
752fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville         * State entered when transitionToHaltingState is called.
753fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville         */
75464c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville        private class HaltingState extends State {
755fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            @Override
756fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            public boolean processMessage(Message msg) {
75764c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville                mSm.haltedProcessMessage(msg);
758fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                return true;
759fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            }
760fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        }
761fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
762fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        /**
7631b8b98b3db5dcf0b01d1a632aafea076cc91f5a4Wink Saville         * State entered when a valid quit message is handled.
7641b8b98b3db5dcf0b01d1a632aafea076cc91f5a4Wink Saville         */
76564c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville        private class QuittingState extends State {
7661b8b98b3db5dcf0b01d1a632aafea076cc91f5a4Wink Saville            @Override
7671b8b98b3db5dcf0b01d1a632aafea076cc91f5a4Wink Saville            public boolean processMessage(Message msg) {
768a4f3bec29c85ef9e0d07fdd551fe3c50f28b9adcWink Saville                return NOT_HANDLED;
7691b8b98b3db5dcf0b01d1a632aafea076cc91f5a4Wink Saville            }
7701b8b98b3db5dcf0b01d1a632aafea076cc91f5a4Wink Saville        }
7711b8b98b3db5dcf0b01d1a632aafea076cc91f5a4Wink Saville
7721b8b98b3db5dcf0b01d1a632aafea076cc91f5a4Wink Saville        /**
773fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville         * Handle messages sent to the state machine by calling
774fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville         * the current state's processMessage. It also handles
775fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville         * the enter/exit calls and placing any deferred messages
776fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville         * back onto the queue when transitioning to a new state.
777fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville         */
778fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        @Override
779fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        public final void handleMessage(Message msg) {
78003812c7894bd51ffc27aece5933791e4a00d679bWink Saville            if (!mHasQuit) {
78103812c7894bd51ffc27aece5933791e4a00d679bWink Saville                if (mDbg) mSm.log("handleMessage: E msg.what=" + msg.what);
78203812c7894bd51ffc27aece5933791e4a00d679bWink Saville
78303812c7894bd51ffc27aece5933791e4a00d679bWink Saville                /** Save the current message */
78403812c7894bd51ffc27aece5933791e4a00d679bWink Saville                mMsg = msg;
78503812c7894bd51ffc27aece5933791e4a00d679bWink Saville
78603812c7894bd51ffc27aece5933791e4a00d679bWink Saville                /** State that processed the message */
78703812c7894bd51ffc27aece5933791e4a00d679bWink Saville                State msgProcessedState = null;
78803812c7894bd51ffc27aece5933791e4a00d679bWink Saville                if (mIsConstructionCompleted) {
78903812c7894bd51ffc27aece5933791e4a00d679bWink Saville                    /** Normal path */
79003812c7894bd51ffc27aece5933791e4a00d679bWink Saville                    msgProcessedState = processMsg(msg);
79103812c7894bd51ffc27aece5933791e4a00d679bWink Saville                } else if (!mIsConstructionCompleted && (mMsg.what == SM_INIT_CMD)
79203812c7894bd51ffc27aece5933791e4a00d679bWink Saville                        && (mMsg.obj == mSmHandlerObj)) {
79303812c7894bd51ffc27aece5933791e4a00d679bWink Saville                    /** Initial one time path. */
79403812c7894bd51ffc27aece5933791e4a00d679bWink Saville                    mIsConstructionCompleted = true;
79503812c7894bd51ffc27aece5933791e4a00d679bWink Saville                    invokeEnterMethods(0);
79603812c7894bd51ffc27aece5933791e4a00d679bWink Saville                } else {
79703812c7894bd51ffc27aece5933791e4a00d679bWink Saville                    throw new RuntimeException("StateMachine.handleMessage: "
79803812c7894bd51ffc27aece5933791e4a00d679bWink Saville                            + "The start method not called, received msg: " + msg);
79903812c7894bd51ffc27aece5933791e4a00d679bWink Saville                }
80003812c7894bd51ffc27aece5933791e4a00d679bWink Saville                performTransitions(msgProcessedState, msg);
801fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
80203812c7894bd51ffc27aece5933791e4a00d679bWink Saville                // We need to check if mSm == null here as we could be quitting.
80303812c7894bd51ffc27aece5933791e4a00d679bWink Saville                if (mDbg && mSm != null) mSm.log("handleMessage: X");
80403812c7894bd51ffc27aece5933791e4a00d679bWink Saville            }
805e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville        }
806e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville
807e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville        /**
808e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville         * Do any transitions
809ef8da9fe0b70fdbbb54bb0645ac66f75f58f31b8Irfan Sheriff         * @param msgProcessedState is the state that processed the message
810e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville         */
811efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        private void performTransitions(State msgProcessedState, Message msg) {
812fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            /**
813fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville             * If transitionTo has been called, exit and then enter
814e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville             * the appropriate states. We loop on this to allow
815e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville             * enter and exit methods to use transitionTo.
816fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville             */
817ef8da9fe0b70fdbbb54bb0645ac66f75f58f31b8Irfan Sheriff            State orgState = mStateStack[mStateStackTopIndex].state;
818ef8da9fe0b70fdbbb54bb0645ac66f75f58f31b8Irfan Sheriff
819efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville            /**
820efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville             * Record whether message needs to be logged before we transition and
821efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville             * and we won't log special messages SM_INIT_CMD or SM_QUIT_CMD which
822efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville             * always set msg.obj to the handler.
823efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville             */
824f643069ad56763732a06ab601cea1272e4c1827aWink Saville            boolean recordLogMsg = mSm.recordLogRec(mMsg) && (msg.obj != mSmHandlerObj);
825ef8da9fe0b70fdbbb54bb0645ac66f75f58f31b8Irfan Sheriff
826efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville            if (mLogRecords.logOnlyTransitions()) {
827efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                /** Record only if there is a transition */
828efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                if (mDestState != null) {
829efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                    mLogRecords.add(mSm, mMsg, mSm.getLogRecString(mMsg), msgProcessedState,
830efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                            orgState, mDestState);
831efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                }
832efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville            } else if (recordLogMsg) {
833efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                /** Record message */
834ff4fcdb98c9575642c48f1daeafff4b257769e81Wink Saville                mLogRecords.add(mSm, mMsg, mSm.getLogRecString(mMsg), msgProcessedState, orgState,
835ff4fcdb98c9575642c48f1daeafff4b257769e81Wink Saville                        mDestState);
836efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville            }
837fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
838efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville            State destState = mDestState;
839efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville            if (destState != null) {
840fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                /**
841efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                 * Process the transitions including transitions in the enter/exit methods
842e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville                 */
843efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                while (true) {
844efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                    if (mDbg) mSm.log("handleMessage: new destination call exit/enter");
845e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville
846efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                    /**
847efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                     * Determine the states to exit and enter and return the
848efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                     * common ancestor state of the enter/exit states. Then
849efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                     * invoke the exit methods then the enter methods.
850efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                     */
851efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                    StateInfo commonStateInfo = setupTempStateStackWithStatesToEnter(destState);
852efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                    invokeExitMethods(commonStateInfo);
853efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                    int stateStackEnteringIndex = moveTempStateStackToStateStack();
854efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                    invokeEnterMethods(stateStackEnteringIndex);
855fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
856efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                    /**
857efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                     * Since we have transitioned to a new state we need to have
858efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                     * any deferred messages moved to the front of the message queue
859efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                     * so they will be processed before any other messages in the
860efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                     * message queue.
861efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                     */
862efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                    moveDeferredMessageAtFrontOfQueue();
863efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville
864efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                    if (destState != mDestState) {
865efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                        // A new mDestState so continue looping
866efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                        destState = mDestState;
867efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                    } else {
868efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                        // No change in mDestState so we're done
869efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                        break;
870efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                    }
871efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                }
872efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                mDestState = null;
873e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville            }
874fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
875e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville            /**
876e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville             * After processing all transitions check and
877e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville             * see if the last transition was to quit or halt.
878e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville             */
879e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville            if (destState != null) {
880e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville                if (destState == mQuittingState) {
881bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville                    /**
882bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville                     * Call onQuitting to let subclasses cleanup.
883bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville                     */
884bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville                    mSm.onQuitting();
8856f9a61651e7949a5d63a4b44314d435c0105a51fJaikumar Ganesh                    cleanupAfterQuitting();
886e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville                } else if (destState == mHaltingState) {
887e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville                    /**
888bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville                     * Call onHalting() if we've transitioned to the halting
889e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville                     * state. All subsequent messages will be processed in
890e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville                     * in the halting state which invokes haltedProcessMessage(msg);
891e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville                     */
892bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville                    mSm.onHalting();
893fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                }
894fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            }
895fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        }
896fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
897fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        /**
8986f9a61651e7949a5d63a4b44314d435c0105a51fJaikumar Ganesh         * Cleanup all the static variables and the looper after the SM has been quit.
8996f9a61651e7949a5d63a4b44314d435c0105a51fJaikumar Ganesh         */
9006f9a61651e7949a5d63a4b44314d435c0105a51fJaikumar Ganesh        private final void cleanupAfterQuitting() {
9016f9a61651e7949a5d63a4b44314d435c0105a51fJaikumar Ganesh            if (mSm.mSmThread != null) {
9026f9a61651e7949a5d63a4b44314d435c0105a51fJaikumar Ganesh                // If we made the thread then quit looper which stops the thread.
9036f9a61651e7949a5d63a4b44314d435c0105a51fJaikumar Ganesh                getLooper().quit();
9046f9a61651e7949a5d63a4b44314d435c0105a51fJaikumar Ganesh                mSm.mSmThread = null;
9056f9a61651e7949a5d63a4b44314d435c0105a51fJaikumar Ganesh            }
9066f9a61651e7949a5d63a4b44314d435c0105a51fJaikumar Ganesh
9076f9a61651e7949a5d63a4b44314d435c0105a51fJaikumar Ganesh            mSm.mSmHandler = null;
9086f9a61651e7949a5d63a4b44314d435c0105a51fJaikumar Ganesh            mSm = null;
9096f9a61651e7949a5d63a4b44314d435c0105a51fJaikumar Ganesh            mMsg = null;
910bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville            mLogRecords.cleanup();
9116f9a61651e7949a5d63a4b44314d435c0105a51fJaikumar Ganesh            mStateStack = null;
9126f9a61651e7949a5d63a4b44314d435c0105a51fJaikumar Ganesh            mTempStateStack = null;
9136f9a61651e7949a5d63a4b44314d435c0105a51fJaikumar Ganesh            mStateInfo.clear();
9146f9a61651e7949a5d63a4b44314d435c0105a51fJaikumar Ganesh            mInitialState = null;
9156f9a61651e7949a5d63a4b44314d435c0105a51fJaikumar Ganesh            mDestState = null;
9166f9a61651e7949a5d63a4b44314d435c0105a51fJaikumar Ganesh            mDeferredMessages.clear();
91703812c7894bd51ffc27aece5933791e4a00d679bWink Saville            mHasQuit = true;
9186f9a61651e7949a5d63a4b44314d435c0105a51fJaikumar Ganesh        }
9196f9a61651e7949a5d63a4b44314d435c0105a51fJaikumar Ganesh
9206f9a61651e7949a5d63a4b44314d435c0105a51fJaikumar Ganesh        /**
921fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville         * Complete the construction of the state machine.
922fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville         */
923fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        private final void completeConstruction() {
92458c73c3f76c231cf128041aefadd4b6a6bcefac2Wink Saville            if (mDbg) mSm.log("completeConstruction: E");
925fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
926fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            /**
927fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville             * Determine the maximum depth of the state hierarchy
928fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville             * so we can allocate the state stacks.
929fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville             */
930fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            int maxDepth = 0;
931fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            for (StateInfo si : mStateInfo.values()) {
932fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                int depth = 0;
933fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                for (StateInfo i = si; i != null; depth++) {
934fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                    i = i.parentStateInfo;
935fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                }
936fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                if (maxDepth < depth) {
937fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                    maxDepth = depth;
938fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                }
939fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            }
94058c73c3f76c231cf128041aefadd4b6a6bcefac2Wink Saville            if (mDbg) mSm.log("completeConstruction: maxDepth=" + maxDepth);
941fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
942fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            mStateStack = new StateInfo[maxDepth];
943fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            mTempStateStack = new StateInfo[maxDepth];
944fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            setupInitialStateStack();
945fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
946cea056f5894543819898a0e62f98dc7870b27758Wink Saville            /** Sending SM_INIT_CMD message to invoke enter methods asynchronously */
947cea056f5894543819898a0e62f98dc7870b27758Wink Saville            sendMessageAtFrontOfQueue(obtainMessage(SM_INIT_CMD, mSmHandlerObj));
948e7be6a85da5be32348f4e83ede195477a7ec1790Wink Saville
94958c73c3f76c231cf128041aefadd4b6a6bcefac2Wink Saville            if (mDbg) mSm.log("completeConstruction: X");
950fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        }
951fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
952fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        /**
953fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville         * Process the message. If the current state doesn't handle
954fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville         * it, call the states parent and so on. If it is never handled then
955fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville         * call the state machines unhandledMessage method.
956ef8da9fe0b70fdbbb54bb0645ac66f75f58f31b8Irfan Sheriff         * @return the state that processed the message
957fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville         */
958ef8da9fe0b70fdbbb54bb0645ac66f75f58f31b8Irfan Sheriff        private final State processMsg(Message msg) {
959fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            StateInfo curStateInfo = mStateStack[mStateStackTopIndex];
960fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            if (mDbg) {
96158c73c3f76c231cf128041aefadd4b6a6bcefac2Wink Saville                mSm.log("processMsg: " + curStateInfo.state.getName());
962fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            }
963bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville
964bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville            if (isQuit(msg)) {
965bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville                transitionTo(mQuittingState);
966bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville            } else {
967bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville                while (!curStateInfo.state.processMessage(msg)) {
968fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                    /**
969bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville                     * Not processed
970fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                     */
971bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville                    curStateInfo = curStateInfo.parentStateInfo;
972bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville                    if (curStateInfo == null) {
973bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville                        /**
974bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville                         * No parents left so it's not handled
975bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville                         */
976bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville                        mSm.unhandledMessage(msg);
977bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville                        break;
978bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville                    }
979bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville                    if (mDbg) {
98058c73c3f76c231cf128041aefadd4b6a6bcefac2Wink Saville                        mSm.log("processMsg: " + curStateInfo.state.getName());
9811b8b98b3db5dcf0b01d1a632aafea076cc91f5a4Wink Saville                    }
982fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                }
983ff4fcdb98c9575642c48f1daeafff4b257769e81Wink Saville            }
984ef8da9fe0b70fdbbb54bb0645ac66f75f58f31b8Irfan Sheriff            return (curStateInfo != null) ? curStateInfo.state : null;
985fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        }
986fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
987fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        /**
988fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville         * Call the exit method for each state from the top of stack
989fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville         * up to the common ancestor state.
990fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville         */
991fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        private final void invokeExitMethods(StateInfo commonStateInfo) {
992ff4fcdb98c9575642c48f1daeafff4b257769e81Wink Saville            while ((mStateStackTopIndex >= 0)
993ff4fcdb98c9575642c48f1daeafff4b257769e81Wink Saville                    && (mStateStack[mStateStackTopIndex] != commonStateInfo)) {
99464c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville                State curState = mStateStack[mStateStackTopIndex].state;
99558c73c3f76c231cf128041aefadd4b6a6bcefac2Wink Saville                if (mDbg) mSm.log("invokeExitMethods: " + curState.getName());
996fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                curState.exit();
997fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                mStateStack[mStateStackTopIndex].active = false;
998fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                mStateStackTopIndex -= 1;
999fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            }
1000fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        }
1001fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1002fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        /**
1003fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville         * Invoke the enter method starting at the entering index to top of state stack
1004fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville         */
1005fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        private final void invokeEnterMethods(int stateStackEnteringIndex) {
1006fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            for (int i = stateStackEnteringIndex; i <= mStateStackTopIndex; i++) {
100758c73c3f76c231cf128041aefadd4b6a6bcefac2Wink Saville                if (mDbg) mSm.log("invokeEnterMethods: " + mStateStack[i].state.getName());
1008fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                mStateStack[i].state.enter();
1009fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                mStateStack[i].active = true;
1010fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            }
1011fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        }
1012fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1013fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        /**
1014fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville         * Move the deferred message to the front of the message queue.
1015fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville         */
1016fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        private final void moveDeferredMessageAtFrontOfQueue() {
1017fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            /**
1018fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville             * The oldest messages on the deferred list must be at
1019fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville             * the front of the queue so start at the back, which
1020fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville             * as the most resent message and end with the oldest
1021fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville             * messages at the front of the queue.
1022fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville             */
1023ff4fcdb98c9575642c48f1daeafff4b257769e81Wink Saville            for (int i = mDeferredMessages.size() - 1; i >= 0; i--) {
1024fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                Message curMsg = mDeferredMessages.get(i);
102558c73c3f76c231cf128041aefadd4b6a6bcefac2Wink Saville                if (mDbg) mSm.log("moveDeferredMessageAtFrontOfQueue; what=" + curMsg.what);
1026fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                sendMessageAtFrontOfQueue(curMsg);
1027fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            }
1028fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            mDeferredMessages.clear();
1029fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        }
1030fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1031fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        /**
1032fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville         * Move the contents of the temporary stack to the state stack
1033fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville         * reversing the order of the items on the temporary stack as
1034fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville         * they are moved.
1035fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville         *
103664c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville         * @return index into mStateStack where entering needs to start
1037fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville         */
1038fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        private final int moveTempStateStackToStateStack() {
1039fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            int startingIndex = mStateStackTopIndex + 1;
1040fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            int i = mTempStateStackCount - 1;
1041fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            int j = startingIndex;
1042fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            while (i >= 0) {
104358c73c3f76c231cf128041aefadd4b6a6bcefac2Wink Saville                if (mDbg) mSm.log("moveTempStackToStateStack: i=" + i + ",j=" + j);
1044fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                mStateStack[j] = mTempStateStack[i];
1045fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                j += 1;
1046fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                i -= 1;
1047fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            }
1048fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1049fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            mStateStackTopIndex = j - 1;
1050fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            if (mDbg) {
1051ff4fcdb98c9575642c48f1daeafff4b257769e81Wink Saville                mSm.log("moveTempStackToStateStack: X mStateStackTop=" + mStateStackTopIndex
1052ff4fcdb98c9575642c48f1daeafff4b257769e81Wink Saville                        + ",startingIndex=" + startingIndex + ",Top="
1053ff4fcdb98c9575642c48f1daeafff4b257769e81Wink Saville                        + mStateStack[mStateStackTopIndex].state.getName());
1054fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            }
1055fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            return startingIndex;
1056fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        }
1057fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1058fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        /**
1059fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville         * Setup the mTempStateStack with the states we are going to enter.
1060fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville         *
1061fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville         * This is found by searching up the destState's ancestors for a
1062fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville         * state that is already active i.e. StateInfo.active == true.
1063fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville         * The destStae and all of its inactive parents will be on the
1064fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville         * TempStateStack as the list of states to enter.
1065fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville         *
1066fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville         * @return StateInfo of the common ancestor for the destState and
1067fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville         * current state or null if there is no common parent.
1068fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville         */
106964c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville        private final StateInfo setupTempStateStackWithStatesToEnter(State destState) {
1070fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            /**
1071fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville             * Search up the parent list of the destination state for an active
1072fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville             * state. Use a do while() loop as the destState must always be entered
1073fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville             * even if it is active. This can happen if we are exiting/entering
1074fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville             * the current state.
1075fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville             */
1076fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            mTempStateStackCount = 0;
1077fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            StateInfo curStateInfo = mStateInfo.get(destState);
1078fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            do {
1079fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                mTempStateStack[mTempStateStackCount++] = curStateInfo;
1080fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                curStateInfo = curStateInfo.parentStateInfo;
1081fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            } while ((curStateInfo != null) && !curStateInfo.active);
1082fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1083fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            if (mDbg) {
108458c73c3f76c231cf128041aefadd4b6a6bcefac2Wink Saville                mSm.log("setupTempStateStackWithStatesToEnter: X mTempStateStackCount="
1085ff4fcdb98c9575642c48f1daeafff4b257769e81Wink Saville                        + mTempStateStackCount + ",curStateInfo: " + curStateInfo);
1086fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            }
1087fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            return curStateInfo;
1088fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        }
1089fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1090fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        /**
1091fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville         * Initialize StateStack to mInitialState.
1092fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville         */
1093fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        private final void setupInitialStateStack() {
1094fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            if (mDbg) {
1095ff4fcdb98c9575642c48f1daeafff4b257769e81Wink Saville                mSm.log("setupInitialStateStack: E mInitialState=" + mInitialState.getName());
1096fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            }
1097fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1098fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            StateInfo curStateInfo = mStateInfo.get(mInitialState);
1099fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            for (mTempStateStackCount = 0; curStateInfo != null; mTempStateStackCount++) {
1100fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                mTempStateStack[mTempStateStackCount] = curStateInfo;
1101fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                curStateInfo = curStateInfo.parentStateInfo;
1102fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            }
1103fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1104fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            // Empty the StateStack
1105fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            mStateStackTopIndex = -1;
1106fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1107fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            moveTempStateStackToStateStack();
1108fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        }
1109fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1110fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        /**
1111a4f3bec29c85ef9e0d07fdd551fe3c50f28b9adcWink Saville         * @return current message
1112a4f3bec29c85ef9e0d07fdd551fe3c50f28b9adcWink Saville         */
1113a4f3bec29c85ef9e0d07fdd551fe3c50f28b9adcWink Saville        private final Message getCurrentMessage() {
1114a4f3bec29c85ef9e0d07fdd551fe3c50f28b9adcWink Saville            return mMsg;
1115a4f3bec29c85ef9e0d07fdd551fe3c50f28b9adcWink Saville        }
1116a4f3bec29c85ef9e0d07fdd551fe3c50f28b9adcWink Saville
1117a4f3bec29c85ef9e0d07fdd551fe3c50f28b9adcWink Saville        /**
1118fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville         * @return current state
1119fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville         */
112064c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville        private final IState getCurrentState() {
1121fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            return mStateStack[mStateStackTopIndex].state;
1122fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        }
1123fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1124fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        /**
1125fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville         * Add a new state to the state machine. Bottom up addition
1126fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville         * of states is allowed but the same state may only exist
1127fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville         * in one hierarchy.
1128fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville         *
1129fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville         * @param state the state to add
1130fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville         * @param parent the parent of state
1131fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville         * @return stateInfo for this state
1132fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville         */
113364c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville        private final StateInfo addState(State state, State parent) {
1134fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            if (mDbg) {
1135ff4fcdb98c9575642c48f1daeafff4b257769e81Wink Saville                mSm.log("addStateInternal: E state=" + state.getName() + ",parent="
1136ff4fcdb98c9575642c48f1daeafff4b257769e81Wink Saville                        + ((parent == null) ? "" : parent.getName()));
1137fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            }
1138fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            StateInfo parentStateInfo = null;
1139fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            if (parent != null) {
1140fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                parentStateInfo = mStateInfo.get(parent);
1141fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                if (parentStateInfo == null) {
1142fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                    // Recursively add our parent as it's not been added yet.
1143fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                    parentStateInfo = addState(parent, null);
1144fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                }
1145fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            }
1146fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            StateInfo stateInfo = mStateInfo.get(state);
1147fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            if (stateInfo == null) {
1148fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                stateInfo = new StateInfo();
1149fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville                mStateInfo.put(state, stateInfo);
1150fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            }
1151fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1152fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            // Validate that we aren't adding the same state in two different hierarchies.
1153ff4fcdb98c9575642c48f1daeafff4b257769e81Wink Saville            if ((stateInfo.parentStateInfo != null)
1154ff4fcdb98c9575642c48f1daeafff4b257769e81Wink Saville                    && (stateInfo.parentStateInfo != parentStateInfo)) {
1155ff4fcdb98c9575642c48f1daeafff4b257769e81Wink Saville                throw new RuntimeException("state already added");
1156fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            }
1157fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            stateInfo.state = state;
1158fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            stateInfo.parentStateInfo = parentStateInfo;
1159fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            stateInfo.active = false;
116058c73c3f76c231cf128041aefadd4b6a6bcefac2Wink Saville            if (mDbg) mSm.log("addStateInternal: X stateInfo: " + stateInfo);
1161fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            return stateInfo;
1162fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        }
1163fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1164fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        /**
1165fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville         * Constructor
1166fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville         *
1167fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville         * @param looper for dispatching messages
116864c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville         * @param sm the hierarchical state machine
1169fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville         */
117064c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville        private SmHandler(Looper looper, StateMachine sm) {
1171fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            super(looper);
117264c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            mSm = sm;
1173fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1174fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            addState(mHaltingState, null);
11751b8b98b3db5dcf0b01d1a632aafea076cc91f5a4Wink Saville            addState(mQuittingState, null);
1176fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        }
1177fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
117864c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville        /** @see StateMachine#setInitialState(State) */
117964c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville        private final void setInitialState(State initialState) {
118058c73c3f76c231cf128041aefadd4b6a6bcefac2Wink Saville            if (mDbg) mSm.log("setInitialState: initialState=" + initialState.getName());
1181fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            mInitialState = initialState;
1182fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        }
1183fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
118464c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville        /** @see StateMachine#transitionTo(IState) */
118564c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville        private final void transitionTo(IState destState) {
118664c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville            mDestState = (State) destState;
118758c73c3f76c231cf128041aefadd4b6a6bcefac2Wink Saville            if (mDbg) mSm.log("transitionTo: destState=" + mDestState.getName());
1188fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        }
1189fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
119064c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville        /** @see StateMachine#deferMessage(Message) */
1191fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        private final void deferMessage(Message msg) {
119258c73c3f76c231cf128041aefadd4b6a6bcefac2Wink Saville            if (mDbg) mSm.log("deferMessage: msg=" + msg.what);
1193fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1194fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            /* Copy the "msg" to "newMsg" as "msg" will be recycled */
1195fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            Message newMsg = obtainMessage();
1196fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            newMsg.copyFrom(msg);
1197fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1198fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            mDeferredMessages.add(newMsg);
1199fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        }
1200fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1201bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        /** @see StateMachine#quit() */
12021b8b98b3db5dcf0b01d1a632aafea076cc91f5a4Wink Saville        private final void quit() {
120358c73c3f76c231cf128041aefadd4b6a6bcefac2Wink Saville            if (mDbg) mSm.log("quit:");
1204cea056f5894543819898a0e62f98dc7870b27758Wink Saville            sendMessage(obtainMessage(SM_QUIT_CMD, mSmHandlerObj));
12051b8b98b3db5dcf0b01d1a632aafea076cc91f5a4Wink Saville        }
12061b8b98b3db5dcf0b01d1a632aafea076cc91f5a4Wink Saville
1207bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        /** @see StateMachine#quitNow() */
1208bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        private final void quitNow() {
120958c73c3f76c231cf128041aefadd4b6a6bcefac2Wink Saville            if (mDbg) mSm.log("quitNow:");
1210bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville            sendMessageAtFrontOfQueue(obtainMessage(SM_QUIT_CMD, mSmHandlerObj));
1211bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        }
1212bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville
121358c73c3f76c231cf128041aefadd4b6a6bcefac2Wink Saville        /** Validate that the message was sent by quit or quitNow. */
12141b8b98b3db5dcf0b01d1a632aafea076cc91f5a4Wink Saville        private final boolean isQuit(Message msg) {
1215cea056f5894543819898a0e62f98dc7870b27758Wink Saville            return (msg.what == SM_QUIT_CMD) && (msg.obj == mSmHandlerObj);
12161b8b98b3db5dcf0b01d1a632aafea076cc91f5a4Wink Saville        }
12171b8b98b3db5dcf0b01d1a632aafea076cc91f5a4Wink Saville
121864c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville        /** @see StateMachine#isDbg() */
1219fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        private final boolean isDbg() {
1220fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            return mDbg;
1221fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        }
1222fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
122364c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville        /** @see StateMachine#setDbg(boolean) */
1224fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        private final void setDbg(boolean dbg) {
1225fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville            mDbg = dbg;
1226fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        }
1227fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1228fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    }
1229fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
123064c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville    private SmHandler mSmHandler;
123164c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville    private HandlerThread mSmThread;
1232fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1233fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    /**
1234fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville     * Initialize.
1235fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville     *
1236fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville     * @param looper for this state machine
1237fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville     * @param name of the state machine
1238fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville     */
1239f0f566ec4607376583e59964a6a8a6dcb0265c20Wink Saville    private void initStateMachine(String name, Looper looper) {
1240fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        mName = name;
124164c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville        mSmHandler = new SmHandler(looper, this);
1242fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    }
1243fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1244fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    /**
124564c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville     * Constructor creates a StateMachine with its own thread.
1246fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville     *
1247fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville     * @param name of the state machine
1248fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville     */
124964c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville    protected StateMachine(String name) {
125064c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville        mSmThread = new HandlerThread(name);
125164c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville        mSmThread.start();
125264c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville        Looper looper = mSmThread.getLooper();
1253fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1254f0f566ec4607376583e59964a6a8a6dcb0265c20Wink Saville        initStateMachine(name, looper);
1255fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    }
1256fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1257fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    /**
1258f76a50ce8fdc6aea22cabc77b2977a1a15a79630Ken Wakasa     * Constructor creates a StateMachine using the looper.
1259fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville     *
1260fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville     * @param name of the state machine
1261fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville     */
126264c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville    protected StateMachine(String name, Looper looper) {
1263f0f566ec4607376583e59964a6a8a6dcb0265c20Wink Saville        initStateMachine(name, looper);
1264fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    }
1265fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1266fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    /**
126724d248acdf5eee9fc9a209d5207eaeceb00fa3e3Wink Saville     * Constructor creates a StateMachine using the handler.
126824d248acdf5eee9fc9a209d5207eaeceb00fa3e3Wink Saville     *
126924d248acdf5eee9fc9a209d5207eaeceb00fa3e3Wink Saville     * @param name of the state machine
127024d248acdf5eee9fc9a209d5207eaeceb00fa3e3Wink Saville     */
127124d248acdf5eee9fc9a209d5207eaeceb00fa3e3Wink Saville    protected StateMachine(String name, Handler handler) {
127224d248acdf5eee9fc9a209d5207eaeceb00fa3e3Wink Saville        initStateMachine(name, handler.getLooper());
127324d248acdf5eee9fc9a209d5207eaeceb00fa3e3Wink Saville    }
127424d248acdf5eee9fc9a209d5207eaeceb00fa3e3Wink Saville
127524d248acdf5eee9fc9a209d5207eaeceb00fa3e3Wink Saville    /**
1276fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville     * Add a new state to the state machine
1277fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville     * @param state the state to add
1278fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville     * @param parent the parent of state
1279fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville     */
128064c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville    protected final void addState(State state, State parent) {
128164c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville        mSmHandler.addState(state, parent);
1282fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    }
1283a4f3bec29c85ef9e0d07fdd551fe3c50f28b9adcWink Saville
1284a4f3bec29c85ef9e0d07fdd551fe3c50f28b9adcWink Saville    /**
1285fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville     * Add a new state to the state machine, parent will be null
1286fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville     * @param state to add
1287fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville     */
128864c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville    protected final void addState(State state) {
128964c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville        mSmHandler.addState(state, null);
1290fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    }
1291fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1292fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    /**
1293fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville     * Set the initial state. This must be invoked before
1294fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville     * and messages are sent to the state machine.
1295fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville     *
1296fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville     * @param initialState is the state which will receive the first message.
1297fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville     */
129864c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville    protected final void setInitialState(State initialState) {
129964c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville        mSmHandler.setInitialState(initialState);
1300fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    }
1301fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1302fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    /**
1303efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville     * @return current message
1304efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville     */
1305efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville    protected final Message getCurrentMessage() {
1306efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        // mSmHandler can be null if the state machine has quit.
1307efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        SmHandler smh = mSmHandler;
1308efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        if (smh == null) return null;
1309efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        return smh.getCurrentMessage();
1310efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville    }
1311efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville
1312efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville    /**
1313efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville     * @return current state
1314efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville     */
1315efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville    protected final IState getCurrentState() {
1316efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        // mSmHandler can be null if the state machine has quit.
1317efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        SmHandler smh = mSmHandler;
1318efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        if (smh == null) return null;
1319efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        return smh.getCurrentState();
1320efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville    }
1321efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville
1322efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville    /**
1323fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville     * transition to destination state. Upon returning
1324fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville     * from processMessage the current state's exit will
1325fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville     * be executed and upon the next message arriving
1326fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville     * destState.enter will be invoked.
1327fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville     *
1328d2fe04b71a89a0608eb7c67065dead2a1f540122Isaac Levy     * this function can also be called inside the enter function of the
1329d2fe04b71a89a0608eb7c67065dead2a1f540122Isaac Levy     * previous transition target, but the behavior is undefined when it is
1330d2fe04b71a89a0608eb7c67065dead2a1f540122Isaac Levy     * called mid-way through a previous transition (for example, calling this
1331d2fe04b71a89a0608eb7c67065dead2a1f540122Isaac Levy     * in the enter() routine of a intermediate node when the current transition
1332d2fe04b71a89a0608eb7c67065dead2a1f540122Isaac Levy     * target is one of the nodes descendants).
1333d2fe04b71a89a0608eb7c67065dead2a1f540122Isaac Levy     *
1334fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville     * @param destState will be the state that receives the next message.
1335fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville     */
133664c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville    protected final void transitionTo(IState destState) {
133764c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville        mSmHandler.transitionTo(destState);
1338fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    }
1339fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1340fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    /**
1341fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville     * transition to halt state. Upon returning
1342fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville     * from processMessage we will exit all current
1343bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville     * states, execute the onHalting() method and then
1344bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville     * for all subsequent messages haltedProcessMessage
1345fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville     * will be called.
1346fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville     */
1347fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    protected final void transitionToHaltingState() {
134864c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville        mSmHandler.transitionTo(mSmHandler.mHaltingState);
1349fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    }
1350fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1351fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    /**
1352fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville     * Defer this message until next state transition.
1353fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville     * Upon transitioning all deferred messages will be
1354fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville     * placed on the queue and reprocessed in the original
1355fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville     * order. (i.e. The next state the oldest messages will
1356fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville     * be processed first)
1357fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville     *
1358fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville     * @param msg is deferred until the next transition.
1359fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville     */
1360fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    protected final void deferMessage(Message msg) {
136164c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville        mSmHandler.deferMessage(msg);
1362fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    }
1363fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1364fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    /**
1365fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville     * Called when message wasn't handled
1366fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville     *
1367fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville     * @param msg that couldn't be handled.
1368fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville     */
1369fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    protected void unhandledMessage(Message msg) {
137058c73c3f76c231cf128041aefadd4b6a6bcefac2Wink Saville        if (mSmHandler.mDbg) loge(" - unhandledMessage: msg.what=" + msg.what);
1371fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    }
1372fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1373fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    /**
1374fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville     * Called for any message that is received after
1375fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville     * transitionToHalting is called.
1376fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville     */
1377fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    protected void haltedProcessMessage(Message msg) {
1378fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    }
1379fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1380fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    /**
1381d3059487abd526b91b912f70939c1c6994eecf52Wink Saville     * This will be called once after handling a message that called
1382d3059487abd526b91b912f70939c1c6994eecf52Wink Saville     * transitionToHalting. All subsequent messages will invoke
138364c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville     * {@link StateMachine#haltedProcessMessage(Message)}
1384fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville     */
1385bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville    protected void onHalting() {
1386fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    }
1387fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1388fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    /**
1389d3059487abd526b91b912f70939c1c6994eecf52Wink Saville     * This will be called once after a quit message that was NOT handled by
139064c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville     * the derived StateMachine. The StateMachine will stop and any subsequent messages will be
139164c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville     * ignored. In addition, if this StateMachine created the thread, the thread will
1392d3059487abd526b91b912f70939c1c6994eecf52Wink Saville     * be stopped after this method returns.
13931b8b98b3db5dcf0b01d1a632aafea076cc91f5a4Wink Saville     */
1394bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville    protected void onQuitting() {
13951b8b98b3db5dcf0b01d1a632aafea076cc91f5a4Wink Saville    }
13961b8b98b3db5dcf0b01d1a632aafea076cc91f5a4Wink Saville
13971b8b98b3db5dcf0b01d1a632aafea076cc91f5a4Wink Saville    /**
1398fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville     * @return the name
1399fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville     */
1400fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    public final String getName() {
1401fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        return mName;
1402fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    }
1403fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1404fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    /**
1405bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville     * Set number of log records to maintain and clears all current records.
1406fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville     *
1407fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville     * @param maxSize number of messages to maintain at anyone time.
1408fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville     */
1409bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville    public final void setLogRecSize(int maxSize) {
1410bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        mSmHandler.mLogRecords.setSize(maxSize);
1411bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville    }
1412bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville
1413bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville    /**
1414ef8da9fe0b70fdbbb54bb0645ac66f75f58f31b8Irfan Sheriff     * Set to log only messages that cause a state transition
1415ef8da9fe0b70fdbbb54bb0645ac66f75f58f31b8Irfan Sheriff     *
1416ef8da9fe0b70fdbbb54bb0645ac66f75f58f31b8Irfan Sheriff     * @param enable {@code true} to enable, {@code false} to disable
1417ef8da9fe0b70fdbbb54bb0645ac66f75f58f31b8Irfan Sheriff     */
1418ef8da9fe0b70fdbbb54bb0645ac66f75f58f31b8Irfan Sheriff    public final void setLogOnlyTransitions(boolean enable) {
1419ef8da9fe0b70fdbbb54bb0645ac66f75f58f31b8Irfan Sheriff        mSmHandler.mLogRecords.setLogOnlyTransitions(enable);
1420ef8da9fe0b70fdbbb54bb0645ac66f75f58f31b8Irfan Sheriff    }
1421ef8da9fe0b70fdbbb54bb0645ac66f75f58f31b8Irfan Sheriff
1422ef8da9fe0b70fdbbb54bb0645ac66f75f58f31b8Irfan Sheriff    /**
1423bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville     * @return number of log records
1424bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville     */
1425bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville    public final int getLogRecSize() {
1426efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        // mSmHandler can be null if the state machine has quit.
1427efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        SmHandler smh = mSmHandler;
1428efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        if (smh == null) return 0;
1429efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        return smh.mLogRecords.size();
1430bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville    }
1431bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville
1432bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville    /**
1433bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville     * @return the total number of records processed
1434bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville     */
1435bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville    public final int getLogRecCount() {
1436efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        // mSmHandler can be null if the state machine has quit.
1437efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        SmHandler smh = mSmHandler;
1438efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        if (smh == null) return 0;
1439efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        return smh.mLogRecords.count();
1440bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville    }
1441bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville
1442bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville    /**
1443efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville     * @return a log record, or null if index is out of range
1444bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville     */
1445bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville    public final LogRec getLogRec(int index) {
1446efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        // mSmHandler can be null if the state machine has quit.
1447efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        SmHandler smh = mSmHandler;
1448efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        if (smh == null) return null;
1449efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        return smh.mLogRecords.get(index);
1450bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville    }
1451bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville
1452bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville    /**
1453efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville     * @return a copy of LogRecs as a collection
1454bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville     */
1455efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville    public final Collection<LogRec> copyLogRecs() {
1456efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        Vector<LogRec> vlr = new Vector<LogRec>();
1457efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        SmHandler smh = mSmHandler;
1458efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        if (smh != null) {
1459efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville            for (LogRec lr : smh.mLogRecords.mLogRecVector) {
1460efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                vlr.add(lr);
1461efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville            }
1462efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        }
1463efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        return vlr;
1464fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    }
1465fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1466fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    /**
1467efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville     * Add the string to LogRecords.
1468bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville     *
1469bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville     * @param string
1470fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville     */
1471efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville    protected void addLogRec(String string) {
1472efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        // mSmHandler can be null if the state machine has quit.
1473efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        SmHandler smh = mSmHandler;
1474efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        if (smh == null) return;
1475efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        smh.mLogRecords.add(this, smh.getCurrentMessage(), string, smh.getCurrentState(),
1476efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville                smh.mStateStack[smh.mStateStackTopIndex].state, smh.mDestState);
1477fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    }
1478fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1479fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    /**
1480bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville     * @return true if msg should be saved in the log, default is true.
1481fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville     */
1482bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville    protected boolean recordLogRec(Message msg) {
1483bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        return true;
1484fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    }
1485fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1486fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    /**
1487bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville     * Return a string to be logged by LogRec, default
1488bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville     * is an empty string. Override if additional information is desired.
1489bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville     *
1490bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville     * @param msg that was processed
1491bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville     * @return information to be logged as a String
1492fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville     */
1493bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville    protected String getLogRecString(Message msg) {
1494bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        return "";
1495bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville    }
1496bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville
1497bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville    /**
1498bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville     * @return the string for msg.what
1499bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville     */
1500bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville    protected String getWhatToString(int what) {
1501bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        return null;
1502fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    }
1503fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1504fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    /**
1505efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville     * @return Handler, maybe null if state machine has quit.
1506fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville     */
1507fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    public final Handler getHandler() {
150864c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville        return mSmHandler;
1509fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    }
1510fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1511fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    /**
1512efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville     * Get a message and set Message.target state machine handler.
1513fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville     *
1514efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville     * Note: The handler can be null if the state machine has quit,
1515efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville     * which means target will be null and may cause a AndroidRuntimeException
1516efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville     * in MessageQueue#enqueMessage if sent directly or if sent using
1517efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville     * StateMachine#sendMessage the message will just be ignored.
1518efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville     *
1519efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville     * @return  A Message object from the global pool
1520fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville     */
1521ff4fcdb98c9575642c48f1daeafff4b257769e81Wink Saville    public final Message obtainMessage() {
152264c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville        return Message.obtain(mSmHandler);
1523fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    }
1524fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1525fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    /**
1526efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville     * Get a message and set Message.target state machine handler, what.
1527efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville     *
1528efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville     * Note: The handler can be null if the state machine has quit,
1529efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville     * which means target will be null and may cause a AndroidRuntimeException
1530efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville     * in MessageQueue#enqueMessage if sent directly or if sent using
1531efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville     * StateMachine#sendMessage the message will just be ignored.
1532fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville     *
1533fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville     * @param what is the assigned to Message.what.
1534efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville     * @return  A Message object from the global pool
1535fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville     */
1536fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    public final Message obtainMessage(int what) {
153764c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville        return Message.obtain(mSmHandler, what);
1538fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    }
1539fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1540fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    /**
1541efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville     * Get a message and set Message.target state machine handler,
1542fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville     * what and obj.
1543fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville     *
1544efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville     * Note: The handler can be null if the state machine has quit,
1545efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville     * which means target will be null and may cause a AndroidRuntimeException
1546efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville     * in MessageQueue#enqueMessage if sent directly or if sent using
1547efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville     * StateMachine#sendMessage the message will just be ignored.
1548efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville     *
1549fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville     * @param what is the assigned to Message.what.
1550fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville     * @param obj is assigned to Message.obj.
1551efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville     * @return  A Message object from the global pool
1552fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville     */
1553ff4fcdb98c9575642c48f1daeafff4b257769e81Wink Saville    public final Message obtainMessage(int what, Object obj) {
155464c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville        return Message.obtain(mSmHandler, what, obj);
1555fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    }
1556fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
155791fbd56757751a7aca8ef2b4d936e587509e6eefWink Saville    /**
1558efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville     * Get a message and set Message.target state machine handler,
155996e6bdb033b2997a4215b70acc3777fe495b9acaIrfan Sheriff     * what, arg1 and arg2
156096e6bdb033b2997a4215b70acc3777fe495b9acaIrfan Sheriff     *
1561efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville     * Note: The handler can be null if the state machine has quit,
1562efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville     * which means target will be null and may cause a AndroidRuntimeException
1563efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville     * in MessageQueue#enqueMessage if sent directly or if sent using
1564efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville     * StateMachine#sendMessage the message will just be ignored.
1565efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville     *
156696e6bdb033b2997a4215b70acc3777fe495b9acaIrfan Sheriff     * @param what  is assigned to Message.what
156796e6bdb033b2997a4215b70acc3777fe495b9acaIrfan Sheriff     * @param arg1  is assigned to Message.arg1
15688b0db520405c88414bcf8fdcb96293fb7075e524Wink Saville     * @return  A Message object from the global pool
15698b0db520405c88414bcf8fdcb96293fb7075e524Wink Saville     */
15708b0db520405c88414bcf8fdcb96293fb7075e524Wink Saville    public final Message obtainMessage(int what, int arg1) {
15718b0db520405c88414bcf8fdcb96293fb7075e524Wink Saville        // use this obtain so we don't match the obtain(h, what, Object) method
15728b0db520405c88414bcf8fdcb96293fb7075e524Wink Saville        return Message.obtain(mSmHandler, what, arg1, 0);
15738b0db520405c88414bcf8fdcb96293fb7075e524Wink Saville    }
15748b0db520405c88414bcf8fdcb96293fb7075e524Wink Saville
15758b0db520405c88414bcf8fdcb96293fb7075e524Wink Saville    /**
15768b0db520405c88414bcf8fdcb96293fb7075e524Wink Saville     * Get a message and set Message.target state machine handler,
15778b0db520405c88414bcf8fdcb96293fb7075e524Wink Saville     * what, arg1 and arg2
15788b0db520405c88414bcf8fdcb96293fb7075e524Wink Saville     *
15798b0db520405c88414bcf8fdcb96293fb7075e524Wink Saville     * Note: The handler can be null if the state machine has quit,
15808b0db520405c88414bcf8fdcb96293fb7075e524Wink Saville     * which means target will be null and may cause a AndroidRuntimeException
15818b0db520405c88414bcf8fdcb96293fb7075e524Wink Saville     * in MessageQueue#enqueMessage if sent directly or if sent using
15828b0db520405c88414bcf8fdcb96293fb7075e524Wink Saville     * StateMachine#sendMessage the message will just be ignored.
15838b0db520405c88414bcf8fdcb96293fb7075e524Wink Saville     *
15848b0db520405c88414bcf8fdcb96293fb7075e524Wink Saville     * @param what  is assigned to Message.what
15858b0db520405c88414bcf8fdcb96293fb7075e524Wink Saville     * @param arg1  is assigned to Message.arg1
158696e6bdb033b2997a4215b70acc3777fe495b9acaIrfan Sheriff     * @param arg2  is assigned to Message.arg2
1587efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville     * @return  A Message object from the global pool
158896e6bdb033b2997a4215b70acc3777fe495b9acaIrfan Sheriff     */
1589ff4fcdb98c9575642c48f1daeafff4b257769e81Wink Saville    public final Message obtainMessage(int what, int arg1, int arg2) {
159064c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville        return Message.obtain(mSmHandler, what, arg1, arg2);
159196e6bdb033b2997a4215b70acc3777fe495b9acaIrfan Sheriff    }
159296e6bdb033b2997a4215b70acc3777fe495b9acaIrfan Sheriff
159396e6bdb033b2997a4215b70acc3777fe495b9acaIrfan Sheriff    /**
1594efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville     * Get a message and set Message.target state machine handler,
159596e6bdb033b2997a4215b70acc3777fe495b9acaIrfan Sheriff     * what, arg1, arg2 and obj
159696e6bdb033b2997a4215b70acc3777fe495b9acaIrfan Sheriff     *
1597efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville     * Note: The handler can be null if the state machine has quit,
1598efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville     * which means target will be null and may cause a AndroidRuntimeException
1599efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville     * in MessageQueue#enqueMessage if sent directly or if sent using
1600efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville     * StateMachine#sendMessage the message will just be ignored.
1601efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville     *
160296e6bdb033b2997a4215b70acc3777fe495b9acaIrfan Sheriff     * @param what  is assigned to Message.what
160396e6bdb033b2997a4215b70acc3777fe495b9acaIrfan Sheriff     * @param arg1  is assigned to Message.arg1
160496e6bdb033b2997a4215b70acc3777fe495b9acaIrfan Sheriff     * @param arg2  is assigned to Message.arg2
160596e6bdb033b2997a4215b70acc3777fe495b9acaIrfan Sheriff     * @param obj is assigned to Message.obj
1606efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville     * @return  A Message object from the global pool
160796e6bdb033b2997a4215b70acc3777fe495b9acaIrfan Sheriff     */
1608ff4fcdb98c9575642c48f1daeafff4b257769e81Wink Saville    public final Message obtainMessage(int what, int arg1, int arg2, Object obj) {
160964c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville        return Message.obtain(mSmHandler, what, arg1, arg2, obj);
161096e6bdb033b2997a4215b70acc3777fe495b9acaIrfan Sheriff    }
161196e6bdb033b2997a4215b70acc3777fe495b9acaIrfan Sheriff
161296e6bdb033b2997a4215b70acc3777fe495b9acaIrfan Sheriff    /**
161391fbd56757751a7aca8ef2b4d936e587509e6eefWink Saville     * Enqueue a message to this state machine.
1614efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville     *
1615efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville     * Message is ignored if state machine has quit.
161691fbd56757751a7aca8ef2b4d936e587509e6eefWink Saville     */
161791fbd56757751a7aca8ef2b4d936e587509e6eefWink Saville    public final void sendMessage(int what) {
1618a544d467f2a876f2ada2880214b3157cfaef769fJaikumar Ganesh        // mSmHandler can be null if the state machine has quit.
1619efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        SmHandler smh = mSmHandler;
1620efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        if (smh == null) return;
1621a544d467f2a876f2ada2880214b3157cfaef769fJaikumar Ganesh
1622efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        smh.sendMessage(obtainMessage(what));
162391fbd56757751a7aca8ef2b4d936e587509e6eefWink Saville    }
162491fbd56757751a7aca8ef2b4d936e587509e6eefWink Saville
162591fbd56757751a7aca8ef2b4d936e587509e6eefWink Saville    /**
162691fbd56757751a7aca8ef2b4d936e587509e6eefWink Saville     * Enqueue a message to this state machine.
1627efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville     *
1628efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville     * Message is ignored if state machine has quit.
162991fbd56757751a7aca8ef2b4d936e587509e6eefWink Saville     */
163091fbd56757751a7aca8ef2b4d936e587509e6eefWink Saville    public final void sendMessage(int what, Object obj) {
1631a544d467f2a876f2ada2880214b3157cfaef769fJaikumar Ganesh        // mSmHandler can be null if the state machine has quit.
1632efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        SmHandler smh = mSmHandler;
1633efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        if (smh == null) return;
1634a544d467f2a876f2ada2880214b3157cfaef769fJaikumar Ganesh
1635ff4fcdb98c9575642c48f1daeafff4b257769e81Wink Saville        smh.sendMessage(obtainMessage(what, obj));
163691fbd56757751a7aca8ef2b4d936e587509e6eefWink Saville    }
163791fbd56757751a7aca8ef2b4d936e587509e6eefWink Saville
1638fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    /**
1639fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville     * Enqueue a message to this state machine.
1640efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville     *
1641efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville     * Message is ignored if state machine has quit.
1642fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville     */
16438b0db520405c88414bcf8fdcb96293fb7075e524Wink Saville    public final void sendMessage(int what, int arg1) {
16448b0db520405c88414bcf8fdcb96293fb7075e524Wink Saville        // mSmHandler can be null if the state machine has quit.
16458b0db520405c88414bcf8fdcb96293fb7075e524Wink Saville        SmHandler smh = mSmHandler;
16468b0db520405c88414bcf8fdcb96293fb7075e524Wink Saville        if (smh == null) return;
16478b0db520405c88414bcf8fdcb96293fb7075e524Wink Saville
16488b0db520405c88414bcf8fdcb96293fb7075e524Wink Saville        smh.sendMessage(obtainMessage(what, arg1));
16498b0db520405c88414bcf8fdcb96293fb7075e524Wink Saville    }
16508b0db520405c88414bcf8fdcb96293fb7075e524Wink Saville
16518b0db520405c88414bcf8fdcb96293fb7075e524Wink Saville    /**
16528b0db520405c88414bcf8fdcb96293fb7075e524Wink Saville     * Enqueue a message to this state machine.
16538b0db520405c88414bcf8fdcb96293fb7075e524Wink Saville     *
16548b0db520405c88414bcf8fdcb96293fb7075e524Wink Saville     * Message is ignored if state machine has quit.
16558b0db520405c88414bcf8fdcb96293fb7075e524Wink Saville     */
16568b0db520405c88414bcf8fdcb96293fb7075e524Wink Saville    public final void sendMessage(int what, int arg1, int arg2) {
16578b0db520405c88414bcf8fdcb96293fb7075e524Wink Saville        // mSmHandler can be null if the state machine has quit.
16588b0db520405c88414bcf8fdcb96293fb7075e524Wink Saville        SmHandler smh = mSmHandler;
16598b0db520405c88414bcf8fdcb96293fb7075e524Wink Saville        if (smh == null) return;
16608b0db520405c88414bcf8fdcb96293fb7075e524Wink Saville
16618b0db520405c88414bcf8fdcb96293fb7075e524Wink Saville        smh.sendMessage(obtainMessage(what, arg1, arg2));
16628b0db520405c88414bcf8fdcb96293fb7075e524Wink Saville    }
16638b0db520405c88414bcf8fdcb96293fb7075e524Wink Saville
16648b0db520405c88414bcf8fdcb96293fb7075e524Wink Saville    /**
16658b0db520405c88414bcf8fdcb96293fb7075e524Wink Saville     * Enqueue a message to this state machine.
16668b0db520405c88414bcf8fdcb96293fb7075e524Wink Saville     *
16678b0db520405c88414bcf8fdcb96293fb7075e524Wink Saville     * Message is ignored if state machine has quit.
16688b0db520405c88414bcf8fdcb96293fb7075e524Wink Saville     */
16694753cd2014b3db7ab47a9d408601e9e17f790a21Wink Saville    public final void sendMessage(int what, int arg1, int arg2, Object obj) {
16704753cd2014b3db7ab47a9d408601e9e17f790a21Wink Saville        // mSmHandler can be null if the state machine has quit.
16714753cd2014b3db7ab47a9d408601e9e17f790a21Wink Saville        SmHandler smh = mSmHandler;
16724753cd2014b3db7ab47a9d408601e9e17f790a21Wink Saville        if (smh == null) return;
16734753cd2014b3db7ab47a9d408601e9e17f790a21Wink Saville
16744753cd2014b3db7ab47a9d408601e9e17f790a21Wink Saville        smh.sendMessage(obtainMessage(what, arg1, arg2, obj));
16754753cd2014b3db7ab47a9d408601e9e17f790a21Wink Saville    }
16764753cd2014b3db7ab47a9d408601e9e17f790a21Wink Saville
16774753cd2014b3db7ab47a9d408601e9e17f790a21Wink Saville    /**
16784753cd2014b3db7ab47a9d408601e9e17f790a21Wink Saville     * Enqueue a message to this state machine.
16794753cd2014b3db7ab47a9d408601e9e17f790a21Wink Saville     *
16804753cd2014b3db7ab47a9d408601e9e17f790a21Wink Saville     * Message is ignored if state machine has quit.
16814753cd2014b3db7ab47a9d408601e9e17f790a21Wink Saville     */
1682fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    public final void sendMessage(Message msg) {
1683a544d467f2a876f2ada2880214b3157cfaef769fJaikumar Ganesh        // mSmHandler can be null if the state machine has quit.
1684efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        SmHandler smh = mSmHandler;
1685efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        if (smh == null) return;
1686a544d467f2a876f2ada2880214b3157cfaef769fJaikumar Ganesh
1687efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        smh.sendMessage(msg);
1688fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    }
1689fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1690fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    /**
1691fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville     * Enqueue a message to this state machine after a delay.
1692efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville     *
1693efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville     * Message is ignored if state machine has quit.
1694fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville     */
169591fbd56757751a7aca8ef2b4d936e587509e6eefWink Saville    public final void sendMessageDelayed(int what, long delayMillis) {
1696a544d467f2a876f2ada2880214b3157cfaef769fJaikumar Ganesh        // mSmHandler can be null if the state machine has quit.
1697efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        SmHandler smh = mSmHandler;
1698efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        if (smh == null) return;
1699a544d467f2a876f2ada2880214b3157cfaef769fJaikumar Ganesh
1700efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        smh.sendMessageDelayed(obtainMessage(what), delayMillis);
170191fbd56757751a7aca8ef2b4d936e587509e6eefWink Saville    }
170291fbd56757751a7aca8ef2b4d936e587509e6eefWink Saville
170391fbd56757751a7aca8ef2b4d936e587509e6eefWink Saville    /**
170491fbd56757751a7aca8ef2b4d936e587509e6eefWink Saville     * Enqueue a message to this state machine after a delay.
1705efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville     *
1706efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville     * Message is ignored if state machine has quit.
170791fbd56757751a7aca8ef2b4d936e587509e6eefWink Saville     */
170891fbd56757751a7aca8ef2b4d936e587509e6eefWink Saville    public final void sendMessageDelayed(int what, Object obj, long delayMillis) {
1709a544d467f2a876f2ada2880214b3157cfaef769fJaikumar Ganesh        // mSmHandler can be null if the state machine has quit.
1710efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        SmHandler smh = mSmHandler;
1711efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        if (smh == null) return;
1712a544d467f2a876f2ada2880214b3157cfaef769fJaikumar Ganesh
1713efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        smh.sendMessageDelayed(obtainMessage(what, obj), delayMillis);
171491fbd56757751a7aca8ef2b4d936e587509e6eefWink Saville    }
171591fbd56757751a7aca8ef2b4d936e587509e6eefWink Saville
171691fbd56757751a7aca8ef2b4d936e587509e6eefWink Saville    /**
171791fbd56757751a7aca8ef2b4d936e587509e6eefWink Saville     * Enqueue a message to this state machine after a delay.
1718efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville     *
1719efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville     * Message is ignored if state machine has quit.
172091fbd56757751a7aca8ef2b4d936e587509e6eefWink Saville     */
17218b0db520405c88414bcf8fdcb96293fb7075e524Wink Saville    public final void sendMessageDelayed(int what, int arg1, long delayMillis) {
17228b0db520405c88414bcf8fdcb96293fb7075e524Wink Saville        // mSmHandler can be null if the state machine has quit.
17238b0db520405c88414bcf8fdcb96293fb7075e524Wink Saville        SmHandler smh = mSmHandler;
17248b0db520405c88414bcf8fdcb96293fb7075e524Wink Saville        if (smh == null) return;
17258b0db520405c88414bcf8fdcb96293fb7075e524Wink Saville
17268b0db520405c88414bcf8fdcb96293fb7075e524Wink Saville        smh.sendMessageDelayed(obtainMessage(what, arg1), delayMillis);
17278b0db520405c88414bcf8fdcb96293fb7075e524Wink Saville    }
17288b0db520405c88414bcf8fdcb96293fb7075e524Wink Saville
17298b0db520405c88414bcf8fdcb96293fb7075e524Wink Saville    /**
17308b0db520405c88414bcf8fdcb96293fb7075e524Wink Saville     * Enqueue a message to this state machine after a delay.
17318b0db520405c88414bcf8fdcb96293fb7075e524Wink Saville     *
17328b0db520405c88414bcf8fdcb96293fb7075e524Wink Saville     * Message is ignored if state machine has quit.
17338b0db520405c88414bcf8fdcb96293fb7075e524Wink Saville     */
17348b0db520405c88414bcf8fdcb96293fb7075e524Wink Saville    public final void sendMessageDelayed(int what, int arg1, int arg2, long delayMillis) {
17358b0db520405c88414bcf8fdcb96293fb7075e524Wink Saville        // mSmHandler can be null if the state machine has quit.
17368b0db520405c88414bcf8fdcb96293fb7075e524Wink Saville        SmHandler smh = mSmHandler;
17378b0db520405c88414bcf8fdcb96293fb7075e524Wink Saville        if (smh == null) return;
17388b0db520405c88414bcf8fdcb96293fb7075e524Wink Saville
17398b0db520405c88414bcf8fdcb96293fb7075e524Wink Saville        smh.sendMessageDelayed(obtainMessage(what, arg1, arg2), delayMillis);
17408b0db520405c88414bcf8fdcb96293fb7075e524Wink Saville    }
17418b0db520405c88414bcf8fdcb96293fb7075e524Wink Saville
17428b0db520405c88414bcf8fdcb96293fb7075e524Wink Saville    /**
17438b0db520405c88414bcf8fdcb96293fb7075e524Wink Saville     * Enqueue a message to this state machine after a delay.
17448b0db520405c88414bcf8fdcb96293fb7075e524Wink Saville     *
17458b0db520405c88414bcf8fdcb96293fb7075e524Wink Saville     * Message is ignored if state machine has quit.
17468b0db520405c88414bcf8fdcb96293fb7075e524Wink Saville     */
17474753cd2014b3db7ab47a9d408601e9e17f790a21Wink Saville    public final void sendMessageDelayed(int what, int arg1, int arg2, Object obj,
17484753cd2014b3db7ab47a9d408601e9e17f790a21Wink Saville            long delayMillis) {
17494753cd2014b3db7ab47a9d408601e9e17f790a21Wink Saville        // mSmHandler can be null if the state machine has quit.
17504753cd2014b3db7ab47a9d408601e9e17f790a21Wink Saville        SmHandler smh = mSmHandler;
17514753cd2014b3db7ab47a9d408601e9e17f790a21Wink Saville        if (smh == null) return;
17524753cd2014b3db7ab47a9d408601e9e17f790a21Wink Saville
17534753cd2014b3db7ab47a9d408601e9e17f790a21Wink Saville        smh.sendMessageDelayed(obtainMessage(what, arg1, arg2, obj), delayMillis);
17544753cd2014b3db7ab47a9d408601e9e17f790a21Wink Saville    }
17554753cd2014b3db7ab47a9d408601e9e17f790a21Wink Saville
17564753cd2014b3db7ab47a9d408601e9e17f790a21Wink Saville    /**
17574753cd2014b3db7ab47a9d408601e9e17f790a21Wink Saville     * Enqueue a message to this state machine after a delay.
17584753cd2014b3db7ab47a9d408601e9e17f790a21Wink Saville     *
17594753cd2014b3db7ab47a9d408601e9e17f790a21Wink Saville     * Message is ignored if state machine has quit.
17604753cd2014b3db7ab47a9d408601e9e17f790a21Wink Saville     */
1761fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    public final void sendMessageDelayed(Message msg, long delayMillis) {
1762a544d467f2a876f2ada2880214b3157cfaef769fJaikumar Ganesh        // mSmHandler can be null if the state machine has quit.
1763efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        SmHandler smh = mSmHandler;
1764efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        if (smh == null) return;
1765a544d467f2a876f2ada2880214b3157cfaef769fJaikumar Ganesh
1766efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        smh.sendMessageDelayed(msg, delayMillis);
1767fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    }
1768fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1769fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    /**
1770fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville     * Enqueue a message to the front of the queue for this state machine.
177164c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville     * Protected, may only be called by instances of StateMachine.
1772efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville     *
1773efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville     * Message is ignored if state machine has quit.
1774fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville     */
17758b0db520405c88414bcf8fdcb96293fb7075e524Wink Saville    protected final void sendMessageAtFrontOfQueue(int what) {
17768b0db520405c88414bcf8fdcb96293fb7075e524Wink Saville        // mSmHandler can be null if the state machine has quit.
17778b0db520405c88414bcf8fdcb96293fb7075e524Wink Saville        SmHandler smh = mSmHandler;
17788b0db520405c88414bcf8fdcb96293fb7075e524Wink Saville        if (smh == null) return;
17798b0db520405c88414bcf8fdcb96293fb7075e524Wink Saville
17808b0db520405c88414bcf8fdcb96293fb7075e524Wink Saville        smh.sendMessageAtFrontOfQueue(obtainMessage(what));
17818b0db520405c88414bcf8fdcb96293fb7075e524Wink Saville    }
17828b0db520405c88414bcf8fdcb96293fb7075e524Wink Saville
17838b0db520405c88414bcf8fdcb96293fb7075e524Wink Saville    /**
17848b0db520405c88414bcf8fdcb96293fb7075e524Wink Saville     * Enqueue a message to the front of the queue for this state machine.
17858b0db520405c88414bcf8fdcb96293fb7075e524Wink Saville     * Protected, may only be called by instances of StateMachine.
17868b0db520405c88414bcf8fdcb96293fb7075e524Wink Saville     *
17878b0db520405c88414bcf8fdcb96293fb7075e524Wink Saville     * Message is ignored if state machine has quit.
17888b0db520405c88414bcf8fdcb96293fb7075e524Wink Saville     */
178991fbd56757751a7aca8ef2b4d936e587509e6eefWink Saville    protected final void sendMessageAtFrontOfQueue(int what, Object obj) {
1790efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        // mSmHandler can be null if the state machine has quit.
1791efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        SmHandler smh = mSmHandler;
1792efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        if (smh == null) return;
1793efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville
1794efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        smh.sendMessageAtFrontOfQueue(obtainMessage(what, obj));
179591fbd56757751a7aca8ef2b4d936e587509e6eefWink Saville    }
179691fbd56757751a7aca8ef2b4d936e587509e6eefWink Saville
179791fbd56757751a7aca8ef2b4d936e587509e6eefWink Saville    /**
179891fbd56757751a7aca8ef2b4d936e587509e6eefWink Saville     * Enqueue a message to the front of the queue for this state machine.
179964c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville     * Protected, may only be called by instances of StateMachine.
1800efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville     *
1801efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville     * Message is ignored if state machine has quit.
180291fbd56757751a7aca8ef2b4d936e587509e6eefWink Saville     */
18038b0db520405c88414bcf8fdcb96293fb7075e524Wink Saville    protected final void sendMessageAtFrontOfQueue(int what, int arg1) {
1804efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        // mSmHandler can be null if the state machine has quit.
1805efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        SmHandler smh = mSmHandler;
1806efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        if (smh == null) return;
1807efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville
18088b0db520405c88414bcf8fdcb96293fb7075e524Wink Saville        smh.sendMessageAtFrontOfQueue(obtainMessage(what, arg1));
18098b0db520405c88414bcf8fdcb96293fb7075e524Wink Saville    }
18108b0db520405c88414bcf8fdcb96293fb7075e524Wink Saville
18118b0db520405c88414bcf8fdcb96293fb7075e524Wink Saville
18128b0db520405c88414bcf8fdcb96293fb7075e524Wink Saville    /**
18138b0db520405c88414bcf8fdcb96293fb7075e524Wink Saville     * Enqueue a message to the front of the queue for this state machine.
18148b0db520405c88414bcf8fdcb96293fb7075e524Wink Saville     * Protected, may only be called by instances of StateMachine.
18158b0db520405c88414bcf8fdcb96293fb7075e524Wink Saville     *
18168b0db520405c88414bcf8fdcb96293fb7075e524Wink Saville     * Message is ignored if state machine has quit.
18178b0db520405c88414bcf8fdcb96293fb7075e524Wink Saville     */
18188b0db520405c88414bcf8fdcb96293fb7075e524Wink Saville    protected final void sendMessageAtFrontOfQueue(int what, int arg1, int arg2) {
18198b0db520405c88414bcf8fdcb96293fb7075e524Wink Saville        // mSmHandler can be null if the state machine has quit.
18208b0db520405c88414bcf8fdcb96293fb7075e524Wink Saville        SmHandler smh = mSmHandler;
18218b0db520405c88414bcf8fdcb96293fb7075e524Wink Saville        if (smh == null) return;
18228b0db520405c88414bcf8fdcb96293fb7075e524Wink Saville
18238b0db520405c88414bcf8fdcb96293fb7075e524Wink Saville        smh.sendMessageAtFrontOfQueue(obtainMessage(what, arg1, arg2));
182491fbd56757751a7aca8ef2b4d936e587509e6eefWink Saville    }
182591fbd56757751a7aca8ef2b4d936e587509e6eefWink Saville
182691fbd56757751a7aca8ef2b4d936e587509e6eefWink Saville    /**
182791fbd56757751a7aca8ef2b4d936e587509e6eefWink Saville     * Enqueue a message to the front of the queue for this state machine.
182864c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville     * Protected, may only be called by instances of StateMachine.
1829efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville     *
1830efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville     * Message is ignored if state machine has quit.
183191fbd56757751a7aca8ef2b4d936e587509e6eefWink Saville     */
18324753cd2014b3db7ab47a9d408601e9e17f790a21Wink Saville    protected final void sendMessageAtFrontOfQueue(int what, int arg1, int arg2, Object obj) {
18334753cd2014b3db7ab47a9d408601e9e17f790a21Wink Saville        // mSmHandler can be null if the state machine has quit.
18344753cd2014b3db7ab47a9d408601e9e17f790a21Wink Saville        SmHandler smh = mSmHandler;
18354753cd2014b3db7ab47a9d408601e9e17f790a21Wink Saville        if (smh == null) return;
18364753cd2014b3db7ab47a9d408601e9e17f790a21Wink Saville
18374753cd2014b3db7ab47a9d408601e9e17f790a21Wink Saville        smh.sendMessageAtFrontOfQueue(obtainMessage(what, arg1, arg2, obj));
18384753cd2014b3db7ab47a9d408601e9e17f790a21Wink Saville    }
18394753cd2014b3db7ab47a9d408601e9e17f790a21Wink Saville
18404753cd2014b3db7ab47a9d408601e9e17f790a21Wink Saville    /**
18414753cd2014b3db7ab47a9d408601e9e17f790a21Wink Saville     * Enqueue a message to the front of the queue for this state machine.
18424753cd2014b3db7ab47a9d408601e9e17f790a21Wink Saville     * Protected, may only be called by instances of StateMachine.
18434753cd2014b3db7ab47a9d408601e9e17f790a21Wink Saville     *
18444753cd2014b3db7ab47a9d408601e9e17f790a21Wink Saville     * Message is ignored if state machine has quit.
18454753cd2014b3db7ab47a9d408601e9e17f790a21Wink Saville     */
1846fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    protected final void sendMessageAtFrontOfQueue(Message msg) {
1847efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        // mSmHandler can be null if the state machine has quit.
1848efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        SmHandler smh = mSmHandler;
1849efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        if (smh == null) return;
1850efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville
1851efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        smh.sendMessageAtFrontOfQueue(msg);
1852fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    }
1853fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1854fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    /**
1855aa4b235dd720d1f2861681cdfabf3b5fabc61fb0Jaikumar Ganesh     * Removes a message from the message queue.
185664c42cae4482fe0157e977b8ddd0f2c2436b3f31Wink Saville     * Protected, may only be called by instances of StateMachine.
1857aa4b235dd720d1f2861681cdfabf3b5fabc61fb0Jaikumar Ganesh     */
1858aa4b235dd720d1f2861681cdfabf3b5fabc61fb0Jaikumar Ganesh    protected final void removeMessages(int what) {
1859efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        // mSmHandler can be null if the state machine has quit.
1860efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        SmHandler smh = mSmHandler;
1861efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        if (smh == null) return;
1862efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville
1863efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        smh.removeMessages(what);
1864efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville    }
1865efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville
1866efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville    /**
1867efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville     * Validate that the message was sent by
1868efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville     * {@link StateMachine#quit} or {@link StateMachine#quitNow}.
1869efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville     * */
1870efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville    protected final boolean isQuit(Message msg) {
1871efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        // mSmHandler can be null if the state machine has quit.
1872efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        SmHandler smh = mSmHandler;
1873efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        if (smh == null) return msg.what == SM_QUIT_CMD;
1874efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville
1875efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        return smh.isQuit(msg);
1876aa4b235dd720d1f2861681cdfabf3b5fabc61fb0Jaikumar Ganesh    }
1877aa4b235dd720d1f2861681cdfabf3b5fabc61fb0Jaikumar Ganesh
1878aa4b235dd720d1f2861681cdfabf3b5fabc61fb0Jaikumar Ganesh    /**
1879bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville     * Quit the state machine after all currently queued up messages are processed.
18801b8b98b3db5dcf0b01d1a632aafea076cc91f5a4Wink Saville     */
1881bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville    protected final void quit() {
1882bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        // mSmHandler can be null if the state machine is already stopped.
1883efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        SmHandler smh = mSmHandler;
1884efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        if (smh == null) return;
1885a544d467f2a876f2ada2880214b3157cfaef769fJaikumar Ganesh
1886efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        smh.quit();
18871b8b98b3db5dcf0b01d1a632aafea076cc91f5a4Wink Saville    }
18881b8b98b3db5dcf0b01d1a632aafea076cc91f5a4Wink Saville
18891b8b98b3db5dcf0b01d1a632aafea076cc91f5a4Wink Saville    /**
1890bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville     * Quit the state machine immediately all currently queued messages will be discarded.
18911b8b98b3db5dcf0b01d1a632aafea076cc91f5a4Wink Saville     */
1892bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville    protected final void quitNow() {
1893bbf30dfd767f823f5f40d14b498e2a593454c5c9Wink Saville        // mSmHandler can be null if the state machine is already stopped.
1894efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        SmHandler smh = mSmHandler;
1895efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        if (smh == null) return;
1896583eaaa57c51b28bf14da2a5cc94a2e6091cccf5Wink Saville
1897efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        smh.quitNow();
1898583eaaa57c51b28bf14da2a5cc94a2e6091cccf5Wink Saville    }
1899583eaaa57c51b28bf14da2a5cc94a2e6091cccf5Wink Saville
1900583eaaa57c51b28bf14da2a5cc94a2e6091cccf5Wink Saville    /**
1901fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville     * @return if debugging is enabled
1902fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville     */
1903fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    public boolean isDbg() {
1904a544d467f2a876f2ada2880214b3157cfaef769fJaikumar Ganesh        // mSmHandler can be null if the state machine has quit.
1905efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        SmHandler smh = mSmHandler;
1906efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        if (smh == null) return false;
1907a544d467f2a876f2ada2880214b3157cfaef769fJaikumar Ganesh
1908efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        return smh.isDbg();
1909fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    }
1910fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1911fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    /**
1912fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville     * Set debug enable/disabled.
1913fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville     *
1914fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville     * @param dbg is true to enable debugging.
1915fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville     */
1916fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    public void setDbg(boolean dbg) {
1917a544d467f2a876f2ada2880214b3157cfaef769fJaikumar Ganesh        // mSmHandler can be null if the state machine has quit.
1918efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        SmHandler smh = mSmHandler;
1919efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        if (smh == null) return;
1920a544d467f2a876f2ada2880214b3157cfaef769fJaikumar Ganesh
1921efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        smh.setDbg(dbg);
1922fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    }
1923fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville
1924fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    /**
1925fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville     * Start the state machine.
1926fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville     */
1927fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    public void start() {
1928a544d467f2a876f2ada2880214b3157cfaef769fJaikumar Ganesh        // mSmHandler can be null if the state machine has quit.
1929efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        SmHandler smh = mSmHandler;
1930efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        if (smh == null) return;
1931a544d467f2a876f2ada2880214b3157cfaef769fJaikumar Ganesh
1932fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville        /** Send the complete construction message */
1933efcc3d35661c0cd978bb2b2f808fade4c4734e21Wink Saville        smh.completeConstruction();
1934fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville    }
1935583eaaa57c51b28bf14da2a5cc94a2e6091cccf5Wink Saville
1936583eaaa57c51b28bf14da2a5cc94a2e6091cccf5Wink Saville    /**
1937583eaaa57c51b28bf14da2a5cc94a2e6091cccf5Wink Saville     * Dump the current state.
1938583eaaa57c51b28bf14da2a5cc94a2e6091cccf5Wink Saville     *
1939583eaaa57c51b28bf14da2a5cc94a2e6091cccf5Wink Saville     * @param fd
1940583eaaa57c51b28bf14da2a5cc94a2e6091cccf5Wink Saville     * @param pw
1941583eaaa57c51b28bf14da2a5cc94a2e6091cccf5Wink Saville     * @param args
1942583eaaa57c51b28bf14da2a5cc94a2e6091cccf5Wink Saville     */
1943583eaaa57c51b28bf14da2a5cc94a2e6091cccf5Wink Saville    public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
194454b1b1a07ad3edd1df060889aad453aa0e1cc79aWink Saville        // Cannot just invoke pw.println(this.toString()) because if the
194554b1b1a07ad3edd1df060889aad453aa0e1cc79aWink Saville        // resulting string is to long it won't be displayed.
194654b1b1a07ad3edd1df060889aad453aa0e1cc79aWink Saville        pw.println(getName() + ":");
194754b1b1a07ad3edd1df060889aad453aa0e1cc79aWink Saville        pw.println(" total records=" + getLogRecCount());
194854b1b1a07ad3edd1df060889aad453aa0e1cc79aWink Saville        for (int i = 0; i < getLogRecSize(); i++) {
194954b1b1a07ad3edd1df060889aad453aa0e1cc79aWink Saville            pw.println(" rec[" + i + "]: " + getLogRec(i).toString());
195054b1b1a07ad3edd1df060889aad453aa0e1cc79aWink Saville            pw.flush();
195154b1b1a07ad3edd1df060889aad453aa0e1cc79aWink Saville        }
195254b1b1a07ad3edd1df060889aad453aa0e1cc79aWink Saville        pw.println("curState=" + getCurrentState().getName());
1953726d4de780dea9afded2e44a010b793f7ac29c23Mike Lockwood    }
1954726d4de780dea9afded2e44a010b793f7ac29c23Mike Lockwood
1955726d4de780dea9afded2e44a010b793f7ac29c23Mike Lockwood    @Override
1956726d4de780dea9afded2e44a010b793f7ac29c23Mike Lockwood    public String toString() {
195754b1b1a07ad3edd1df060889aad453aa0e1cc79aWink Saville        StringWriter sr = new StringWriter();
195854b1b1a07ad3edd1df060889aad453aa0e1cc79aWink Saville        PrintWriter pr = new PrintWriter(sr);
195954b1b1a07ad3edd1df060889aad453aa0e1cc79aWink Saville        dump(null, pr, null);
196054b1b1a07ad3edd1df060889aad453aa0e1cc79aWink Saville        pr.flush();
196154b1b1a07ad3edd1df060889aad453aa0e1cc79aWink Saville        pr.close();
196254b1b1a07ad3edd1df060889aad453aa0e1cc79aWink Saville        return sr.toString();
1963583eaaa57c51b28bf14da2a5cc94a2e6091cccf5Wink Saville    }
196458c73c3f76c231cf128041aefadd4b6a6bcefac2Wink Saville
1965ff4fcdb98c9575642c48f1daeafff4b257769e81Wink Saville    /**
1966ff4fcdb98c9575642c48f1daeafff4b257769e81Wink Saville     * Log with debug and add to the LogRecords.
1967ff4fcdb98c9575642c48f1daeafff4b257769e81Wink Saville     *
1968ff4fcdb98c9575642c48f1daeafff4b257769e81Wink Saville     * @param s is string log
1969ff4fcdb98c9575642c48f1daeafff4b257769e81Wink Saville     */
1970ff4fcdb98c9575642c48f1daeafff4b257769e81Wink Saville    protected void logAndAddLogRec(String s) {
1971ff4fcdb98c9575642c48f1daeafff4b257769e81Wink Saville        addLogRec(s);
1972ff4fcdb98c9575642c48f1daeafff4b257769e81Wink Saville        log(s);
1973ff4fcdb98c9575642c48f1daeafff4b257769e81Wink Saville    }
1974ff4fcdb98c9575642c48f1daeafff4b257769e81Wink Saville
1975ff4fcdb98c9575642c48f1daeafff4b257769e81Wink Saville    /**
1976ff4fcdb98c9575642c48f1daeafff4b257769e81Wink Saville     * Log with debug
1977ff4fcdb98c9575642c48f1daeafff4b257769e81Wink Saville     *
1978ff4fcdb98c9575642c48f1daeafff4b257769e81Wink Saville     * @param s is string log
1979ff4fcdb98c9575642c48f1daeafff4b257769e81Wink Saville     */
198058c73c3f76c231cf128041aefadd4b6a6bcefac2Wink Saville    protected void log(String s) {
198158c73c3f76c231cf128041aefadd4b6a6bcefac2Wink Saville        Log.d(mName, s);
198258c73c3f76c231cf128041aefadd4b6a6bcefac2Wink Saville    }
198358c73c3f76c231cf128041aefadd4b6a6bcefac2Wink Saville
1984ff4fcdb98c9575642c48f1daeafff4b257769e81Wink Saville    /**
1985ff4fcdb98c9575642c48f1daeafff4b257769e81Wink Saville     * Log with debug attribute
1986ff4fcdb98c9575642c48f1daeafff4b257769e81Wink Saville     *
1987ff4fcdb98c9575642c48f1daeafff4b257769e81Wink Saville     * @param s is string log
1988ff4fcdb98c9575642c48f1daeafff4b257769e81Wink Saville     */
1989ff4fcdb98c9575642c48f1daeafff4b257769e81Wink Saville    protected void logd(String s) {
1990ff4fcdb98c9575642c48f1daeafff4b257769e81Wink Saville        Log.d(mName, s);
1991ff4fcdb98c9575642c48f1daeafff4b257769e81Wink Saville    }
1992ff4fcdb98c9575642c48f1daeafff4b257769e81Wink Saville
1993ff4fcdb98c9575642c48f1daeafff4b257769e81Wink Saville    /**
1994ff4fcdb98c9575642c48f1daeafff4b257769e81Wink Saville     * Log with verbose attribute
1995ff4fcdb98c9575642c48f1daeafff4b257769e81Wink Saville     *
1996ff4fcdb98c9575642c48f1daeafff4b257769e81Wink Saville     * @param s is string log
1997ff4fcdb98c9575642c48f1daeafff4b257769e81Wink Saville     */
199858c73c3f76c231cf128041aefadd4b6a6bcefac2Wink Saville    protected void logv(String s) {
199958c73c3f76c231cf128041aefadd4b6a6bcefac2Wink Saville        Log.v(mName, s);
200058c73c3f76c231cf128041aefadd4b6a6bcefac2Wink Saville    }
200158c73c3f76c231cf128041aefadd4b6a6bcefac2Wink Saville
2002ff4fcdb98c9575642c48f1daeafff4b257769e81Wink Saville    /**
2003ff4fcdb98c9575642c48f1daeafff4b257769e81Wink Saville     * Log with info attribute
2004ff4fcdb98c9575642c48f1daeafff4b257769e81Wink Saville     *
2005ff4fcdb98c9575642c48f1daeafff4b257769e81Wink Saville     * @param s is string log
2006ff4fcdb98c9575642c48f1daeafff4b257769e81Wink Saville     */
200758c73c3f76c231cf128041aefadd4b6a6bcefac2Wink Saville    protected void logi(String s) {
200858c73c3f76c231cf128041aefadd4b6a6bcefac2Wink Saville        Log.i(mName, s);
200958c73c3f76c231cf128041aefadd4b6a6bcefac2Wink Saville    }
201058c73c3f76c231cf128041aefadd4b6a6bcefac2Wink Saville
2011ff4fcdb98c9575642c48f1daeafff4b257769e81Wink Saville    /**
2012ff4fcdb98c9575642c48f1daeafff4b257769e81Wink Saville     * Log with warning attribute
2013ff4fcdb98c9575642c48f1daeafff4b257769e81Wink Saville     *
2014ff4fcdb98c9575642c48f1daeafff4b257769e81Wink Saville     * @param s is string log
2015ff4fcdb98c9575642c48f1daeafff4b257769e81Wink Saville     */
201658c73c3f76c231cf128041aefadd4b6a6bcefac2Wink Saville    protected void logw(String s) {
201758c73c3f76c231cf128041aefadd4b6a6bcefac2Wink Saville        Log.w(mName, s);
201858c73c3f76c231cf128041aefadd4b6a6bcefac2Wink Saville    }
201958c73c3f76c231cf128041aefadd4b6a6bcefac2Wink Saville
2020ff4fcdb98c9575642c48f1daeafff4b257769e81Wink Saville    /**
2021ff4fcdb98c9575642c48f1daeafff4b257769e81Wink Saville     * Log with error attribute
2022ff4fcdb98c9575642c48f1daeafff4b257769e81Wink Saville     *
2023ff4fcdb98c9575642c48f1daeafff4b257769e81Wink Saville     * @param s is string log
2024ff4fcdb98c9575642c48f1daeafff4b257769e81Wink Saville     */
202558c73c3f76c231cf128041aefadd4b6a6bcefac2Wink Saville    protected void loge(String s) {
202658c73c3f76c231cf128041aefadd4b6a6bcefac2Wink Saville        Log.e(mName, s);
202758c73c3f76c231cf128041aefadd4b6a6bcefac2Wink Saville    }
2028ff4fcdb98c9575642c48f1daeafff4b257769e81Wink Saville
2029ff4fcdb98c9575642c48f1daeafff4b257769e81Wink Saville    /**
2030ff4fcdb98c9575642c48f1daeafff4b257769e81Wink Saville     * Log with error attribute
2031ff4fcdb98c9575642c48f1daeafff4b257769e81Wink Saville     *
2032ff4fcdb98c9575642c48f1daeafff4b257769e81Wink Saville     * @param s is string log
2033ff4fcdb98c9575642c48f1daeafff4b257769e81Wink Saville     * @param e is a Throwable which logs additional information.
2034ff4fcdb98c9575642c48f1daeafff4b257769e81Wink Saville     */
2035ff4fcdb98c9575642c48f1daeafff4b257769e81Wink Saville    protected void loge(String s, Throwable e) {
2036ff4fcdb98c9575642c48f1daeafff4b257769e81Wink Saville        Log.e(mName, s, e);
2037ff4fcdb98c9575642c48f1daeafff4b257769e81Wink Saville    }
2038fc5b4802a544b6ca304aa7e58a26018ef714d233Wink Saville}
2039