1 /*
2  * Copyright (C) 2011 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 HW_EMULATOR_CAMERA_CALLBACK_NOTIFIER_H
18 #define HW_EMULATOR_CAMERA_CALLBACK_NOTIFIER_H
19 
20 /*
21  * Contains declaration of a class CallbackNotifier that manages callbacks set
22  * via set_callbacks, enable_msg_type, and disable_msg_type camera HAL API.
23  */
24 
25 #include <hardware/camera.h>
26 #include <utils/List.h>
27 #include <utils/Mutex.h>
28 #include <utils/Timers.h>
29 
30 namespace android {
31 
32 class EmulatedCameraDevice;
33 
34 /* Manages callbacks set via set_callbacks, enable_msg_type, and
35  * disable_msg_type camera HAL API.
36  *
37  * Objects of this class are contained in EmulatedCamera objects, and handle
38  * relevant camera API callbacks.
39  * Locking considerations. Apparently, it's not allowed to call callbacks
40  * registered in this class, while holding a lock: recursion is quite possible,
41  * which will cause a deadlock.
42  */
43 class CallbackNotifier {
44  public:
45   /* Constructs CallbackNotifier instance. */
46   CallbackNotifier();
47 
48   /* Destructs CallbackNotifier instance. */
49   ~CallbackNotifier();
50 
51   /****************************************************************************
52    * Camera API
53    ***************************************************************************/
54 
55  public:
56   /* Actual handler for camera_device_ops_t::set_callbacks callback.
57    * This method is called by the containing emulated camera object when it is
58    * handing the camera_device_ops_t::set_callbacks callback.
59    */
60   void setCallbacks(camera_notify_callback notify_cb,
61                     camera_data_callback data_cb,
62                     camera_data_timestamp_callback data_cb_timestamp,
63                     camera_request_memory get_memory, void* user);
64 
65   /* Actual handler for camera_device_ops_t::enable_msg_type callback.
66    * This method is called by the containing emulated camera object when it is
67    * handing the camera_device_ops_t::enable_msg_type callback.
68    */
69   void enableMessage(uint msg_type);
70 
71   /* Actual handler for camera_device_ops_t::disable_msg_type callback.
72    * This method is called by the containing emulated camera object when it is
73    * handing the camera_device_ops_t::disable_msg_type callback.
74    */
75   void disableMessage(uint msg_type);
76 
77   /* Actual handler for camera_device_ops_t::store_meta_data_in_buffers
78    * callback. This method is called by the containing emulated camera object
79    * when it is handing the camera_device_ops_t::store_meta_data_in_buffers
80    * callback.
81    * Return:
82    *  NO_ERROR on success, or an appropriate error status.
83    */
84   status_t storeMetaDataInBuffers(bool enable);
85 
86   /* Enables video recording.
87    * This method is called by the containing emulated camera object when it is
88    * handing the camera_device_ops_t::start_recording callback.
89    * Param:
90    *  fps - Video frame frequency. This parameter determins when a frame
91    *      received via onNextFrameAvailable call will be pushed through the
92    *      callback.
93    * Return:
94    *  NO_ERROR on success, or an appropriate error status.
95    */
96   status_t enableVideoRecording(int fps);
97 
98   /* Disables video recording.
99    * This method is called by the containing emulated camera object when it is
100    * handing the camera_device_ops_t::stop_recording callback.
101    */
102   void disableVideoRecording();
103 
104   /* Releases video frame, sent to the framework.
105    * This method is called by the containing emulated camera object when it is
106    * handing the camera_device_ops_t::release_recording_frame callback.
107    */
108   void releaseRecordingFrame(const void* opaque);
109 
110   /* Actual handler for camera_device_ops_t::msg_type_enabled callback.
111    * This method is called by the containing emulated camera object when it is
112    * handing the camera_device_ops_t::msg_type_enabled callback.
113    * Note: this method doesn't grab a lock while checking message status, since
114    * upon exit the status would be undefined anyway. So, grab a lock before
115    * calling this method if you care about persisting a defined message status.
116    * Return:
117    *  0 if message is disabled, or non-zero value, if message is enabled.
118    */
isMessageEnabled(uint msg_type)119   inline int isMessageEnabled(uint msg_type) {
120     return mMessageEnabler & msg_type;
121   }
122 
123   /* Checks id video recording is enabled.
124    * This method is called by the containing emulated camera object when it is
125    * handing the camera_device_ops_t::recording_enabled callback.
126    * Note: this method doesn't grab a lock while checking video recordin status,
127    * since upon exit the status would be undefined anyway. So, grab a lock
128    * before calling this method if you care about persisting of a defined video
129    * recording status.
130    * Return:
131    *  true if video recording is enabled, or false if it is disabled.
132    */
isVideoRecordingEnabled()133   inline bool isVideoRecordingEnabled() { return mVideoRecEnabled; }
134 
135   /****************************************************************************
136    * Public API
137    ***************************************************************************/
138 
139  public:
140   /* Resets the callback notifier. */
141   void cleanupCBNotifier();
142 
143   /* Next frame is available in the camera device.
144    * This is a notification callback that is invoked by the camera device when
145    * a new frame is available.
146    * Note that most likely this method is called in context of a worker thread
147    * that camera device has created for frame capturing.
148    * Param:
149    *  frame - Captured frame, or NULL if camera device didn't pull the frame
150    *      yet. If NULL is passed in this parameter use GetCurrentFrame method
151    *      of the camera device class to obtain the next frame. Also note that
152    *      the size of the frame that is passed here (as well as the frame
153    *      returned from the GetCurrentFrame method) is defined by the current
154    *      frame settings (width + height + pixel format) for the camera device.
155    * timestamp - Frame's timestamp.
156    * camera_dev - Camera device instance that delivered the frame.
157    */
158   void onNextFrameAvailable(const void* frame, nsecs_t timestamp,
159                             EmulatedCameraDevice* camera_dev);
160 
161   /* Entry point for notifications that occur in camera device.
162    * Param:
163    *  err - CAMERA_ERROR_XXX error code.
164    */
165   void onCameraDeviceError(int err);
166 
167   /* Reports focus operation completion to camera client.
168    */
169   void onCameraFocusAcquired();
170 
171   /* Sets, or resets taking picture state.
172    * This state control whether or not to notify the framework about compressed
173    * image, shutter, and other picture related events.
174    */
setTakingPicture(bool taking)175   void setTakingPicture(bool taking) { mTakingPicture = taking; }
176 
177   /* Sets JPEG quality used to compress frame during picture taking. */
setJpegQuality(int jpeg_quality)178   void setJpegQuality(int jpeg_quality) { mJpegQuality = jpeg_quality; }
179 
180   /****************************************************************************
181    * Private API
182    ***************************************************************************/
183 
184  protected:
185   /* Checks if it's time to push new video frame.
186    * Note that this method must be called while object is locked.
187    * Param:
188    *  timestamp - Timestamp for the new frame. */
189   bool isNewVideoFrameTime(nsecs_t timestamp);
190 
191   /****************************************************************************
192    * Data members
193    ***************************************************************************/
194 
195  protected:
196   /* Locks this instance for data change. */
197   Mutex mObjectLock;
198 
199   /*
200    * Callbacks, registered in set_callbacks.
201    */
202 
203   camera_notify_callback mNotifyCB;
204   camera_data_callback mDataCB;
205   camera_data_timestamp_callback mDataCBTimestamp;
206   camera_request_memory mGetMemoryCB;
207   void* mCBOpaque;
208 
209   /* video frame queue for the CameraHeapMemory destruction */
210   List<camera_memory_t*> mCameraMemoryTs;
211 
212   /* Timestamp when last frame has been delivered to the framework. */
213   nsecs_t mLastFrameTimestamp;
214 
215   /* Video frequency in nanosec. */
216   nsecs_t mFrameRefreshFreq;
217 
218   /* Message enabler. */
219   uint32_t mMessageEnabler;
220 
221   /* JPEG quality used to compress frame during picture taking. */
222   int mJpegQuality;
223 
224   /* Video recording status. */
225   bool mVideoRecEnabled;
226 
227   /* Picture taking status. */
228   bool mTakingPicture;
229 };
230 
231 }; /* namespace android */
232 
233 #endif /* HW_EMULATOR_CAMERA_CALLBACK_NOTIFIER_H */
234