/*
* Copyright (C) 2011 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef HW_EMULATOR_CAMERA_CALLBACK_NOTIFIER_H
#define HW_EMULATOR_CAMERA_CALLBACK_NOTIFIER_H
/*
* Contains declaration of a class CallbackNotifier that manages callbacks set
* via set_callbacks, enable_msg_type, and disable_msg_type camera HAL API.
*/
#include <hardware/camera.h>
#include <utils/List.h>
#include <utils/Mutex.h>
#include <utils/Timers.h>
namespace android {
class EmulatedCameraDevice;
/* Manages callbacks set via set_callbacks, enable_msg_type, and
* disable_msg_type camera HAL API.
*
* Objects of this class are contained in EmulatedCamera objects, and handle
* relevant camera API callbacks.
* Locking considerations. Apparently, it's not allowed to call callbacks
* registered in this class, while holding a lock: recursion is quite possible,
* which will cause a deadlock.
*/
class CallbackNotifier {
public:
/* Constructs CallbackNotifier instance. */
CallbackNotifier();
/* Destructs CallbackNotifier instance. */
~CallbackNotifier();
/****************************************************************************
* Camera API
***************************************************************************/
public:
/* Actual handler for camera_device_ops_t::set_callbacks callback.
* This method is called by the containing emulated camera object when it is
* handing the camera_device_ops_t::set_callbacks callback.
*/
void setCallbacks(camera_notify_callback notify_cb,
camera_data_callback data_cb,
camera_data_timestamp_callback data_cb_timestamp,
camera_request_memory get_memory, void* user);
/* Actual handler for camera_device_ops_t::enable_msg_type callback.
* This method is called by the containing emulated camera object when it is
* handing the camera_device_ops_t::enable_msg_type callback.
*/
void enableMessage(uint msg_type);
/* Actual handler for camera_device_ops_t::disable_msg_type callback.
* This method is called by the containing emulated camera object when it is
* handing the camera_device_ops_t::disable_msg_type callback.
*/
void disableMessage(uint msg_type);
/* Actual handler for camera_device_ops_t::store_meta_data_in_buffers
* callback. This method is called by the containing emulated camera object
* when it is handing the camera_device_ops_t::store_meta_data_in_buffers
* callback.
* Return:
* NO_ERROR on success, or an appropriate error status.
*/
status_t storeMetaDataInBuffers(bool enable);
/* Enables video recording.
* This method is called by the containing emulated camera object when it is
* handing the camera_device_ops_t::start_recording callback.
* Param:
* fps - Video frame frequency. This parameter determins when a frame
* received via onNextFrameAvailable call will be pushed through the
* callback.
* Return:
* NO_ERROR on success, or an appropriate error status.
*/
status_t enableVideoRecording(int fps);
/* Disables video recording.
* This method is called by the containing emulated camera object when it is
* handing the camera_device_ops_t::stop_recording callback.
*/
void disableVideoRecording();
/* Releases video frame, sent to the framework.
* This method is called by the containing emulated camera object when it is
* handing the camera_device_ops_t::release_recording_frame callback.
*/
void releaseRecordingFrame(const void* opaque);
/* Actual handler for camera_device_ops_t::msg_type_enabled callback.
* This method is called by the containing emulated camera object when it is
* handing the camera_device_ops_t::msg_type_enabled callback.
* Note: this method doesn't grab a lock while checking message status, since
* upon exit the status would be undefined anyway. So, grab a lock before
* calling this method if you care about persisting a defined message status.
* Return:
* 0 if message is disabled, or non-zero value, if message is enabled.
*/
inline int isMessageEnabled(uint msg_type) {
return mMessageEnabler & msg_type;
}
/* Checks id video recording is enabled.
* This method is called by the containing emulated camera object when it is
* handing the camera_device_ops_t::recording_enabled callback.
* Note: this method doesn't grab a lock while checking video recordin status,
* since upon exit the status would be undefined anyway. So, grab a lock
* before calling this method if you care about persisting of a defined video
* recording status.
* Return:
* true if video recording is enabled, or false if it is disabled.
*/
inline bool isVideoRecordingEnabled() { return mVideoRecEnabled; }
/****************************************************************************
* Public API
***************************************************************************/
public:
/* Resets the callback notifier. */
void cleanupCBNotifier();
/* Next frame is available in the camera device.
* This is a notification callback that is invoked by the camera device when
* a new frame is available.
* Note that most likely this method is called in context of a worker thread
* that camera device has created for frame capturing.
* Param:
* frame - Captured frame, or NULL if camera device didn't pull the frame
* yet. If NULL is passed in this parameter use GetCurrentFrame method
* of the camera device class to obtain the next frame. Also note that
* the size of the frame that is passed here (as well as the frame
* returned from the GetCurrentFrame method) is defined by the current
* frame settings (width + height + pixel format) for the camera device.
* timestamp - Frame's timestamp.
* camera_dev - Camera device instance that delivered the frame.
*/
void onNextFrameAvailable(const void* frame, nsecs_t timestamp,
EmulatedCameraDevice* camera_dev);
/* Entry point for notifications that occur in camera device.
* Param:
* err - CAMERA_ERROR_XXX error code.
*/
void onCameraDeviceError(int err);
/* Reports focus operation completion to camera client.
*/
void onCameraFocusAcquired();
/* Sets, or resets taking picture state.
* This state control whether or not to notify the framework about compressed
* image, shutter, and other picture related events.
*/
void setTakingPicture(bool taking) { mTakingPicture = taking; }
/* Sets JPEG quality used to compress frame during picture taking. */
void setJpegQuality(int jpeg_quality) { mJpegQuality = jpeg_quality; }
/****************************************************************************
* Private API
***************************************************************************/
protected:
/* Checks if it's time to push new video frame.
* Note that this method must be called while object is locked.
* Param:
* timestamp - Timestamp for the new frame. */
bool isNewVideoFrameTime(nsecs_t timestamp);
/****************************************************************************
* Data members
***************************************************************************/
protected:
/* Locks this instance for data change. */
Mutex mObjectLock;
/*
* Callbacks, registered in set_callbacks.
*/
camera_notify_callback mNotifyCB;
camera_data_callback mDataCB;
camera_data_timestamp_callback mDataCBTimestamp;
camera_request_memory mGetMemoryCB;
void* mCBOpaque;
/* video frame queue for the CameraHeapMemory destruction */
List<camera_memory_t*> mCameraMemoryTs;
/* Timestamp when last frame has been delivered to the framework. */
nsecs_t mLastFrameTimestamp;
/* Video frequency in nanosec. */
nsecs_t mFrameRefreshFreq;
/* Message enabler. */
uint32_t mMessageEnabler;
/* JPEG quality used to compress frame during picture taking. */
int mJpegQuality;
/* Video recording status. */
bool mVideoRecEnabled;
/* Picture taking status. */
bool mTakingPicture;
};
}; /* namespace android */
#endif /* HW_EMULATOR_CAMERA_CALLBACK_NOTIFIER_H */