1f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala/* 2f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala * Copyright (C) 2013 The Android Open Source Project 3f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala * 4f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala * Licensed under the Apache License, Version 2.0 (the "License"); 5f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala * you may not use this file except in compliance with the License. 6f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala * You may obtain a copy of the License at 7f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala * 8f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala * http://www.apache.org/licenses/LICENSE-2.0 9f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala * 10f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala * Unless required by applicable law or agreed to in writing, software 11f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala * distributed under the License is distributed on an "AS IS" BASIS, 12f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala * See the License for the specific language governing permissions and 14f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala * limitations under the License. 15f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala */ 16f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala 17f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala#ifndef ANDROID_SERVERS_CAMERA3_STATUSTRACKER_H 18f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala#define ANDROID_SERVERS_CAMERA3_STATUSTRACKER_H 19f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala 20f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala#include <utils/Condition.h> 21f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala#include <utils/Errors.h> 22f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala#include <utils/List.h> 23f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala#include <utils/Mutex.h> 24f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala#include <utils/Thread.h> 25f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala#include <utils/KeyedVector.h> 26f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala#include <hardware/camera3.h> 27f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala 28f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala#include "common/CameraDeviceBase.h" 29f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala 30f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvalanamespace android { 31f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala 32f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvalaclass Camera3Device; 33f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvalaclass Fence; 34f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala 35f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvalanamespace camera3 { 36f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala 37f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala/** 38f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala * State tracking for idle and other collective state transitions. 39f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala * Collects idle notifications from different sources and calls the 40f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala * parent when all of them become idle. 41f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala * 42f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala * The parent is responsible for synchronizing the status updates with its 43f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala * internal state correctly, which means the notifyStatus call to the parent may 44f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala * block for a while. 45f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala */ 46f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvalaclass StatusTracker: public Thread { 47f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala public: 488b0b971b1416738f22488a80be726d1ec12552a8Chih-Hung Hsieh explicit StatusTracker(wp<Camera3Device> parent); 49f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala ~StatusTracker(); 50f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala 51f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala // An always-invalid component ID 52f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala static const int NO_STATUS_ID = -1; 53f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala 54f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala // Add a component to track; returns non-negative unique ID for the new 55f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala // component on success, negative error code on failure. 56f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala // New components start in the idle state. 57f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala int addComponent(); 58f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala 59f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala // Remove existing component from idle tracking. Ignores unknown IDs 60f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala void removeComponent(int id); 61f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala 62f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala // Set the state of a tracked component to be idle. Ignores unknown IDs; can 63f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala // accept a fence to wait on to complete idle. The fence is merged with any 64f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala // previous fences given, which means they all must signal before the 65f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala // component is considered idle. 66f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala void markComponentIdle(int id, const sp<Fence>& componentFence); 67f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala 68f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala // Set the state of a tracked component to be active. Ignores unknown IDs. 69f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala void markComponentActive(int id); 70f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala 71f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala virtual void requestExit(); 72f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala protected: 73f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala 74f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala virtual bool threadLoop(); 75f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala 76f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala private: 77f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala enum ComponentState { 78f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala IDLE, 79f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala ACTIVE 80f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala }; 81f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala 82f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala void markComponent(int id, ComponentState state, 83f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala const sp<Fence>& componentFence); 84f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala 85f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala // Guards mPendingChange, mPendingStates, mComponentsChanged 86f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala Mutex mPendingLock; 87f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala 88f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala Condition mPendingChangeSignal; 89f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala 90f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala struct StateChange { 91f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala int id; 92f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala ComponentState state; 93f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala sp<Fence> fence; 94f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala }; 95f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala // A queue of yet-to-be-processed state changes to components 96f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala Vector<StateChange> mPendingChangeQueue; 97f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala bool mComponentsChanged; 98f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala 99f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala wp<Camera3Device> mParent; 100f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala 101f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala // Guards rest of internals. Must be locked after mPendingLock if both used. 102f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala Mutex mLock; 103f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala 104f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala int mNextComponentId; 105f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala 106f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala // Current component states 107f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala KeyedVector<int, ComponentState> mStates; 108f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala // Merged fence for all processed state changes 109f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala sp<Fence> mIdleFence; 110f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala // Current overall device state 111f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala ComponentState mDeviceState; 112f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala 113f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala // Private to threadLoop 114f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala 115f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala // Determine current overall device state 116f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala // We're IDLE iff 117f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala // - All components are currently IDLE 118f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala // - The merged fence for all component updates has signalled 119f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala ComponentState getDeviceStateLocked(); 120f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala 121f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala Vector<ComponentState> mStateTransitions; 122f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala 123f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala static const nsecs_t kWaitDuration = 250000000LL; // 250 ms 124f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala}; 125f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala 126f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala} // namespace camera3 127f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala 128f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala} // namespace android 129f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala 130f1e98d857ec377f2c9b916073d40732e6ebb7cedEino-Ville Talvala#endif 131