blob: f89b8b0bfabf780e7581ccc255224d255d6b838d [file] [log] [blame] [edit]
/*
* Copyright (C) 2010 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.
*/
//#define LOG_NDEBUG 0
#define LOG_TAG "AHierarchicalStateMachine"
#include <utils/Log.h>
#include <media/stagefright/AHierarchicalStateMachine.h>
#include <media/stagefright/foundation/ADebug.h>
#include <media/stagefright/foundation/AMessage.h>
#include <utils/Vector.h>
namespace android {
AState::AState(const sp<AState> &parentState)
: mParentState(parentState) {
}
AState::~AState() {
}
sp<AState> AState::parentState() {
return mParentState;
}
void AState::stateEntered() {
}
void AState::stateExited() {
}
////////////////////////////////////////////////////////////////////////////////
AHierarchicalStateMachine::AHierarchicalStateMachine() {
}
AHierarchicalStateMachine::~AHierarchicalStateMachine() {
}
void AHierarchicalStateMachine::handleMessage(const sp<AMessage> &msg) {
sp<AState> save = mState;
sp<AState> cur = mState;
while (cur != NULL && !cur->onMessageReceived(msg)) {
// If you claim not to have handled the message you shouldn't
// have called setState...
CHECK(save == mState);
cur = cur->parentState();
}
if (cur != NULL) {
return;
}
ALOGW("Warning message %s unhandled in root state.",
msg->debugString().c_str());
}
void AHierarchicalStateMachine::changeState(const sp<AState> &state) {
if (state == mState) {
// Quick exit for the easy case.
return;
}
Vector<sp<AState> > A;
sp<AState> cur = mState;
for (;;) {
A.push(cur);
if (cur == NULL) {
break;
}
cur = cur->parentState();
}
Vector<sp<AState> > B;
cur = state;
for (;;) {
B.push(cur);
if (cur == NULL) {
break;
}
cur = cur->parentState();
}
// Remove the common tail.
while (A.size() > 0 && B.size() > 0 && A.top() == B.top()) {
A.pop();
B.pop();
}
mState = state;
for (size_t i = 0; i < A.size(); ++i) {
A.editItemAt(i)->stateExited();
}
for (size_t i = B.size(); i > 0;) {
i--;
B.editItemAt(i)->stateEntered();
}
}
} // namespace android