12f1f2248c8439adbd686810e306c55f9e6a5abc3James Dong/*
22f1f2248c8439adbd686810e306c55f9e6a5abc3James Dong * Copyright (C) 2010 The Android Open Source Project
32f1f2248c8439adbd686810e306c55f9e6a5abc3James Dong *
42f1f2248c8439adbd686810e306c55f9e6a5abc3James Dong * Licensed under the Apache License, Version 2.0 (the "License");
52f1f2248c8439adbd686810e306c55f9e6a5abc3James Dong * you may not use this file except in compliance with the License.
62f1f2248c8439adbd686810e306c55f9e6a5abc3James Dong * You may obtain a copy of the License at
72f1f2248c8439adbd686810e306c55f9e6a5abc3James Dong *
82f1f2248c8439adbd686810e306c55f9e6a5abc3James Dong *      http://www.apache.org/licenses/LICENSE-2.0
92f1f2248c8439adbd686810e306c55f9e6a5abc3James Dong *
102f1f2248c8439adbd686810e306c55f9e6a5abc3James Dong * Unless required by applicable law or agreed to in writing, software
112f1f2248c8439adbd686810e306c55f9e6a5abc3James Dong * distributed under the License is distributed on an "AS IS" BASIS,
122f1f2248c8439adbd686810e306c55f9e6a5abc3James Dong * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
132f1f2248c8439adbd686810e306c55f9e6a5abc3James Dong * See the License for the specific language governing permissions and
142f1f2248c8439adbd686810e306c55f9e6a5abc3James Dong * limitations under the License.
152f1f2248c8439adbd686810e306c55f9e6a5abc3James Dong */
162f1f2248c8439adbd686810e306c55f9e6a5abc3James Dong
17a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber#include <media/stagefright/foundation/AHierarchicalStateMachine.h>
18a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber
19a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber#include <media/stagefright/foundation/ADebug.h>
20a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber#include <media/stagefright/foundation/AMessage.h>
21a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber#include <utils/Vector.h>
22a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber
23a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Hubernamespace android {
24a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber
25a15874665fa785c82afa9f2e8cb3512470c297cbAndreas HuberAState::AState(const sp<AState> &parentState)
26a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber    : mParentState(parentState) {
27a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber}
28a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber
29a15874665fa785c82afa9f2e8cb3512470c297cbAndreas HuberAState::~AState() {
30a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber}
31a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber
32a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Hubersp<AState> AState::parentState() {
33a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber    return mParentState;
34a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber}
35a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber
36a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Hubervoid AState::stateEntered() {
37a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber}
38a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber
39a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Hubervoid AState::stateExited() {
40a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber}
41a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber
42a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber////////////////////////////////////////////////////////////////////////////////
43a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber
44a15874665fa785c82afa9f2e8cb3512470c297cbAndreas HuberAHierarchicalStateMachine::AHierarchicalStateMachine() {
45a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber}
46a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber
47a15874665fa785c82afa9f2e8cb3512470c297cbAndreas HuberAHierarchicalStateMachine::~AHierarchicalStateMachine() {
48a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber}
49a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber
50a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Hubervoid AHierarchicalStateMachine::onMessageReceived(const sp<AMessage> &msg) {
51a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber    sp<AState> save = mState;
52a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber
53a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber    sp<AState> cur = mState;
54a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber    while (cur != NULL && !cur->onMessageReceived(msg)) {
55a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber        // If you claim not to have handled the message you shouldn't
56a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber        // have called setState...
57a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber        CHECK(save == mState);
58a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber
59a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber        cur = cur->parentState();
60a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber    }
61a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber
62a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber    if (cur != NULL) {
63a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber        return;
64a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber    }
65a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber
66a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber    LOGW("Warning message %s unhandled in root state.",
67a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber         msg->debugString().c_str());
68a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber}
69a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber
70a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Hubervoid AHierarchicalStateMachine::changeState(const sp<AState> &state) {
71a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber    if (state == mState) {
72a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber        // Quick exit for the easy case.
73a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber        return;
74a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber    }
75a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber
76a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber    Vector<sp<AState> > A;
77a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber    sp<AState> cur = mState;
78a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber    for (;;) {
79a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber        A.push(cur);
80a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber        if (cur == NULL) {
81a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber            break;
82a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber        }
83a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber        cur = cur->parentState();
84a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber    }
85a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber
86a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber    Vector<sp<AState> > B;
87a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber    cur = state;
88a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber    for (;;) {
89a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber        B.push(cur);
90a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber        if (cur == NULL) {
91a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber            break;
92a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber        }
93a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber        cur = cur->parentState();
94a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber    }
95a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber
96a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber    // Remove the common tail.
97a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber    while (A.size() > 0 && B.size() > 0 && A.top() == B.top()) {
98a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber        A.pop();
99a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber        B.pop();
100a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber    }
101a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber
102a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber    mState = state;
103a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber
104a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber    for (size_t i = 0; i < A.size(); ++i) {
105a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber        A.editItemAt(i)->stateExited();
106a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber    }
107a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber
108a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber    for (size_t i = B.size(); i-- > 0;) {
109a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber        B.editItemAt(i)->stateEntered();
110a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber    }
111a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber}
112a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber
113a15874665fa785c82afa9f2e8cb3512470c297cbAndreas Huber}  // namespace android
114