Merge "Enhance StateMachine Quitting and logging support. DO NOT MERGE" into jb-dev-plus-aosp
diff --git a/core/java/android/bluetooth/BluetoothDeviceProfileState.java b/core/java/android/bluetooth/BluetoothDeviceProfileState.java
index c9603bf..020f051 100644
--- a/core/java/android/bluetooth/BluetoothDeviceProfileState.java
+++ b/core/java/android/bluetooth/BluetoothDeviceProfileState.java
@@ -304,6 +304,25 @@
         }
     }
 
+    @Override
+    protected void onQuitting() {
+        mContext.unregisterReceiver(mBroadcastReceiver);
+        mBroadcastReceiver = null;
+        mAdapter.closeProfileProxy(BluetoothProfile.HEADSET, mHeadsetService);
+        mBluetoothProfileServiceListener = null;
+        mOutgoingHandsfree = null;
+        mPbap = null;
+        mPbapService.close();
+        mPbapService = null;
+        mIncomingHid = null;
+        mOutgoingHid = null;
+        mIncomingHandsfree = null;
+        mOutgoingHandsfree = null;
+        mIncomingA2dp = null;
+        mOutgoingA2dp = null;
+        mBondedDevice = null;
+    }
+
     private class BondedDevice extends State {
         @Override
         public void enter() {
@@ -416,26 +435,6 @@
                 case TRANSITION_TO_STABLE:
                     // ignore.
                     break;
-                case SM_QUIT_CMD:
-                    mContext.unregisterReceiver(mBroadcastReceiver);
-                    mBroadcastReceiver = null;
-                    mAdapter.closeProfileProxy(BluetoothProfile.HEADSET, mHeadsetService);
-                    mBluetoothProfileServiceListener = null;
-                    mOutgoingHandsfree = null;
-                    mPbap = null;
-                    mPbapService.close();
-                    mPbapService = null;
-                    mIncomingHid = null;
-                    mOutgoingHid = null;
-                    mIncomingHandsfree = null;
-                    mOutgoingHandsfree = null;
-                    mIncomingA2dp = null;
-                    mOutgoingA2dp = null;
-                    mBondedDevice = null;
-                    // There is a problem in the State Machine code
-                    // where things are not cleaned up properly, when quit message
-                    // is handled so return NOT_HANDLED as a workaround.
-                    return NOT_HANDLED;
                 default:
                     return NOT_HANDLED;
             }
@@ -1341,6 +1340,15 @@
         return mDevice;
     }
 
+    /**
+     * Quit the state machine, only to be called by BluetoothService.
+     *
+     * @hide
+     */
+    public void doQuit() {
+        this.quit();
+    }
+
     private void log(String message) {
         if (DBG) {
             Log.i(TAG, "Device:" + mDevice + " Message:" + message);
diff --git a/core/java/android/net/DhcpStateMachine.java b/core/java/android/net/DhcpStateMachine.java
index 397a12a..cc3e34f 100644
--- a/core/java/android/net/DhcpStateMachine.java
+++ b/core/java/android/net/DhcpStateMachine.java
@@ -163,8 +163,21 @@
         mRegisteredForPreDhcpNotification = true;
     }
 
+    /**
+     * Quit the DhcpStateMachine.
+     *
+     * @hide
+     */
+    public void doQuit() {
+        quit();
+    }
+
     class DefaultState extends State {
         @Override
+        public void exit() {
+            mContext.unregisterReceiver(mBroadcastReceiver);
+        }
+        @Override
         public boolean processMessage(Message message) {
             if (DBG) Log.d(TAG, getName() + message.toString() + "\n");
             switch (message.what) {
@@ -172,10 +185,6 @@
                     Log.e(TAG, "Error! Failed to handle a DHCP renewal on " + mInterfaceName);
                     mDhcpRenewWakeLock.release();
                     break;
-                case SM_QUIT_CMD:
-                    mContext.unregisterReceiver(mBroadcastReceiver);
-                    //let parent kill the state machine
-                    return NOT_HANDLED;
                 default:
                     Log.e(TAG, "Error! unhandled message  " + message);
                     break;
diff --git a/core/java/android/server/BluetoothService.java b/core/java/android/server/BluetoothService.java
index 97c0209..6296b11 100755
--- a/core/java/android/server/BluetoothService.java
+++ b/core/java/android/server/BluetoothService.java
@@ -2448,7 +2448,7 @@
         BluetoothDeviceProfileState state = mDeviceProfileState.get(address);
         if (state == null) return;
 
-        state.quit();
+        state.doQuit();
         mDeviceProfileState.remove(address);
     }
 
diff --git a/core/java/com/android/internal/util/StateMachine.java b/core/java/com/android/internal/util/StateMachine.java
index 1391ac3..0ea7b83 100644
--- a/core/java/com/android/internal/util/StateMachine.java
+++ b/core/java/com/android/internal/util/StateMachine.java
@@ -80,9 +80,9 @@
  * and invoke <code>halting</code>. Any message subsequently received by the state
  * machine will cause <code>haltedProcessMessage</code> to be invoked.</p>
  *
- * <p>If it is desirable to completely stop the state machine call <code>quit</code>. This
- * will exit the current state and its parent and then exit from the controlling thread
- * and no further messages will be processed.</p>
+ * <p>If it is desirable to completely stop the state machine call <code>quit</code> or
+ * <code>abort</code>. These will call <code>exit</code> of the current state and its parents, call
+ * <code>onQuiting</code> and then exit Thread/Loopers.</p>
  *
  * <p>In addition to <code>processMessage</code> each <code>State</code> has
  * an <code>enter</code> method and <code>exit</exit> method which may be overridden.</p>
@@ -362,7 +362,7 @@
     }
 
     &#64;Override
-    void halting() {
+    void onHalting() {
         Log.d(TAG, "halting");
         synchronized (this) {
             this.notifyAll();
@@ -423,10 +423,10 @@
     private String mName;
 
     /** Message.what value when quitting */
-    public static final int SM_QUIT_CMD = -1;
+    private static final int SM_QUIT_CMD = -1;
 
     /** Message.what value when initializing */
-    public static final int SM_INIT_CMD = -2;
+    private static final int SM_INIT_CMD = -2;
 
     /**
      * Convenience constant that maybe returned by processMessage
@@ -443,11 +443,10 @@
     public static final boolean NOT_HANDLED = false;
 
     /**
+     * StateMachine logging record.
      * {@hide}
-     *
-     * The information maintained for a processed message.
      */
-    public static class ProcessedMessageInfo {
+    public static class LogRec {
         private long mTime;
         private int mWhat;
         private String mInfo;
@@ -456,12 +455,13 @@
 
         /**
          * Constructor
-         * @param message
+         *
+         * @param msg
          * @param state that handled the message
          * @param orgState is the first state the received the message but
          * did not processes the message.
          */
-        ProcessedMessageInfo(Message msg, String info, State state, State orgState) {
+        LogRec(Message msg, String info, State state, State orgState) {
             update(msg, info, state, orgState);
         }
 
@@ -473,7 +473,7 @@
          */
         public void update(Message msg, String info, State state, State orgState) {
             mTime = System.currentTimeMillis();
-            mWhat = msg.what;
+            mWhat = (msg != null) ? msg.what : 0;
             mInfo = info;
             mState = state;
             mOrgState = orgState;
@@ -517,8 +517,7 @@
         /**
          * @return as string
          */
-        @Override
-        public String toString() {
+        public String toString(StateMachine sm) {
             StringBuilder sb = new StringBuilder();
             sb.append("time=");
             Calendar c = Calendar.getInstance();
@@ -529,10 +528,15 @@
             sb.append(" orgState=");
             sb.append(mOrgState == null ? "<null>" : mOrgState.getName());
             sb.append(" what=");
-            sb.append(mWhat);
-            sb.append("(0x");
-            sb.append(Integer.toHexString(mWhat));
-            sb.append(")");
+            String what = sm.getWhatToString(mWhat);
+            if (TextUtils.isEmpty(what)) {
+                sb.append(mWhat);
+                sb.append("(0x");
+                sb.append(Integer.toHexString(mWhat));
+                sb.append(")");
+            } else {
+                sb.append(what);
+            }
             if ( ! TextUtils.isEmpty(mInfo)) {
                 sb.append(" ");
                 sb.append(mInfo);
@@ -542,21 +546,21 @@
     }
 
     /**
-     * A list of messages recently processed by the state machine.
+     * A list of log records including messages recently processed by the state machine.
      *
-     * The class maintains a list of messages that have been most
+     * The class maintains a list of log records including messages
      * recently processed. The list is finite and may be set in the
      * constructor or by calling setSize. The public interface also
-     * includes size which returns the number of recent messages,
-     * count which is the number of message processed since the
-     * the last setSize, get which returns a processed message and
-     * add which adds a processed messaged.
+     * includes size which returns the number of recent records,
+     * count which is the number of records processed since the
+     * the last setSize, get which returns a record and
+     * add which adds a record.
      */
-    private static class ProcessedMessages {
+    private static class LogRecords {
 
         private static final int DEFAULT_SIZE = 20;
 
-        private Vector<ProcessedMessageInfo> mMessages = new Vector<ProcessedMessageInfo>();
+        private Vector<LogRec> mLogRecords = new Vector<LogRec>();
         private int mMaxSize = DEFAULT_SIZE;
         private int mOldestIndex = 0;
         private int mCount = 0;
@@ -564,39 +568,39 @@
         /**
          * private constructor use add
          */
-        private ProcessedMessages() {
+        private LogRecords() {
         }
 
         /**
-         * Set size of messages to maintain and clears all current messages.
+         * Set size of messages to maintain and clears all current records.
          *
-         * @param maxSize number of messages to maintain at anyone time.
+         * @param maxSize number of records to maintain at anyone time.
         */
-        void setSize(int maxSize) {
+        synchronized void setSize(int maxSize) {
             mMaxSize = maxSize;
             mCount = 0;
-            mMessages.clear();
+            mLogRecords.clear();
         }
 
         /**
-         * @return the number of recent messages.
+         * @return the number of recent records.
          */
-        int size() {
-            return mMessages.size();
+        synchronized int size() {
+            return mLogRecords.size();
         }
 
         /**
-         * @return the total number of messages processed since size was set.
+         * @return the total number of records processed since size was set.
          */
-        int count() {
+        synchronized int count() {
             return mCount;
         }
 
         /**
-         * Clear the list of Processed Message Info.
+         * Clear the list of records.
          */
-        void cleanup() {
-            mMessages.clear();
+        synchronized void cleanup() {
+            mLogRecords.clear();
         }
 
         /**
@@ -604,7 +608,7 @@
          * record and size()-1 is the newest record. If the index is to
          * large null is returned.
          */
-        ProcessedMessageInfo get(int index) {
+        synchronized LogRec get(int index) {
             int nextIndex = mOldestIndex + index;
             if (nextIndex >= mMaxSize) {
                 nextIndex -= mMaxSize;
@@ -612,7 +616,7 @@
             if (nextIndex >= size()) {
                 return null;
             } else {
-                return mMessages.get(nextIndex);
+                return mLogRecords.get(nextIndex);
             }
         }
 
@@ -625,12 +629,12 @@
          * @param orgState is the first state the received the message but
          * did not processes the message.
          */
-        void add(Message msg, String messageInfo, State state, State orgState) {
+        synchronized void add(Message msg, String messageInfo, State state, State orgState) {
             mCount += 1;
-            if (mMessages.size() < mMaxSize) {
-                mMessages.add(new ProcessedMessageInfo(msg, messageInfo, state, orgState));
+            if (mLogRecords.size() < mMaxSize) {
+                mLogRecords.add(new LogRec(msg, messageInfo, state, orgState));
             } else {
-                ProcessedMessageInfo pmi = mMessages.get(mOldestIndex);
+                LogRec pmi = mLogRecords.get(mOldestIndex);
                 mOldestIndex += 1;
                 if (mOldestIndex >= mMaxSize) {
                     mOldestIndex = 0;
@@ -652,8 +656,8 @@
         /** The current message */
         private Message mMsg;
 
-        /** A list of messages that this state machine has processed */
-        private ProcessedMessages mProcessedMessages = new ProcessedMessages();
+        /** A list of log records including messages this state machine has processed */
+        private LogRecords mLogRecords = new LogRecords();
 
         /** true if construction of the state machine has not been completed */
         private boolean mIsConstructionCompleted;
@@ -814,15 +818,18 @@
              */
             if (destState != null) {
                 if (destState == mQuittingState) {
+                    /**
+                     * Call onQuitting to let subclasses cleanup.
+                     */
+                    mSm.onQuitting();
                     cleanupAfterQuitting();
-
                 } else if (destState == mHaltingState) {
                     /**
-                     * Call halting() if we've transitioned to the halting
+                     * Call onHalting() if we've transitioned to the halting
                      * state. All subsequent messages will be processed in
                      * in the halting state which invokes haltedProcessMessage(msg);
                      */
-                    mSm.halting();
+                    mSm.onHalting();
                 }
             }
         }
@@ -831,7 +838,6 @@
          * Cleanup all the static variables and the looper after the SM has been quit.
          */
         private final void cleanupAfterQuitting() {
-            mSm.quitting();
             if (mSm.mSmThread != null) {
                 // If we made the thread then quit looper which stops the thread.
                 getLooper().quit();
@@ -841,7 +847,7 @@
             mSm.mSmHandler = null;
             mSm = null;
             mMsg = null;
-            mProcessedMessages.cleanup();
+            mLogRecords.cleanup();
             mStateStack = null;
             mTempStateStack = null;
             mStateInfo.clear();
@@ -892,36 +898,38 @@
             if (mDbg) {
                 Log.d(TAG, "processMsg: " + curStateInfo.state.getName());
             }
-            while (!curStateInfo.state.processMessage(msg)) {
-                /**
-                 * Not processed
-                 */
-                curStateInfo = curStateInfo.parentStateInfo;
-                if (curStateInfo == null) {
-                    /**
-                     * No parents left so it's not handled
-                     */
-                    mSm.unhandledMessage(msg);
-                    if (isQuit(msg)) {
-                        transitionTo(mQuittingState);
-                    }
-                    break;
-                }
-                if (mDbg) {
-                    Log.d(TAG, "processMsg: " + curStateInfo.state.getName());
-                }
-            }
 
-            /**
-             * Record that we processed the message
-             */
-            if (mSm.recordProcessedMessage(msg)) {
-                if (curStateInfo != null) {
-                    State orgState = mStateStack[mStateStackTopIndex].state;
-                    mProcessedMessages.add(msg, mSm.getMessageInfo(msg), curStateInfo.state,
-                            orgState);
-                } else {
-                    mProcessedMessages.add(msg, mSm.getMessageInfo(msg), null, null);
+            if (isQuit(msg)) {
+                transitionTo(mQuittingState);
+            } else {
+                while (!curStateInfo.state.processMessage(msg)) {
+                    /**
+                     * Not processed
+                     */
+                    curStateInfo = curStateInfo.parentStateInfo;
+                    if (curStateInfo == null) {
+                        /**
+                         * No parents left so it's not handled
+                         */
+                        mSm.unhandledMessage(msg);
+                        break;
+                    }
+                    if (mDbg) {
+                        Log.d(TAG, "processMsg: " + curStateInfo.state.getName());
+                    }
+                }
+
+                /**
+                 * Record that we processed the message
+                 */
+                if (mSm.recordLogRec(msg)) {
+                    if (curStateInfo != null) {
+                        State orgState = mStateStack[mStateStackTopIndex].state;
+                        mLogRecords.add(msg, mSm.getLogRecString(msg), curStateInfo.state,
+                                orgState);
+                    } else {
+                        mLogRecords.add(msg, mSm.getLogRecString(msg), null, null);
+                    }
                 }
             }
         }
@@ -1141,13 +1149,19 @@
             mDeferredMessages.add(newMsg);
         }
 
-        /** @see StateMachine#deferMessage(Message) */
+        /** @see StateMachine#quit() */
         private final void quit() {
             if (mDbg) Log.d(TAG, "quit:");
             sendMessage(obtainMessage(SM_QUIT_CMD, mSmHandlerObj));
         }
 
-        /** @see StateMachine#isQuit(Message) */
+        /** @see StateMachine#quitNow() */
+        private final void quitNow() {
+            if (mDbg) Log.d(TAG, "abort:");
+            sendMessageAtFrontOfQueue(obtainMessage(SM_QUIT_CMD, mSmHandlerObj));
+        }
+
+        /** Validate that the message was sent by quit or abort. */
         private final boolean isQuit(Message msg) {
             return (msg.what == SM_QUIT_CMD) && (msg.obj == mSmHandlerObj);
         }
@@ -1162,26 +1176,6 @@
             mDbg = dbg;
         }
 
-        /** @see StateMachine#setProcessedMessagesSize(int) */
-        private final void setProcessedMessagesSize(int maxSize) {
-            mProcessedMessages.setSize(maxSize);
-        }
-
-        /** @see StateMachine#getProcessedMessagesSize() */
-        private final int getProcessedMessagesSize() {
-            return mProcessedMessages.size();
-        }
-
-        /** @see StateMachine#getProcessedMessagesCount() */
-        private final int getProcessedMessagesCount() {
-            return mProcessedMessages.count();
-        }
-
-        /** @see StateMachine#getProcessedMessageInfo(int) */
-        private final ProcessedMessageInfo getProcessedMessageInfo(int index) {
-            return mProcessedMessages.get(index);
-        }
-
     }
 
     private SmHandler mSmHandler;
@@ -1282,8 +1276,8 @@
     /**
      * transition to halt state. Upon returning
      * from processMessage we will exit all current
-     * states, execute the halting() method and then
-     * all subsequent messages haltedProcessMesage
+     * states, execute the onHalting() method and then
+     * for all subsequent messages haltedProcessMessage
      * will be called.
      */
     protected final void transitionToHaltingState() {
@@ -1303,7 +1297,6 @@
         mSmHandler.deferMessage(msg);
     }
 
-
     /**
      * Called when message wasn't handled
      *
@@ -1325,7 +1318,7 @@
      * transitionToHalting. All subsequent messages will invoke
      * {@link StateMachine#haltedProcessMessage(Message)}
      */
-    protected void halting() {
+    protected void onHalting() {
     }
 
     /**
@@ -1334,7 +1327,7 @@
      * ignored. In addition, if this StateMachine created the thread, the thread will
      * be stopped after this method returns.
      */
-    protected void quitting() {
+    protected void onQuitting() {
     }
 
     /**
@@ -1345,33 +1338,77 @@
     }
 
     /**
-     * Set size of messages to maintain and clears all current messages.
+     * Set number of log records to maintain and clears all current records.
      *
      * @param maxSize number of messages to maintain at anyone time.
      */
-    public final void setProcessedMessagesSize(int maxSize) {
-        mSmHandler.setProcessedMessagesSize(maxSize);
+    public final void setLogRecSize(int maxSize) {
+        mSmHandler.mLogRecords.setSize(maxSize);
     }
 
     /**
-     * @return number of messages processed
+     * @return number of log records
      */
-    public final int getProcessedMessagesSize() {
-        return mSmHandler.getProcessedMessagesSize();
+    public final int getLogRecSize() {
+        return mSmHandler.mLogRecords.size();
     }
 
     /**
-     * @return the total number of messages processed
+     * @return the total number of records processed
      */
-    public final int getProcessedMessagesCount() {
-        return mSmHandler.getProcessedMessagesCount();
+    public final int getLogRecCount() {
+        return mSmHandler.mLogRecords.count();
     }
 
     /**
-     * @return a processed message information
+     * @return a log record
      */
-    public final ProcessedMessageInfo getProcessedMessageInfo(int index) {
-        return mSmHandler.getProcessedMessageInfo(index);
+    public final LogRec getLogRec(int index) {
+        return mSmHandler.mLogRecords.get(index);
+    }
+
+    /**
+     * Add the string to LogRecords.
+     *
+     * @param string
+     */
+    protected void addLogRec(String string) {
+        mSmHandler.mLogRecords.add(null, string, null, null);
+    }
+
+    /**
+     * Add the string and state to LogRecords
+     *
+     * @param string
+     * @param state current state
+     */
+    protected void addLogRec(String string, State state) {
+        mSmHandler.mLogRecords.add(null, string, state, null);
+    }
+
+    /**
+     * @return true if msg should be saved in the log, default is true.
+     */
+    protected boolean recordLogRec(Message msg) {
+        return true;
+    }
+
+    /**
+     * Return a string to be logged by LogRec, default
+     * is an empty string. Override if additional information is desired.
+     *
+     * @param msg that was processed
+     * @return information to be logged as a String
+     */
+    protected String getLogRecString(Message msg) {
+        return "";
+    }
+
+    /**
+     * @return the string for msg.what
+     */
+    protected String getWhatToString(int what) {
+        return null;
     }
 
     /**
@@ -1548,43 +1585,23 @@
     }
 
     /**
-     * Conditionally quit the looper and stop execution.
-     *
-     * This sends the SM_QUIT_MSG to the state machine and
-     * if not handled by any state's processMessage then the
-     * state machine will be stopped and no further messages
-     * will be processed.
+     * Quit the state machine after all currently queued up messages are processed.
      */
-    public final void quit() {
-        // mSmHandler can be null if the state machine has quit.
+    protected final void quit() {
+        // mSmHandler can be null if the state machine is already stopped.
         if (mSmHandler == null) return;
 
         mSmHandler.quit();
     }
 
     /**
-     * @return ture if msg is quit
+     * Quit the state machine immediately all currently queued messages will be discarded.
      */
-    protected final boolean isQuit(Message msg) {
-        return mSmHandler.isQuit(msg);
-    }
+    protected final void quitNow() {
+        // mSmHandler can be null if the state machine is already stopped.
+        if (mSmHandler == null) return;
 
-    /**
-     * @return true if msg should be saved in ProcessedMessage, default is true.
-     */
-    protected boolean recordProcessedMessage(Message msg) {
-        return true;
-    }
-
-    /**
-     * Return message info to be logged by ProcessedMessageInfo, default
-     * is an empty string. Override if additional information is desired.
-     *
-     * @param msg that was processed
-     * @return information to be logged as a String
-     */
-    protected String getMessageInfo(Message msg) {
-        return "";
+        mSmHandler.quitNow();
     }
 
     /**
@@ -1629,9 +1646,9 @@
      */
     public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
         pw.println(getName() + ":");
-        pw.println(" total messages=" + getProcessedMessagesCount());
-        for (int i=0; i < getProcessedMessagesSize(); i++) {
-            pw.printf(" msg[%d]: %s\n", i, getProcessedMessageInfo(i));
+        pw.println(" total records=" + getLogRecCount());
+        for (int i=0; i < getLogRecSize(); i++) {
+            pw.printf(" rec[%d]: %s\n", i, getLogRec(i).toString(this));
             pw.flush();
         }
         pw.println("curState=" + getCurrentState().getName());
diff --git a/core/tests/coretests/src/com/android/internal/util/StateMachineTest.java b/core/tests/coretests/src/com/android/internal/util/StateMachineTest.java
index ab6b2b6..418bbd6 100644
--- a/core/tests/coretests/src/com/android/internal/util/StateMachineTest.java
+++ b/core/tests/coretests/src/com/android/internal/util/StateMachineTest.java
@@ -24,7 +24,7 @@
 
 import com.android.internal.util.State;
 import com.android.internal.util.StateMachine;
-import com.android.internal.util.StateMachine.ProcessedMessageInfo;
+import com.android.internal.util.StateMachine.LogRec;
 
 import android.test.suitebuilder.annotation.MediumTest;
 import android.test.suitebuilder.annotation.SmallTest;
@@ -36,6 +36,10 @@
  * Test for StateMachine.
  */
 public class StateMachineTest extends TestCase {
+    private static final String ENTER = "enter";
+    private static final String EXIT = "exit";
+    private static final String ON_QUITTING = "ON_QUITTING";
+
     private static final int TEST_CMD_1 = 1;
     private static final int TEST_CMD_2 = 2;
     private static final int TEST_CMD_3 = 3;
@@ -47,11 +51,18 @@
     private static final boolean WAIT_FOR_DEBUGGER = false;
     private static final String TAG = "StateMachineTest";
 
+    private void sleep(int millis) {
+        try {
+            Thread.sleep(millis);
+        } catch(InterruptedException e) {
+        }
+    }
+
     /**
-     * Tests that we can quit the state machine.
+     * Tests {@link StateMachine#quit()}.
      */
     class StateMachineQuitTest extends StateMachine {
-        private int mQuitCount = 0;
+        Object mWaitUntilTestDone = new Object();
 
         StateMachineQuitTest(String name) {
             super(name);
@@ -65,29 +76,45 @@
             setInitialState(mS1);
         }
 
-        class S1 extends State {
-            @Override
-            public boolean processMessage(Message message) {
-                if (isQuit(message)) {
-                    mQuitCount += 1;
-                    if (mQuitCount > 2) {
-                        // Returning NOT_HANDLED to actually quit
-                        return NOT_HANDLED;
-                    } else {
-                        // Do NOT quit
-                        return HANDLED;
-                    }
-                } else  {
-                    // All other message are handled
-                    return HANDLED;
+        @Override
+        public void onQuitting() {
+            Log.d(TAG, "onQuitting");
+            addLogRec(ON_QUITTING);
+            synchronized (mThisSm) {
+                mThisSm.notifyAll();
+            }
+
+            // Don't leave onQuitting before the test is done as everything is cleared
+            // including the log records.
+            synchronized (mWaitUntilTestDone) {
+                try {
+                    mWaitUntilTestDone.wait();
+                } catch(InterruptedException e) {
                 }
             }
         }
 
-        @Override
-        protected void quitting() {
-            synchronized (mThisSm) {
-                mThisSm.notifyAll();
+        class S1 extends State {
+            public void exit() {
+                Log.d(TAG, "S1.exit");
+                addLogRec(EXIT, mS1);
+            }
+            @Override
+            public boolean processMessage(Message message) {
+                switch(message.what) {
+                    // Sleep and assume the other messages will be queued up.
+                    case TEST_CMD_1: {
+                        Log.d(TAG, "TEST_CMD_1");
+                        sleep(500);
+                        quit();
+                        break;
+                    }
+                    default: {
+                        Log.d(TAG, "default what=" + message.what);
+                        break;
+                    }
+                }
+                return HANDLED;
             }
         }
 
@@ -96,62 +123,167 @@
     }
 
     @SmallTest
-    public void testStateMachineQuitTest() throws Exception {
+    public void testStateMachineQuit() throws Exception {
         if (WAIT_FOR_DEBUGGER) Debug.waitForDebugger();
 
         StateMachineQuitTest smQuitTest = new StateMachineQuitTest("smQuitTest");
         smQuitTest.start();
-        if (smQuitTest.isDbg()) Log.d(TAG, "testStateMachineQuitTest E");
+        if (smQuitTest.isDbg()) Log.d(TAG, "testStateMachineQuit E");
 
         synchronized (smQuitTest) {
-            // Send 6 messages
+
+            // Send 6 message we'll quit on the first but all 6 should be processed before quitting.
             for (int i = 1; i <= 6; i++) {
-                smQuitTest.sendMessage(i);
+                smQuitTest.sendMessage(smQuitTest.obtainMessage(i));
             }
 
-            // First two are ignored
-            smQuitTest.quit();
-            smQuitTest.quit();
-
-            // Now we will quit
-            smQuitTest.quit();
-
             try {
                 // wait for the messages to be handled
                 smQuitTest.wait();
             } catch (InterruptedException e) {
-                Log.e(TAG, "testStateMachineQuitTest: exception while waiting " + e.getMessage());
+                Log.e(TAG, "testStateMachineQuit: exception while waiting " + e.getMessage());
             }
         }
 
-        assertTrue(smQuitTest.getProcessedMessagesCount() == 9);
+        assertEquals(8, smQuitTest.getLogRecCount());
 
-        ProcessedMessageInfo pmi;
+        LogRec lr;
 
-        // The first two message didn't quit and were handled by mS1
-        pmi = smQuitTest.getProcessedMessageInfo(6);
-        assertEquals(StateMachine.SM_QUIT_CMD, pmi.getWhat());
-        assertEquals(smQuitTest.mS1, pmi.getState());
-        assertEquals(smQuitTest.mS1, pmi.getOriginalState());
+        for (int i = 0; i < 6; i++) {
+            lr = smQuitTest.getLogRec(i);
+            assertEquals(i+1, lr.getWhat());
+            assertEquals(smQuitTest.mS1, lr.getState());
+            assertEquals(smQuitTest.mS1, lr.getOriginalState());
+        }
+        lr = smQuitTest.getLogRec(6);
+        assertEquals(EXIT, lr.getInfo());
+        assertEquals(smQuitTest.mS1, lr.getState());
 
-        pmi = smQuitTest.getProcessedMessageInfo(7);
-        assertEquals(StateMachine.SM_QUIT_CMD, pmi.getWhat());
-        assertEquals(smQuitTest.mS1, pmi.getState());
-        assertEquals(smQuitTest.mS1, pmi.getOriginalState());
+        lr = smQuitTest.getLogRec(7);
+        assertEquals(ON_QUITTING, lr.getInfo());
 
-        // The last message was never handled so the states are null
-        pmi = smQuitTest.getProcessedMessageInfo(8);
-        assertEquals(StateMachine.SM_QUIT_CMD, pmi.getWhat());
-        assertEquals(null, pmi.getState());
-        assertEquals(null, pmi.getOriginalState());
+        synchronized (smQuitTest.mWaitUntilTestDone) {
+            smQuitTest.mWaitUntilTestDone.notifyAll();
+        }
+        if (smQuitTest.isDbg()) Log.d(TAG, "testStateMachineQuit X");
+    }
 
-        if (smQuitTest.isDbg()) Log.d(TAG, "testStateMachineQuitTest X");
+    /**
+     * Tests {@link StateMachine#quitNow()}
+     */
+    class StateMachineQuitNowTest extends StateMachine {
+        Object mWaitUntilTestDone = new Object();
+
+        StateMachineQuitNowTest(String name) {
+            super(name);
+            mThisSm = this;
+            setDbg(DBG);
+
+            // Setup state machine with 1 state
+            addState(mS1);
+
+            // Set the initial state
+            setInitialState(mS1);
+        }
+
+        @Override
+        public void onQuitting() {
+            Log.d(TAG, "onQuitting");
+            addLogRec(ON_QUITTING);
+            synchronized (mThisSm) {
+                mThisSm.notifyAll();
+            }
+
+            // Don't leave onQuitting before the test is done as everything is cleared
+            // including the log records.
+            synchronized (mWaitUntilTestDone) {
+                try {
+                    mWaitUntilTestDone.wait();
+                } catch(InterruptedException e) {
+                }
+            }
+        }
+
+        class S1 extends State {
+            public void exit() {
+                Log.d(TAG, "S1.exit");
+                addLogRec(EXIT, mS1);
+            }
+            @Override
+            public boolean processMessage(Message message) {
+                switch(message.what) {
+                    // Sleep and assume the other messages will be queued up.
+                    case TEST_CMD_1: {
+                        Log.d(TAG, "TEST_CMD_1");
+                        sleep(500);
+                        quitNow();
+                        break;
+                    }
+                    default: {
+                        Log.d(TAG, "default what=" + message.what);
+                        break;
+                    }
+                }
+                return HANDLED;
+            }
+        }
+
+        private StateMachineQuitNowTest mThisSm;
+        private S1 mS1 = new S1();
+    }
+
+    @SmallTest
+    public void testStateMachineQuitNow() throws Exception {
+        if (WAIT_FOR_DEBUGGER) Debug.waitForDebugger();
+
+        StateMachineQuitNowTest smQuitNowTest = new StateMachineQuitNowTest("smQuitNowTest");
+        smQuitNowTest.start();
+        if (smQuitNowTest.isDbg()) Log.d(TAG, "testStateMachineQuitNow E");
+
+        synchronized (smQuitNowTest) {
+
+            // Send 6 messages but we'll QuitNow on the first so even though
+            // we send 6 only one will be processed.
+            for (int i = 1; i <= 6; i++) {
+                smQuitNowTest.sendMessage(smQuitNowTest.obtainMessage(i));
+            }
+
+            try {
+                // wait for the messages to be handled
+                smQuitNowTest.wait();
+            } catch (InterruptedException e) {
+                Log.e(TAG, "testStateMachineQuitNow: exception while waiting " + e.getMessage());
+            }
+        }
+
+        // Only three records because we executed quitNow.
+        assertEquals(3, smQuitNowTest.getLogRecCount());
+
+        LogRec lr;
+
+        lr = smQuitNowTest.getLogRec(0);
+        assertEquals(1, lr.getWhat());
+        assertEquals(smQuitNowTest.mS1, lr.getState());
+        assertEquals(smQuitNowTest.mS1, lr.getOriginalState());
+
+        lr = smQuitNowTest.getLogRec(1);
+        assertEquals(EXIT, lr.getInfo());
+        assertEquals(smQuitNowTest.mS1, lr.getState());
+
+        lr = smQuitNowTest.getLogRec(2);
+        assertEquals(ON_QUITTING, lr.getInfo());
+
+        synchronized (smQuitNowTest.mWaitUntilTestDone) {
+            smQuitNowTest.mWaitUntilTestDone.notifyAll();
+        }
+        if (smQuitNowTest.isDbg()) Log.d(TAG, "testStateMachineQuitNow X");
     }
 
     /**
      * Test enter/exit can use transitionTo
      */
     class StateMachineEnterExitTransitionToTest extends StateMachine {
+
         StateMachineEnterExitTransitionToTest(String name) {
             super(name);
             mThisSm = this;
@@ -170,20 +302,15 @@
         class S1 extends State {
             @Override
             public void enter() {
-                // Test that message is HSM_INIT_CMD
-                assertEquals(SM_INIT_CMD, getCurrentMessage().what);
-
-                // Test that a transition in enter and the initial state works
-                mS1EnterCount += 1;
+                // Test transitions in enter on the initial state work
+                addLogRec(ENTER, mS1);
                 transitionTo(mS2);
                 Log.d(TAG, "S1.enter");
             }
             @Override
             public void exit() {
                 // Test that message is HSM_INIT_CMD
-                assertEquals(SM_INIT_CMD, getCurrentMessage().what);
-
-                mS1ExitCount += 1;
+                addLogRec(EXIT, mS1);
                 Log.d(TAG, "S1.exit");
             }
         }
@@ -191,19 +318,15 @@
         class S2 extends State {
             @Override
             public void enter() {
-                // Test that message is HSM_INIT_CMD
-                assertEquals(SM_INIT_CMD, getCurrentMessage().what);
-
-                mS2EnterCount += 1;
+                addLogRec(ENTER, mS2);
                 Log.d(TAG, "S2.enter");
             }
             @Override
             public void exit() {
-                // Test that message is TEST_CMD_1
+                addLogRec(EXIT, mS2);
                 assertEquals(TEST_CMD_1, getCurrentMessage().what);
 
                 // Test transition in exit work
-                mS2ExitCount += 1;
                 transitionTo(mS4);
                 Log.d(TAG, "S2.exit");
             }
@@ -220,36 +343,33 @@
         class S3 extends State {
             @Override
             public void enter() {
-                // Test that we can do halting in an enter/exit
-                transitionToHaltingState();
-                mS3EnterCount += 1;
+                addLogRec(ENTER, mS3);
                 Log.d(TAG, "S3.enter");
             }
             @Override
             public void exit() {
-                mS3ExitCount += 1;
+                addLogRec(EXIT, mS3);
                 Log.d(TAG, "S3.exit");
             }
         }
 
-
         class S4 extends State {
             @Override
             public void enter() {
+                addLogRec(ENTER, mS4);
                 // Test that we can do halting in an enter/exit
                 transitionToHaltingState();
-                mS4EnterCount += 1;
                 Log.d(TAG, "S4.enter");
             }
             @Override
             public void exit() {
-                mS4ExitCount += 1;
+                addLogRec(EXIT, mS4);
                 Log.d(TAG, "S4.exit");
             }
         }
 
         @Override
-        protected void halting() {
+        protected void onHalting() {
             synchronized (mThisSm) {
                 mThisSm.notifyAll();
             }
@@ -260,14 +380,6 @@
         private S2 mS2 = new S2();
         private S3 mS3 = new S3();
         private S4 mS4 = new S4();
-        private int mS1EnterCount = 0;
-        private int mS1ExitCount = 0;
-        private int mS2EnterCount = 0;
-        private int mS2ExitCount = 0;
-        private int mS3EnterCount = 0;
-        private int mS3ExitCount = 0;
-        private int mS4EnterCount = 0;
-        private int mS4ExitCount = 0;
     }
 
     @SmallTest
@@ -293,24 +405,46 @@
             }
         }
 
-        assertTrue(smEnterExitTranstionToTest.getProcessedMessagesCount() == 1);
+        assertEquals(smEnterExitTranstionToTest.getLogRecCount(), 9);
 
-        ProcessedMessageInfo pmi;
+        LogRec lr;
 
-        // Message should be handled by mS2.
-        pmi = smEnterExitTranstionToTest.getProcessedMessageInfo(0);
-        assertEquals(TEST_CMD_1, pmi.getWhat());
-        assertEquals(smEnterExitTranstionToTest.mS2, pmi.getState());
-        assertEquals(smEnterExitTranstionToTest.mS2, pmi.getOriginalState());
+        lr = smEnterExitTranstionToTest.getLogRec(0);
+        assertEquals(ENTER, lr.getInfo());
+        assertEquals(smEnterExitTranstionToTest.mS1, lr.getState());
 
-        assertEquals(smEnterExitTranstionToTest.mS1EnterCount, 1);
-        assertEquals(smEnterExitTranstionToTest.mS1ExitCount, 1);
-        assertEquals(smEnterExitTranstionToTest.mS2EnterCount, 1);
-        assertEquals(smEnterExitTranstionToTest.mS2ExitCount, 1);
-        assertEquals(smEnterExitTranstionToTest.mS3EnterCount, 1);
-        assertEquals(smEnterExitTranstionToTest.mS3ExitCount, 1);
-        assertEquals(smEnterExitTranstionToTest.mS3EnterCount, 1);
-        assertEquals(smEnterExitTranstionToTest.mS3ExitCount, 1);
+        lr = smEnterExitTranstionToTest.getLogRec(1);
+        assertEquals(EXIT, lr.getInfo());
+        assertEquals(smEnterExitTranstionToTest.mS1, lr.getState());
+
+        lr = smEnterExitTranstionToTest.getLogRec(2);
+        assertEquals(ENTER, lr.getInfo());
+        assertEquals(smEnterExitTranstionToTest.mS2, lr.getState());
+
+        lr = smEnterExitTranstionToTest.getLogRec(3);
+        assertEquals(TEST_CMD_1, lr.getWhat());
+        assertEquals(smEnterExitTranstionToTest.mS2, lr.getState());
+        assertEquals(smEnterExitTranstionToTest.mS2, lr.getOriginalState());
+
+        lr = smEnterExitTranstionToTest.getLogRec(4);
+        assertEquals(EXIT, lr.getInfo());
+        assertEquals(smEnterExitTranstionToTest.mS2, lr.getState());
+
+        lr = smEnterExitTranstionToTest.getLogRec(5);
+        assertEquals(ENTER, lr.getInfo());
+        assertEquals(smEnterExitTranstionToTest.mS3, lr.getState());
+
+        lr = smEnterExitTranstionToTest.getLogRec(6);
+        assertEquals(EXIT, lr.getInfo());
+        assertEquals(smEnterExitTranstionToTest.mS3, lr.getState());
+
+        lr = smEnterExitTranstionToTest.getLogRec(7);
+        assertEquals(ENTER, lr.getInfo());
+        assertEquals(smEnterExitTranstionToTest.mS4, lr.getState());
+
+        lr = smEnterExitTranstionToTest.getLogRec(8);
+        assertEquals(EXIT, lr.getInfo());
+        assertEquals(smEnterExitTranstionToTest.mS4, lr.getState());
 
         if (smEnterExitTranstionToTest.isDbg()) {
             Log.d(TAG, "testStateMachineEnterExitTransitionToTest X");
@@ -325,7 +459,7 @@
             super(name);
             mThisSm = this;
             setDbg(DBG);
-            setProcessedMessagesSize(3);
+            setLogRecSize(3);
 
             // Setup state machine with 1 state
             addState(mS1);
@@ -345,7 +479,7 @@
         }
 
         @Override
-        protected void halting() {
+        protected void onHalting() {
             synchronized (mThisSm) {
                 mThisSm.notifyAll();
             }
@@ -377,24 +511,24 @@
             }
         }
 
-        assertTrue(sm0.getProcessedMessagesCount() == 6);
-        assertTrue(sm0.getProcessedMessagesSize() == 3);
+        assertEquals(6, sm0.getLogRecCount());
+        assertEquals(3, sm0.getLogRecSize());
 
-        ProcessedMessageInfo pmi;
-        pmi = sm0.getProcessedMessageInfo(0);
-        assertEquals(TEST_CMD_4, pmi.getWhat());
-        assertEquals(sm0.mS1, pmi.getState());
-        assertEquals(sm0.mS1, pmi.getOriginalState());
+        LogRec lr;
+        lr = sm0.getLogRec(0);
+        assertEquals(TEST_CMD_4, lr.getWhat());
+        assertEquals(sm0.mS1, lr.getState());
+        assertEquals(sm0.mS1, lr.getOriginalState());
 
-        pmi = sm0.getProcessedMessageInfo(1);
-        assertEquals(TEST_CMD_5, pmi.getWhat());
-        assertEquals(sm0.mS1, pmi.getState());
-        assertEquals(sm0.mS1, pmi.getOriginalState());
+        lr = sm0.getLogRec(1);
+        assertEquals(TEST_CMD_5, lr.getWhat());
+        assertEquals(sm0.mS1, lr.getState());
+        assertEquals(sm0.mS1, lr.getOriginalState());
 
-        pmi = sm0.getProcessedMessageInfo(2);
-        assertEquals(TEST_CMD_6, pmi.getWhat());
-        assertEquals(sm0.mS1, pmi.getState());
-        assertEquals(sm0.mS1, pmi.getOriginalState());
+        lr = sm0.getLogRec(2);
+        assertEquals(TEST_CMD_6, lr.getWhat());
+        assertEquals(sm0.mS1, lr.getState());
+        assertEquals(sm0.mS1, lr.getOriginalState());
 
         if (sm0.isDbg()) Log.d(TAG, "testStateMachine0 X");
     }
@@ -444,7 +578,7 @@
         }
 
         @Override
-        protected void halting() {
+        protected void onHalting() {
             synchronized (mThisSm) {
                 mThisSm.notifyAll();
             }
@@ -479,18 +613,18 @@
         assertEquals(2, sm1.mEnterCount);
         assertEquals(2, sm1.mExitCount);
 
-        assertTrue(sm1.getProcessedMessagesSize() == 2);
+        assertEquals(2, sm1.getLogRecSize());
 
-        ProcessedMessageInfo pmi;
-        pmi = sm1.getProcessedMessageInfo(0);
-        assertEquals(TEST_CMD_1, pmi.getWhat());
-        assertEquals(sm1.mS1, pmi.getState());
-        assertEquals(sm1.mS1, pmi.getOriginalState());
+        LogRec lr;
+        lr = sm1.getLogRec(0);
+        assertEquals(TEST_CMD_1, lr.getWhat());
+        assertEquals(sm1.mS1, lr.getState());
+        assertEquals(sm1.mS1, lr.getOriginalState());
 
-        pmi = sm1.getProcessedMessageInfo(1);
-        assertEquals(TEST_CMD_2, pmi.getWhat());
-        assertEquals(sm1.mS1, pmi.getState());
-        assertEquals(sm1.mS1, pmi.getOriginalState());
+        lr = sm1.getLogRec(1);
+        assertEquals(TEST_CMD_2, lr.getWhat());
+        assertEquals(sm1.mS1, lr.getState());
+        assertEquals(sm1.mS1, lr.getOriginalState());
 
         assertEquals(2, sm1.mEnterCount);
         assertEquals(2, sm1.mExitCount);
@@ -550,7 +684,7 @@
         }
 
         @Override
-        protected void halting() {
+        protected void onHalting() {
             synchronized (mThisSm) {
                 mThisSm.notifyAll();
             }
@@ -583,24 +717,24 @@
             }
         }
 
-        assertTrue(sm2.getProcessedMessagesSize() == 4);
+        assertEquals(4, sm2.getLogRecSize());
 
-        ProcessedMessageInfo pmi;
-        pmi = sm2.getProcessedMessageInfo(0);
-        assertEquals(TEST_CMD_1, pmi.getWhat());
-        assertEquals(sm2.mS1, pmi.getState());
+        LogRec lr;
+        lr = sm2.getLogRec(0);
+        assertEquals(TEST_CMD_1, lr.getWhat());
+        assertEquals(sm2.mS1, lr.getState());
 
-        pmi = sm2.getProcessedMessageInfo(1);
-        assertEquals(TEST_CMD_2, pmi.getWhat());
-        assertEquals(sm2.mS1, pmi.getState());
+        lr = sm2.getLogRec(1);
+        assertEquals(TEST_CMD_2, lr.getWhat());
+        assertEquals(sm2.mS1, lr.getState());
 
-        pmi = sm2.getProcessedMessageInfo(2);
-        assertEquals(TEST_CMD_1, pmi.getWhat());
-        assertEquals(sm2.mS2, pmi.getState());
+        lr = sm2.getLogRec(2);
+        assertEquals(TEST_CMD_1, lr.getWhat());
+        assertEquals(sm2.mS2, lr.getState());
 
-        pmi = sm2.getProcessedMessageInfo(3);
-        assertEquals(TEST_CMD_2, pmi.getWhat());
-        assertEquals(sm2.mS2, pmi.getState());
+        lr = sm2.getLogRec(3);
+        assertEquals(TEST_CMD_2, lr.getWhat());
+        assertEquals(sm2.mS2, lr.getState());
 
         assertTrue(sm2.mDidEnter);
         assertTrue(sm2.mDidExit);
@@ -647,7 +781,7 @@
         }
 
         @Override
-        protected void halting() {
+        protected void onHalting() {
             synchronized (mThisSm) {
                 mThisSm.notifyAll();
             }
@@ -677,18 +811,18 @@
             }
         }
 
-        assertTrue(sm3.getProcessedMessagesSize() == 2);
+        assertEquals(2, sm3.getLogRecSize());
 
-        ProcessedMessageInfo pmi;
-        pmi = sm3.getProcessedMessageInfo(0);
-        assertEquals(TEST_CMD_1, pmi.getWhat());
-        assertEquals(sm3.mParentState, pmi.getState());
-        assertEquals(sm3.mChildState, pmi.getOriginalState());
+        LogRec lr;
+        lr = sm3.getLogRec(0);
+        assertEquals(TEST_CMD_1, lr.getWhat());
+        assertEquals(sm3.mParentState, lr.getState());
+        assertEquals(sm3.mChildState, lr.getOriginalState());
 
-        pmi = sm3.getProcessedMessageInfo(1);
-        assertEquals(TEST_CMD_2, pmi.getWhat());
-        assertEquals(sm3.mParentState, pmi.getState());
-        assertEquals(sm3.mChildState, pmi.getOriginalState());
+        lr = sm3.getLogRec(1);
+        assertEquals(TEST_CMD_2, lr.getWhat());
+        assertEquals(sm3.mParentState, lr.getState());
+        assertEquals(sm3.mChildState, lr.getOriginalState());
 
         if (sm3.isDbg()) Log.d(TAG, "testStateMachine3 X");
     }
@@ -742,7 +876,7 @@
         }
 
         @Override
-        protected void halting() {
+        protected void onHalting() {
             synchronized (mThisSm) {
                 mThisSm.notifyAll();
             }
@@ -774,18 +908,18 @@
         }
 
 
-        assertTrue(sm4.getProcessedMessagesSize() == 2);
+        assertEquals(2, sm4.getLogRecSize());
 
-        ProcessedMessageInfo pmi;
-        pmi = sm4.getProcessedMessageInfo(0);
-        assertEquals(TEST_CMD_1, pmi.getWhat());
-        assertEquals(sm4.mChildState1, pmi.getState());
-        assertEquals(sm4.mChildState1, pmi.getOriginalState());
+        LogRec lr;
+        lr = sm4.getLogRec(0);
+        assertEquals(TEST_CMD_1, lr.getWhat());
+        assertEquals(sm4.mChildState1, lr.getState());
+        assertEquals(sm4.mChildState1, lr.getOriginalState());
 
-        pmi = sm4.getProcessedMessageInfo(1);
-        assertEquals(TEST_CMD_2, pmi.getWhat());
-        assertEquals(sm4.mParentState, pmi.getState());
-        assertEquals(sm4.mChildState2, pmi.getOriginalState());
+        lr = sm4.getLogRec(1);
+        assertEquals(TEST_CMD_2, lr.getWhat());
+        assertEquals(sm4.mParentState, lr.getState());
+        assertEquals(sm4.mChildState2, lr.getOriginalState());
 
         if (sm4.isDbg()) Log.d(TAG, "testStateMachine4 X");
     }
@@ -1018,7 +1152,7 @@
         }
 
         @Override
-        protected void halting() {
+        protected void onHalting() {
             synchronized (mThisSm) {
                 mThisSm.notifyAll();
             }
@@ -1073,7 +1207,7 @@
         }
 
 
-        assertTrue(sm5.getProcessedMessagesSize() == 6);
+        assertEquals(6, sm5.getLogRecSize());
 
         assertEquals(1, sm5.mParentState1EnterCount);
         assertEquals(1, sm5.mParentState1ExitCount);
@@ -1090,36 +1224,36 @@
         assertEquals(1, sm5.mChildState5EnterCount);
         assertEquals(1, sm5.mChildState5ExitCount);
 
-        ProcessedMessageInfo pmi;
-        pmi = sm5.getProcessedMessageInfo(0);
-        assertEquals(TEST_CMD_1, pmi.getWhat());
-        assertEquals(sm5.mChildState1, pmi.getState());
-        assertEquals(sm5.mChildState1, pmi.getOriginalState());
+        LogRec lr;
+        lr = sm5.getLogRec(0);
+        assertEquals(TEST_CMD_1, lr.getWhat());
+        assertEquals(sm5.mChildState1, lr.getState());
+        assertEquals(sm5.mChildState1, lr.getOriginalState());
 
-        pmi = sm5.getProcessedMessageInfo(1);
-        assertEquals(TEST_CMD_2, pmi.getWhat());
-        assertEquals(sm5.mChildState2, pmi.getState());
-        assertEquals(sm5.mChildState2, pmi.getOriginalState());
+        lr = sm5.getLogRec(1);
+        assertEquals(TEST_CMD_2, lr.getWhat());
+        assertEquals(sm5.mChildState2, lr.getState());
+        assertEquals(sm5.mChildState2, lr.getOriginalState());
 
-        pmi = sm5.getProcessedMessageInfo(2);
-        assertEquals(TEST_CMD_3, pmi.getWhat());
-        assertEquals(sm5.mChildState5, pmi.getState());
-        assertEquals(sm5.mChildState5, pmi.getOriginalState());
+        lr = sm5.getLogRec(2);
+        assertEquals(TEST_CMD_3, lr.getWhat());
+        assertEquals(sm5.mChildState5, lr.getState());
+        assertEquals(sm5.mChildState5, lr.getOriginalState());
 
-        pmi = sm5.getProcessedMessageInfo(3);
-        assertEquals(TEST_CMD_4, pmi.getWhat());
-        assertEquals(sm5.mChildState3, pmi.getState());
-        assertEquals(sm5.mChildState3, pmi.getOriginalState());
+        lr = sm5.getLogRec(3);
+        assertEquals(TEST_CMD_4, lr.getWhat());
+        assertEquals(sm5.mChildState3, lr.getState());
+        assertEquals(sm5.mChildState3, lr.getOriginalState());
 
-        pmi = sm5.getProcessedMessageInfo(4);
-        assertEquals(TEST_CMD_5, pmi.getWhat());
-        assertEquals(sm5.mChildState4, pmi.getState());
-        assertEquals(sm5.mChildState4, pmi.getOriginalState());
+        lr = sm5.getLogRec(4);
+        assertEquals(TEST_CMD_5, lr.getWhat());
+        assertEquals(sm5.mChildState4, lr.getState());
+        assertEquals(sm5.mChildState4, lr.getOriginalState());
 
-        pmi = sm5.getProcessedMessageInfo(5);
-        assertEquals(TEST_CMD_6, pmi.getWhat());
-        assertEquals(sm5.mParentState2, pmi.getState());
-        assertEquals(sm5.mParentState2, pmi.getOriginalState());
+        lr = sm5.getLogRec(5);
+        assertEquals(TEST_CMD_6, lr.getWhat());
+        assertEquals(sm5.mParentState2, lr.getState());
+        assertEquals(sm5.mParentState2, lr.getOriginalState());
 
         if (sm5.isDbg()) Log.d(TAG, "testStateMachine5 X");
     }
@@ -1161,7 +1295,7 @@
         }
 
         @Override
-        protected void halting() {
+        protected void onHalting() {
             synchronized (mThisSm) {
                 mThisSm.notifyAll();
             }
@@ -1176,7 +1310,6 @@
 
     @MediumTest
     public void testStateMachine6() throws Exception {
-        long sentTimeMsg2;
         final int DELAY_TIME = 250;
         final int DELAY_FUDGE = 20;
 
@@ -1186,7 +1319,6 @@
 
         synchronized (sm6) {
             // Send a message
-            sentTimeMsg2 = SystemClock.elapsedRealtime();
             sm6.sendMessageDelayed(TEST_CMD_2, DELAY_TIME);
 
             try {
@@ -1268,7 +1400,7 @@
         }
 
         @Override
-        protected void halting() {
+        protected void onHalting() {
             synchronized (mThisSm) {
                 mThisSm.notifyAll();
             }
@@ -1285,7 +1417,6 @@
 
     @MediumTest
     public void testStateMachine7() throws Exception {
-        long sentTimeMsg2;
         final int SM7_DELAY_FUDGE = 20;
 
         StateMachine7 sm7 = new StateMachine7("sm7");
@@ -1294,7 +1425,6 @@
 
         synchronized (sm7) {
             // Send a message
-            sentTimeMsg2 = SystemClock.elapsedRealtime();
             sm7.sendMessage(TEST_CMD_1);
 
             try {
@@ -1350,7 +1480,7 @@
         }
 
         @Override
-        protected void halting() {
+        protected void onHalting() {
             synchronized (mThisSm) {
                 mThisSm.notifyAll();
             }
@@ -1383,7 +1513,7 @@
             }
         }
 
-        assertTrue(sm.getProcessedMessagesCount() == 2);
+        assertEquals(sm.getLogRecCount(), 2);
         assertEquals(2, sm.mUnhandledMessageCount);
 
         if (sm.isDbg()) Log.d(TAG, "testStateMachineUnhandledMessage X");
@@ -1420,7 +1550,7 @@
         }
 
         @Override
-        protected void halting() {
+        protected void onHalting() {
             // Update the shared counter, which is OK since all state
             // machines are using the same thread.
             sharedCounter += 1;
@@ -1470,12 +1600,12 @@
         }
 
         for (StateMachineSharedThread sm : sms) {
-            assertTrue(sm.getProcessedMessagesCount() == 4);
-            for (int i = 0; i < sm.getProcessedMessagesCount(); i++) {
-                ProcessedMessageInfo pmi = sm.getProcessedMessageInfo(i);
-                assertEquals(i+1, pmi.getWhat());
-                assertEquals(sm.mS1, pmi.getState());
-                assertEquals(sm.mS1, pmi.getOriginalState());
+            assertEquals(sm.getLogRecCount(), 4);
+            for (int i = 0; i < sm.getLogRecCount(); i++) {
+                LogRec lr = sm.getLogRec(i);
+                assertEquals(i+1, lr.getWhat());
+                assertEquals(sm.mS1, lr.getState());
+                assertEquals(sm.mS1, lr.getOriginalState());
             }
         }
 
@@ -1501,41 +1631,41 @@
             }
         }
 
-        assertEquals(7, sm.getProcessedMessagesCount());
-        ProcessedMessageInfo pmi = sm.getProcessedMessageInfo(0);
-        assertEquals(Hsm1.CMD_1, pmi.getWhat());
-        assertEquals(sm.mS1, pmi.getState());
-        assertEquals(sm.mS1, pmi.getOriginalState());
+        assertEquals(7, sm.getLogRecCount());
+        LogRec lr = sm.getLogRec(0);
+        assertEquals(Hsm1.CMD_1, lr.getWhat());
+        assertEquals(sm.mS1, lr.getState());
+        assertEquals(sm.mS1, lr.getOriginalState());
 
-        pmi = sm.getProcessedMessageInfo(1);
-        assertEquals(Hsm1.CMD_2, pmi.getWhat());
-        assertEquals(sm.mP1, pmi.getState());
-        assertEquals(sm.mS1, pmi.getOriginalState());
+        lr = sm.getLogRec(1);
+        assertEquals(Hsm1.CMD_2, lr.getWhat());
+        assertEquals(sm.mP1, lr.getState());
+        assertEquals(sm.mS1, lr.getOriginalState());
 
-        pmi = sm.getProcessedMessageInfo(2);
-        assertEquals(Hsm1.CMD_2, pmi.getWhat());
-        assertEquals(sm.mS2, pmi.getState());
-        assertEquals(sm.mS2, pmi.getOriginalState());
+        lr = sm.getLogRec(2);
+        assertEquals(Hsm1.CMD_2, lr.getWhat());
+        assertEquals(sm.mS2, lr.getState());
+        assertEquals(sm.mS2, lr.getOriginalState());
 
-        pmi = sm.getProcessedMessageInfo(3);
-        assertEquals(Hsm1.CMD_3, pmi.getWhat());
-        assertEquals(sm.mS2, pmi.getState());
-        assertEquals(sm.mS2, pmi.getOriginalState());
+        lr = sm.getLogRec(3);
+        assertEquals(Hsm1.CMD_3, lr.getWhat());
+        assertEquals(sm.mS2, lr.getState());
+        assertEquals(sm.mS2, lr.getOriginalState());
 
-        pmi = sm.getProcessedMessageInfo(4);
-        assertEquals(Hsm1.CMD_3, pmi.getWhat());
-        assertEquals(sm.mP2, pmi.getState());
-        assertEquals(sm.mP2, pmi.getOriginalState());
+        lr = sm.getLogRec(4);
+        assertEquals(Hsm1.CMD_3, lr.getWhat());
+        assertEquals(sm.mP2, lr.getState());
+        assertEquals(sm.mP2, lr.getOriginalState());
 
-        pmi = sm.getProcessedMessageInfo(5);
-        assertEquals(Hsm1.CMD_4, pmi.getWhat());
-        assertEquals(sm.mP2, pmi.getState());
-        assertEquals(sm.mP2, pmi.getOriginalState());
+        lr = sm.getLogRec(5);
+        assertEquals(Hsm1.CMD_4, lr.getWhat());
+        assertEquals(sm.mP2, lr.getState());
+        assertEquals(sm.mP2, lr.getOriginalState());
 
-        pmi = sm.getProcessedMessageInfo(6);
-        assertEquals(Hsm1.CMD_5, pmi.getWhat());
-        assertEquals(sm.mP2, pmi.getState());
-        assertEquals(sm.mP2, pmi.getOriginalState());
+        lr = sm.getLogRec(6);
+        assertEquals(Hsm1.CMD_5, lr.getWhat());
+        assertEquals(sm.mP2, lr.getState());
+        assertEquals(sm.mP2, lr.getOriginalState());
 
         if (DBG) Log.d(TAG, "testStateMachineSharedThread X");
     }
@@ -1684,7 +1814,7 @@
     }
 
     @Override
-    protected void halting() {
+    protected void onHalting() {
         Log.d(TAG, "halting");
         synchronized (this) {
             this.notifyAll();
diff --git a/services/java/com/android/server/NsdService.java b/services/java/com/android/server/NsdService.java
index 6ad8bd0..87843d9 100644
--- a/services/java/com/android/server/NsdService.java
+++ b/services/java/com/android/server/NsdService.java
@@ -110,8 +110,8 @@
         private final EnabledState mEnabledState = new EnabledState();
 
         @Override
-        protected String getMessageInfo(Message msg) {
-            return cmdToString(msg.what);
+        protected String getWhatToString(int what) {
+            return cmdToString(what);
         }
 
         /**
@@ -144,7 +144,7 @@
             } else {
                 setInitialState(mDisabledState);
             }
-            setProcessedMessagesSize(25);
+            setLogRecSize(25);
             registerForNsdSetting();
         }
 
diff --git a/telephony/java/com/android/internal/telephony/DataConnection.java b/telephony/java/com/android/internal/telephony/DataConnection.java
index cc4adfd..02f0d03 100644
--- a/telephony/java/com/android/internal/telephony/DataConnection.java
+++ b/telephony/java/com/android/internal/telephony/DataConnection.java
@@ -265,7 +265,7 @@
     protected DataConnection(PhoneBase phone, String name, int id, RetryManager rm,
             DataConnectionTracker dct) {
         super(name);
-        setProcessedMessagesSize(100);
+        setLogRecSize(100);
         if (DBG) log("DataConnection constructor E");
         this.phone = phone;
         this.mDataConnectionTracker = dct;
@@ -1215,11 +1215,11 @@
      * @return the string for msg.what as our info.
      */
     @Override
-    protected String getMessageInfo(Message msg) {
+    protected String getWhatToString(int what) {
         String info = null;
-        info = cmdToString(msg.what);
+        info = cmdToString(what);
         if (info == null) {
-            info = DataConnectionAc.cmdToString(msg.what);
+            info = DataConnectionAc.cmdToString(what);
         }
         return info;
     }
diff --git a/wifi/java/android/net/wifi/WifiStateMachine.java b/wifi/java/android/net/wifi/WifiStateMachine.java
index 7f8f9ce..23b1b44 100644
--- a/wifi/java/android/net/wifi/WifiStateMachine.java
+++ b/wifi/java/android/net/wifi/WifiStateMachine.java
@@ -697,7 +697,7 @@
 
         setInitialState(mInitialState);
 
-        setProcessedMessagesSize(100);
+        setLogRecSize(100);
         if (DBG) setDbg(true);
 
         //start the state machine
@@ -1151,7 +1151,7 @@
     }
 
     @Override
-    protected boolean recordProcessedMessage(Message msg) {
+    protected boolean recordLogRec(Message msg) {
         //Ignore screen on/off & common messages when driver has started
         if (getCurrentState() == mConnectedState || getCurrentState() == mDisconnectedState) {
             switch (msg.what) {
@@ -1651,7 +1651,7 @@
             handlePostDhcpSetup();
 
             mDhcpStateMachine.sendMessage(DhcpStateMachine.CMD_STOP_DHCP);
-            mDhcpStateMachine.quit();
+            mDhcpStateMachine.doQuit();
             mDhcpStateMachine = null;
         }
 
diff --git a/wifi/java/android/net/wifi/p2p/WifiP2pService.java b/wifi/java/android/net/wifi/p2p/WifiP2pService.java
index 9e004d0..5759074 100644
--- a/wifi/java/android/net/wifi/p2p/WifiP2pService.java
+++ b/wifi/java/android/net/wifi/p2p/WifiP2pService.java
@@ -1196,7 +1196,7 @@
                     } else {
                         if (DBG) logd("stop DHCP client");
                         mDhcpStateMachine.sendMessage(DhcpStateMachine.CMD_STOP_DHCP);
-                        mDhcpStateMachine.quit();
+                        mDhcpStateMachine.doQuit();
                         mDhcpStateMachine = null;
                     }