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