Merge "Move ProcessedMessage into HierarchicalStateMachine." into honeycomb-LTE

This commit is contained in:
Wink Saville
2011-04-11 12:04:47 -07:00
committed by Android (Google) Code Review
3 changed files with 230 additions and 255 deletions

View File

@@ -24,6 +24,7 @@ import android.util.Log;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Vector;
/**
* {@hide}
@@ -433,6 +434,180 @@ public class HierarchicalStateMachine {
*/
public static final boolean NOT_HANDLED = false;
/**
* {@hide}
*
* The information maintained for a processed message.
*/
public static class ProcessedMessageInfo {
private int what;
private HierarchicalState state;
private HierarchicalState orgState;
/**
* Constructor
* @param message
* @param state that handled the message
* @param orgState is the first state the received the message but
* did not processes the message.
*/
ProcessedMessageInfo(Message message, HierarchicalState state, HierarchicalState orgState) {
update(message, state, orgState);
}
/**
* Update the information in the record.
* @param state that handled the message
* @param orgState is the first state the received the message but
* did not processes the message.
*/
public void update(Message message, HierarchicalState state, HierarchicalState orgState) {
this.what = message.what;
this.state = state;
this.orgState = orgState;
}
/**
* @return the command that was executing
*/
public int getWhat() {
return what;
}
/**
* @return the state that handled this message
*/
public HierarchicalState getState() {
return state;
}
/**
* @return the original state that received the message.
*/
public HierarchicalState getOriginalState() {
return orgState;
}
/**
* @return as string
*/
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("what=");
sb.append(what);
sb.append(" state=");
sb.append(cn(state));
sb.append(" orgState=");
sb.append(cn(orgState));
return sb.toString();
}
/**
* @return an objects class name
*/
private String cn(Object n) {
if (n == null) {
return "null";
} else {
String name = n.getClass().getName();
int lastDollar = name.lastIndexOf('$');
return name.substring(lastDollar + 1);
}
}
}
/**
* A list of messages recently processed by the state machine.
*
* The class maintains a list of messages that have been most
* 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.
*/
private static class ProcessedMessages {
private static final int DEFAULT_SIZE = 20;
private Vector<ProcessedMessageInfo> mMessages = new Vector<ProcessedMessageInfo>();
private int mMaxSize = DEFAULT_SIZE;
private int mOldestIndex = 0;
private int mCount = 0;
/**
* Constructor
*/
ProcessedMessages() {
}
/**
* Set size of messages to maintain and clears all current messages.
*
* @param maxSize number of messages to maintain at anyone time.
*/
void setSize(int maxSize) {
mMaxSize = maxSize;
mCount = 0;
mMessages.clear();
}
/**
* @return the number of recent messages.
*/
int size() {
return mMessages.size();
}
/**
* @return the total number of messages processed since size was set.
*/
int count() {
return mCount;
}
/**
* @return the information on a particular record. 0 is the oldest
* record and size()-1 is the newest record. If the index is to
* large null is returned.
*/
ProcessedMessageInfo get(int index) {
int nextIndex = mOldestIndex + index;
if (nextIndex >= mMaxSize) {
nextIndex -= mMaxSize;
}
if (nextIndex >= size()) {
return null;
} else {
return mMessages.get(nextIndex);
}
}
/**
* Add a processed message.
*
* @param message
* @param state that handled the message
* @param orgState is the first state the received the message but
* did not processes the message.
*/
void add(Message message, HierarchicalState state, HierarchicalState orgState) {
mCount += 1;
if (mMessages.size() < mMaxSize) {
mMessages.add(new ProcessedMessageInfo(message, state, orgState));
} else {
ProcessedMessageInfo pmi = mMessages.get(mOldestIndex);
mOldestIndex += 1;
if (mOldestIndex >= mMaxSize) {
mOldestIndex = 0;
}
pmi.update(message, state, orgState);
}
}
}
private static class HsmHandler extends Handler {
/** The debug flag */
@@ -441,9 +616,6 @@ public class HierarchicalStateMachine {
/** The quit object */
private static final Object mQuitObj = new Object();
/** The initialization message */
private static final Message mInitMsg = null;
/** The current message */
private Message mMsg;
@@ -615,8 +787,9 @@ public class HierarchicalStateMachine {
*/
mHsm.quitting();
if (mHsm.mHsmThread != null) {
// If we made the thread then quit looper
// If we made the thread then quit looper which stops the thread.
getLooper().quit();
mHsm.mHsmThread = null;
}
} else if (destState == mHaltingState) {
/**
@@ -963,8 +1136,8 @@ public class HierarchicalStateMachine {
return mProcessedMessages.count();
}
/** @see HierarchicalStateMachine#getProcessedMessage(int) */
private final ProcessedMessages.Info getProcessedMessage(int index) {
/** @see HierarchicalStateMachine#getProcessedMessageInfo(int) */
private final ProcessedMessageInfo getProcessedMessageInfo(int index) {
return mProcessedMessages.get(index);
}
@@ -1090,9 +1263,7 @@ public class HierarchicalStateMachine {
* @param msg that couldn't be handled.
*/
protected void unhandledMessage(Message msg) {
if (false) {
Log.e(TAG, mName + " - unhandledMessage: msg.what=" + msg.what);
}
if (mHsmHandler.mDbg) Log.e(TAG, mName + " - unhandledMessage: msg.what=" + msg.what);
}
/**
@@ -1103,16 +1274,18 @@ public class HierarchicalStateMachine {
}
/**
* Called after the message that called transitionToHalting
* is called and should be overridden by StateMachine's that
* call transitionToHalting.
* This will be called once after handling a message that called
* transitionToHalting. All subsequent messages will invoke
* {@link HierarchicalStateMachine#haltedProcessMessage(Message)}
*/
protected void halting() {
}
/**
* Called after the quitting message was NOT handled and
* just before the quit actually occurs.
* This will be called once after a quit message that was NOT handled by
* the derived HSM. The HSM will stop and any subsequent messages will be
* ignored. In addition, if this HSM created the thread, the thread will
* be stopped after this method returns.
*/
protected void quitting() {
}
@@ -1148,10 +1321,10 @@ public class HierarchicalStateMachine {
}
/**
* @return a processed message
* @return a processed message information
*/
public final ProcessedMessages.Info getProcessedMessage(int index) {
return mHsmHandler.getProcessedMessage(index);
public final ProcessedMessageInfo getProcessedMessageInfo(int index) {
return mHsmHandler.getProcessedMessageInfo(index);
}
/**

View File

@@ -1,198 +0,0 @@
/**
* Copyright (C) 2009 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.android.internal.util;
import android.os.Message;
import java.util.Vector;
/**
* {@hide}
*
* A list of messages recently processed by the state machine.
*
* The class maintains a list of messages that have been most
* 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.
*/
public class ProcessedMessages {
public static final int DEFAULT_SIZE = 20;
/**
* The information maintained for a processed message.
*/
public class Info {
private int what;
private HierarchicalState state;
private HierarchicalState orgState;
/**
* Constructor
* @param message
* @param state that handled the message
* @param orgState is the first state the received the message but
* did not processes the message.
*/
Info(Message message, HierarchicalState state, HierarchicalState orgState) {
update(message, state, orgState);
}
/**
* Update the information in the record.
* @param state that handled the message
* @param orgState is the first state the received the message but
* did not processes the message.
*/
public void update(Message message, HierarchicalState state, HierarchicalState orgState) {
this.what = message.what;
this.state = state;
this.orgState = orgState;
}
/**
* @return the command that was executing
*/
public int getWhat() {
return what;
}
/**
* @return the state that handled this message
*/
public HierarchicalState getState() {
return state;
}
/**
* @return the original state that received the message.
*/
public HierarchicalState getOriginalState() {
return orgState;
}
/**
* @return as string
*/
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("what=");
sb.append(what);
sb.append(" state=");
sb.append(cn(state));
sb.append(" orgState=");
sb.append(cn(orgState));
return sb.toString();
}
/**
* @return an objects class name
*/
private String cn(Object n) {
if (n == null) {
return "null";
} else {
String name = n.getClass().getName();
int lastDollar = name.lastIndexOf('$');
return name.substring(lastDollar + 1);
}
}
}
private Vector<Info> mMessages = new Vector<Info>();
private int mMaxSize = DEFAULT_SIZE;
private int mOldestIndex = 0;
private int mCount = 0;
/**
* Constructor
*/
ProcessedMessages() {
}
ProcessedMessages(int maxSize) {
setSize(maxSize);
}
/**
* Set size of messages to maintain and clears all current messages.
*
* @param maxSize number of messages to maintain at anyone time.
*/
void setSize(int maxSize) {
mMaxSize = maxSize;
mCount = 0;
mMessages.clear();
}
/**
* @return the number of recent messages.
*/
int size() {
return mMessages.size();
}
/**
* @return the total number of messages processed since size was set.
*/
int count() {
return mCount;
}
/**
* @return the information on a particular record. 0 is the oldest
* record and size()-1 is the newest record. If the index is to
* large null is returned.
*/
Info get(int index) {
int nextIndex = mOldestIndex + index;
if (nextIndex >= mMaxSize) {
nextIndex -= mMaxSize;
}
if (nextIndex >= size()) {
return null;
} else {
return mMessages.get(nextIndex);
}
}
/**
* Add a processed message.
*
* @param message
* @param state that handled the message
* @param orgState is the first state the received the message but
* did not processes the message.
*/
void add(Message message, HierarchicalState state, HierarchicalState orgState) {
mCount += 1;
if (mMessages.size() < mMaxSize) {
mMessages.add(new Info(message, state, orgState));
} else {
Info info = mMessages.get(mOldestIndex);
mOldestIndex += 1;
if (mOldestIndex >= mMaxSize) {
mOldestIndex = 0;
}
info.update(message, state, orgState);
}
}
}

View File

@@ -24,7 +24,7 @@ import android.os.SystemClock;
import com.android.internal.util.HierarchicalState;
import com.android.internal.util.HierarchicalStateMachine;
import com.android.internal.util.ProcessedMessages;
import com.android.internal.util.HierarchicalStateMachine.ProcessedMessageInfo;
import android.test.suitebuilder.annotation.MediumTest;
import android.test.suitebuilder.annotation.SmallTest;
@@ -125,21 +125,21 @@ public class HierarchicalStateMachineTest extends TestCase {
assertTrue(smQuitTest.getProcessedMessagesCount() == 9);
ProcessedMessages.Info pmi;
ProcessedMessageInfo pmi;
// The first two message didn't quit and were handled by mS1
pmi = smQuitTest.getProcessedMessage(6);
pmi = smQuitTest.getProcessedMessageInfo(6);
assertEquals(HierarchicalStateMachine.HSM_QUIT_CMD, pmi.getWhat());
assertEquals(smQuitTest.mS1, pmi.getState());
assertEquals(smQuitTest.mS1, pmi.getOriginalState());
pmi = smQuitTest.getProcessedMessage(7);
pmi = smQuitTest.getProcessedMessageInfo(7);
assertEquals(HierarchicalStateMachine.HSM_QUIT_CMD, pmi.getWhat());
assertEquals(smQuitTest.mS1, pmi.getState());
assertEquals(smQuitTest.mS1, pmi.getOriginalState());
// The last message was never handled so the states are null
pmi = smQuitTest.getProcessedMessage(8);
pmi = smQuitTest.getProcessedMessageInfo(8);
assertEquals(HierarchicalStateMachine.HSM_QUIT_CMD, pmi.getWhat());
assertEquals(null, pmi.getState());
assertEquals(null, pmi.getOriginalState());
@@ -285,10 +285,10 @@ public class HierarchicalStateMachineTest extends TestCase {
assertTrue(smEnterExitTranstionToTest.getProcessedMessagesCount() == 1);
ProcessedMessages.Info pmi;
ProcessedMessageInfo pmi;
// Message should be handled by mS2.
pmi = smEnterExitTranstionToTest.getProcessedMessage(0);
pmi = smEnterExitTranstionToTest.getProcessedMessageInfo(0);
assertEquals(TEST_CMD_1, pmi.getWhat());
assertEquals(smEnterExitTranstionToTest.mS2, pmi.getState());
assertEquals(smEnterExitTranstionToTest.mS2, pmi.getOriginalState());
@@ -369,18 +369,18 @@ public class HierarchicalStateMachineTest extends TestCase {
assertTrue(sm0.getProcessedMessagesCount() == 6);
assertTrue(sm0.getProcessedMessagesSize() == 3);
ProcessedMessages.Info pmi;
pmi = sm0.getProcessedMessage(0);
ProcessedMessageInfo pmi;
pmi = sm0.getProcessedMessageInfo(0);
assertEquals(TEST_CMD_4, pmi.getWhat());
assertEquals(sm0.mS1, pmi.getState());
assertEquals(sm0.mS1, pmi.getOriginalState());
pmi = sm0.getProcessedMessage(1);
pmi = sm0.getProcessedMessageInfo(1);
assertEquals(TEST_CMD_5, pmi.getWhat());
assertEquals(sm0.mS1, pmi.getState());
assertEquals(sm0.mS1, pmi.getOriginalState());
pmi = sm0.getProcessedMessage(2);
pmi = sm0.getProcessedMessageInfo(2);
assertEquals(TEST_CMD_6, pmi.getWhat());
assertEquals(sm0.mS1, pmi.getState());
assertEquals(sm0.mS1, pmi.getOriginalState());
@@ -469,13 +469,13 @@ public class HierarchicalStateMachineTest extends TestCase {
assertTrue(sm1.getProcessedMessagesSize() == 2);
ProcessedMessages.Info pmi;
pmi = sm1.getProcessedMessage(0);
ProcessedMessageInfo pmi;
pmi = sm1.getProcessedMessageInfo(0);
assertEquals(TEST_CMD_1, pmi.getWhat());
assertEquals(sm1.mS1, pmi.getState());
assertEquals(sm1.mS1, pmi.getOriginalState());
pmi = sm1.getProcessedMessage(1);
pmi = sm1.getProcessedMessageInfo(1);
assertEquals(TEST_CMD_2, pmi.getWhat());
assertEquals(sm1.mS1, pmi.getState());
assertEquals(sm1.mS1, pmi.getOriginalState());
@@ -571,20 +571,20 @@ public class HierarchicalStateMachineTest extends TestCase {
assertTrue(sm2.getProcessedMessagesSize() == 4);
ProcessedMessages.Info pmi;
pmi = sm2.getProcessedMessage(0);
ProcessedMessageInfo pmi;
pmi = sm2.getProcessedMessageInfo(0);
assertEquals(TEST_CMD_1, pmi.getWhat());
assertEquals(sm2.mS1, pmi.getState());
pmi = sm2.getProcessedMessage(1);
pmi = sm2.getProcessedMessageInfo(1);
assertEquals(TEST_CMD_2, pmi.getWhat());
assertEquals(sm2.mS1, pmi.getState());
pmi = sm2.getProcessedMessage(2);
pmi = sm2.getProcessedMessageInfo(2);
assertEquals(TEST_CMD_1, pmi.getWhat());
assertEquals(sm2.mS2, pmi.getState());
pmi = sm2.getProcessedMessage(3);
pmi = sm2.getProcessedMessageInfo(3);
assertEquals(TEST_CMD_2, pmi.getWhat());
assertEquals(sm2.mS2, pmi.getState());
@@ -663,13 +663,13 @@ public class HierarchicalStateMachineTest extends TestCase {
assertTrue(sm3.getProcessedMessagesSize() == 2);
ProcessedMessages.Info pmi;
pmi = sm3.getProcessedMessage(0);
ProcessedMessageInfo pmi;
pmi = sm3.getProcessedMessageInfo(0);
assertEquals(TEST_CMD_1, pmi.getWhat());
assertEquals(sm3.mParentState, pmi.getState());
assertEquals(sm3.mChildState, pmi.getOriginalState());
pmi = sm3.getProcessedMessage(1);
pmi = sm3.getProcessedMessageInfo(1);
assertEquals(TEST_CMD_2, pmi.getWhat());
assertEquals(sm3.mParentState, pmi.getState());
assertEquals(sm3.mChildState, pmi.getOriginalState());
@@ -757,13 +757,13 @@ public class HierarchicalStateMachineTest extends TestCase {
assertTrue(sm4.getProcessedMessagesSize() == 2);
ProcessedMessages.Info pmi;
pmi = sm4.getProcessedMessage(0);
ProcessedMessageInfo pmi;
pmi = sm4.getProcessedMessageInfo(0);
assertEquals(TEST_CMD_1, pmi.getWhat());
assertEquals(sm4.mChildState1, pmi.getState());
assertEquals(sm4.mChildState1, pmi.getOriginalState());
pmi = sm4.getProcessedMessage(1);
pmi = sm4.getProcessedMessageInfo(1);
assertEquals(TEST_CMD_2, pmi.getWhat());
assertEquals(sm4.mParentState, pmi.getState());
assertEquals(sm4.mChildState2, pmi.getOriginalState());
@@ -1050,33 +1050,33 @@ public class HierarchicalStateMachineTest extends TestCase {
assertEquals(1, sm5.mChildState5EnterCount);
assertEquals(1, sm5.mChildState5ExitCount);
ProcessedMessages.Info pmi;
pmi = sm5.getProcessedMessage(0);
ProcessedMessageInfo pmi;
pmi = sm5.getProcessedMessageInfo(0);
assertEquals(TEST_CMD_1, pmi.getWhat());
assertEquals(sm5.mChildState1, pmi.getState());
assertEquals(sm5.mChildState1, pmi.getOriginalState());
pmi = sm5.getProcessedMessage(1);
pmi = sm5.getProcessedMessageInfo(1);
assertEquals(TEST_CMD_2, pmi.getWhat());
assertEquals(sm5.mChildState2, pmi.getState());
assertEquals(sm5.mChildState2, pmi.getOriginalState());
pmi = sm5.getProcessedMessage(2);
pmi = sm5.getProcessedMessageInfo(2);
assertEquals(TEST_CMD_3, pmi.getWhat());
assertEquals(sm5.mChildState5, pmi.getState());
assertEquals(sm5.mChildState5, pmi.getOriginalState());
pmi = sm5.getProcessedMessage(3);
pmi = sm5.getProcessedMessageInfo(3);
assertEquals(TEST_CMD_4, pmi.getWhat());
assertEquals(sm5.mChildState3, pmi.getState());
assertEquals(sm5.mChildState3, pmi.getOriginalState());
pmi = sm5.getProcessedMessage(4);
pmi = sm5.getProcessedMessageInfo(4);
assertEquals(TEST_CMD_5, pmi.getWhat());
assertEquals(sm5.mChildState4, pmi.getState());
assertEquals(sm5.mChildState4, pmi.getOriginalState());
pmi = sm5.getProcessedMessage(5);
pmi = sm5.getProcessedMessageInfo(5);
assertEquals(TEST_CMD_6, pmi.getWhat());
assertEquals(sm5.mParentState2, pmi.getState());
assertEquals(sm5.mParentState2, pmi.getOriginalState());
@@ -1434,7 +1434,7 @@ public class HierarchicalStateMachineTest extends TestCase {
for (StateMachineSharedThread sm : sms) {
assertTrue(sm.getProcessedMessagesCount() == 4);
for (int i = 0; i < sm.getProcessedMessagesCount(); i++) {
ProcessedMessages.Info pmi = sm.getProcessedMessage(i);
ProcessedMessageInfo pmi = sm.getProcessedMessageInfo(i);
assertEquals(i+1, pmi.getWhat());
assertEquals(sm.mS1, pmi.getState());
assertEquals(sm.mS1, pmi.getOriginalState());
@@ -1464,37 +1464,37 @@ public class HierarchicalStateMachineTest extends TestCase {
}
assertEquals(7, sm.getProcessedMessagesCount());
ProcessedMessages.Info pmi = sm.getProcessedMessage(0);
ProcessedMessageInfo pmi = sm.getProcessedMessageInfo(0);
assertEquals(Hsm1.CMD_1, pmi.getWhat());
assertEquals(sm.mS1, pmi.getState());
assertEquals(sm.mS1, pmi.getOriginalState());
pmi = sm.getProcessedMessage(1);
pmi = sm.getProcessedMessageInfo(1);
assertEquals(Hsm1.CMD_2, pmi.getWhat());
assertEquals(sm.mP1, pmi.getState());
assertEquals(sm.mS1, pmi.getOriginalState());
pmi = sm.getProcessedMessage(2);
pmi = sm.getProcessedMessageInfo(2);
assertEquals(Hsm1.CMD_2, pmi.getWhat());
assertEquals(sm.mS2, pmi.getState());
assertEquals(sm.mS2, pmi.getOriginalState());
pmi = sm.getProcessedMessage(3);
pmi = sm.getProcessedMessageInfo(3);
assertEquals(Hsm1.CMD_3, pmi.getWhat());
assertEquals(sm.mS2, pmi.getState());
assertEquals(sm.mS2, pmi.getOriginalState());
pmi = sm.getProcessedMessage(4);
pmi = sm.getProcessedMessageInfo(4);
assertEquals(Hsm1.CMD_3, pmi.getWhat());
assertEquals(sm.mP2, pmi.getState());
assertEquals(sm.mP2, pmi.getOriginalState());
pmi = sm.getProcessedMessage(5);
pmi = sm.getProcessedMessageInfo(5);
assertEquals(Hsm1.CMD_4, pmi.getWhat());
assertEquals(sm.mP2, pmi.getState());
assertEquals(sm.mP2, pmi.getOriginalState());
pmi = sm.getProcessedMessage(6);
pmi = sm.getProcessedMessageInfo(6);
assertEquals(Hsm1.CMD_5, pmi.getWhat());
assertEquals(sm.mP2, pmi.getState());
assertEquals(sm.mP2, pmi.getOriginalState());