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
25namespace android {
26
27class EmulatedCameraDevice;
28
29/* Manages callbacks set via set_callbacks, enable_msg_type, and disable_msg_type
30 * camera HAL API.
31 *
32 * Objects of this class are contained in EmulatedCamera objects, and handle
33 * relevant camera API callbacks.
34 * Locking considerations. Apparently, it's not allowed to call callbacks
35 * registered in this class, while holding a lock: recursion is quite possible,
36 * which will cause a deadlock.
37 */
38class CallbackNotifier {
39public:
40    /* Constructs CallbackNotifier instance. */
41    CallbackNotifier();
42
43    /* Destructs CallbackNotifier instance. */
44    ~CallbackNotifier();
45
46    /****************************************************************************
47     * Camera API
48     ***************************************************************************/
49
50public:
51    /* Actual handler for camera_device_ops_t::set_callbacks callback.
52     * This method is called by the containing emulated camera object when it is
53     * handing the camera_device_ops_t::set_callbacks callback.
54     */
55    void setCallbacks(camera_notify_callback notify_cb,
56                      camera_data_callback data_cb,
57                      camera_data_timestamp_callback data_cb_timestamp,
58                      camera_request_memory get_memory,
59                      void* user);
60
61    /* Actual handler for camera_device_ops_t::enable_msg_type callback.
62     * This method is called by the containing emulated camera object when it is
63     * handing the camera_device_ops_t::enable_msg_type callback.
64     */
65    void enableMessage(uint msg_type);
66
67    /* Actual handler for camera_device_ops_t::disable_msg_type callback.
68     * This method is called by the containing emulated camera object when it is
69     * handing the camera_device_ops_t::disable_msg_type callback.
70     */
71    void disableMessage(uint msg_type);
72
73    /* Actual handler for camera_device_ops_t::store_meta_data_in_buffers
74     * callback. This method is called by the containing emulated camera object
75     * when it is handing the camera_device_ops_t::store_meta_data_in_buffers
76     * callback.
77     * Return:
78     *  NO_ERROR on success, or an appropriate error status.
79     */
80    status_t storeMetaDataInBuffers(bool enable);
81
82    /* Enables video recording.
83     * This method is called by the containing emulated camera object when it is
84     * handing the camera_device_ops_t::start_recording callback.
85     * Param:
86     *  fps - Video frame frequency. This parameter determins when a frame
87     *      received via onNextFrameAvailable call will be pushed through the
88     *      callback.
89     * Return:
90     *  NO_ERROR on success, or an appropriate error status.
91     */
92    status_t enableVideoRecording(int fps);
93
94    /* Disables video recording.
95     * This method is called by the containing emulated camera object when it is
96     * handing the camera_device_ops_t::stop_recording callback.
97     */
98    void disableVideoRecording();
99
100    /* Releases video frame, sent to the framework.
101     * This method is called by the containing emulated camera object when it is
102     * handing the camera_device_ops_t::release_recording_frame callback.
103     */
104    void releaseRecordingFrame(const void* opaque);
105
106    /* Actual handler for camera_device_ops_t::msg_type_enabled callback.
107     * This method is called by the containing emulated camera object when it is
108     * handing the camera_device_ops_t::msg_type_enabled callback.
109     * Note: this method doesn't grab a lock while checking message status, since
110     * upon exit the status would be undefined anyway. So, grab a lock before
111     * calling this method if you care about persisting a defined message status.
112     * Return:
113     *  0 if message is disabled, or non-zero value, if message is enabled.
114     */
115    inline int isMessageEnabled(uint msg_type)
116    {
117        return mMessageEnabler & msg_type;
118    }
119
120    /* Checks id video recording is enabled.
121     * This method is called by the containing emulated camera object when it is
122     * handing the camera_device_ops_t::recording_enabled callback.
123     * Note: this method doesn't grab a lock while checking video recordin status,
124     * since upon exit the status would be undefined anyway. So, grab a lock
125     * before calling this method if you care about persisting of a defined video
126     * recording status.
127     * Return:
128     *  true if video recording is enabled, or false if it is disabled.
129     */
130    inline bool isVideoRecordingEnabled()
131    {
132        return mVideoRecEnabled;
133    }
134
135    /****************************************************************************
136     * Public API
137     ***************************************************************************/
138
139public:
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,
159                              nsecs_t timestamp,
160                              EmulatedCameraDevice* camera_dev);
161
162    /* Entry point for notifications that occur in camera device.
163     * Param:
164     *  err - CAMERA_ERROR_XXX error code.
165     */
166    void onCameraDeviceError(int err);
167
168    /* Sets, or resets taking picture state.
169     * This state control whether or not to notify the framework about compressed
170     * image, shutter, and other picture related events.
171     */
172    void setTakingPicture(bool taking)
173    {
174        mTakingPicture = taking;
175    }
176
177    /* Sets JPEG quality used to compress frame during picture taking. */
178    void setJpegQuality(int jpeg_quality)
179    {
180        mJpegQuality = jpeg_quality;
181    }
182
183    /****************************************************************************
184     * Private API
185     ***************************************************************************/
186
187protected:
188    /* Checks if it's time to push new video frame.
189     * Note that this method must be called while object is locked.
190     * Param:
191     *  timestamp - Timestamp for the new frame. */
192    bool isNewVideoFrameTime(nsecs_t timestamp);
193
194    /****************************************************************************
195     * Data members
196     ***************************************************************************/
197
198protected:
199    /* Locks this instance for data change. */
200    Mutex                           mObjectLock;
201
202    /*
203     * Callbacks, registered in set_callbacks.
204     */
205
206    camera_notify_callback          mNotifyCB;
207    camera_data_callback            mDataCB;
208    camera_data_timestamp_callback  mDataCBTimestamp;
209    camera_request_memory           mGetMemoryCB;
210    void*                           mCBOpaque;
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