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