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