AHierarchicalStateMachine.cpp revision f933441648ef6a71dee783d733aac17b9508b452
1#include <media/stagefright/foundation/AHierarchicalStateMachine.h>
2
3#include <media/stagefright/foundation/ADebug.h>
4#include <media/stagefright/foundation/AMessage.h>
5#include <utils/Vector.h>
6
7namespace android {
8
9AState::AState(const sp<AState> &parentState)
10    : mParentState(parentState) {
11}
12
13AState::~AState() {
14}
15
16sp<AState> AState::parentState() {
17    return mParentState;
18}
19
20void AState::stateEntered() {
21}
22
23void AState::stateExited() {
24}
25
26////////////////////////////////////////////////////////////////////////////////
27
28AHierarchicalStateMachine::AHierarchicalStateMachine() {
29}
30
31AHierarchicalStateMachine::~AHierarchicalStateMachine() {
32}
33
34void AHierarchicalStateMachine::onMessageReceived(const sp<AMessage> &msg) {
35    sp<AState> save = mState;
36
37    sp<AState> cur = mState;
38    while (cur != NULL && !cur->onMessageReceived(msg)) {
39        // If you claim not to have handled the message you shouldn't
40        // have called setState...
41        CHECK(save == mState);
42
43        cur = cur->parentState();
44    }
45
46    if (cur != NULL) {
47        return;
48    }
49
50    LOGW("Warning message %s unhandled in root state.",
51         msg->debugString().c_str());
52}
53
54void AHierarchicalStateMachine::changeState(const sp<AState> &state) {
55    if (state == mState) {
56        // Quick exit for the easy case.
57        return;
58    }
59
60    Vector<sp<AState> > A;
61    sp<AState> cur = mState;
62    for (;;) {
63        A.push(cur);
64        if (cur == NULL) {
65            break;
66        }
67        cur = cur->parentState();
68    }
69
70    Vector<sp<AState> > B;
71    cur = state;
72    for (;;) {
73        B.push(cur);
74        if (cur == NULL) {
75            break;
76        }
77        cur = cur->parentState();
78    }
79
80    // Remove the common tail.
81    while (A.size() > 0 && B.size() > 0 && A.top() == B.top()) {
82        A.pop();
83        B.pop();
84    }
85
86    mState = state;
87
88    for (size_t i = 0; i < A.size(); ++i) {
89        A.editItemAt(i)->stateExited();
90    }
91
92    for (size_t i = B.size(); i-- > 0;) {
93        B.editItemAt(i)->stateEntered();
94    }
95}
96
97}  // namespace android
98