1 /*
2  * Copyright (C) 2012 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 /*
18  * Contains implementation of a class EmulatedCamera that encapsulates
19  * functionality common to all version 2.0 emulated camera devices.  Instances
20  * of this class (for each emulated camera) are created during the construction
21  * of the EmulatedCameraFactory instance.  This class serves as an entry point
22  * for all camera API calls that defined by camera2_device_ops_t API.
23  */
24 
25 #define LOG_NDEBUG 0
26 #define LOG_TAG "EmulatedCamera2_Camera"
27 #include <log/log.h>
28 
29 #include "EmulatedCamera2.h"
30 #include "system/camera_metadata.h"
31 
32 namespace android {
33 
34 /* Constructs EmulatedCamera2 instance.
35  * Param:
36  *  cameraId - Zero based camera identifier, which is an index of the camera
37  *      instance in camera factory's array.
38  *  module - Emulated camera HAL module descriptor.
39  */
EmulatedCamera2(int cameraId,struct hw_module_t * module)40 EmulatedCamera2::EmulatedCamera2(int cameraId, struct hw_module_t *module)
41     : EmulatedBaseCamera(cameraId, CAMERA_DEVICE_API_VERSION_2_0, &common,
42                          module) {
43   common.close = EmulatedCamera2::close;
44   ops = &sDeviceOps;
45   priv = this;
46 
47   mNotifyCb = NULL;
48 
49   mRequestQueueSrc = NULL;
50   mFrameQueueDst = NULL;
51 
52   mVendorTagOps.get_camera_vendor_section_name =
53       EmulatedCamera2::get_camera_vendor_section_name;
54   mVendorTagOps.get_camera_vendor_tag_name =
55       EmulatedCamera2::get_camera_vendor_tag_name;
56   mVendorTagOps.get_camera_vendor_tag_type =
57       EmulatedCamera2::get_camera_vendor_tag_type;
58   mVendorTagOps.parent = this;
59 
60   mStatusPresent = true;
61 }
62 
63 /* Destructs EmulatedCamera2 instance. */
~EmulatedCamera2()64 EmulatedCamera2::~EmulatedCamera2() {}
65 
66 /****************************************************************************
67  * Abstract API
68  ***************************************************************************/
69 
70 /****************************************************************************
71  * Public API
72  ***************************************************************************/
73 
Initialize(const cuttlefish::CameraDefinition &)74 status_t EmulatedCamera2::Initialize(const cuttlefish::CameraDefinition & /*props*/) {
75   return NO_ERROR;
76 }
77 
78 /****************************************************************************
79  * Camera API implementation
80  ***************************************************************************/
81 
connectCamera(hw_device_t ** device)82 status_t EmulatedCamera2::connectCamera(hw_device_t **device) {
83   *device = &common;
84   return NO_ERROR;
85 }
86 
closeCamera()87 status_t EmulatedCamera2::closeCamera() { return NO_ERROR; }
88 
getCameraInfo(struct camera_info * info)89 status_t EmulatedCamera2::getCameraInfo(struct camera_info *info) {
90   return EmulatedBaseCamera::getCameraInfo(info);
91 }
92 
93 /****************************************************************************
94  * Camera Device API implementation.
95  * These methods are called from the camera API callback routines.
96  ***************************************************************************/
97 
98 /** Request input queue */
99 
requestQueueNotify()100 int EmulatedCamera2::requestQueueNotify() { return INVALID_OPERATION; }
101 
102 /** Count of requests in flight */
getInProgressCount()103 int EmulatedCamera2::getInProgressCount() { return INVALID_OPERATION; }
104 
105 /** Cancel all captures in flight */
flushCapturesInProgress()106 int EmulatedCamera2::flushCapturesInProgress() { return INVALID_OPERATION; }
107 
108 /** Construct a default request for a given use case */
constructDefaultRequest(int,camera_metadata_t **)109 int EmulatedCamera2::constructDefaultRequest(int /*request_template*/,
110                                              camera_metadata_t ** /*request*/) {
111   return INVALID_OPERATION;
112 }
113 
114 /** Output stream creation and management */
115 
allocateStream(uint32_t,uint32_t,int,const camera2_stream_ops_t *,uint32_t *,uint32_t *,uint32_t *,uint32_t *)116 int EmulatedCamera2::allocateStream(uint32_t /*width*/, uint32_t /*height*/,
117                                     int /*format*/,
118                                     const camera2_stream_ops_t * /*stream_ops*/,
119                                     uint32_t * /*stream_id*/,
120                                     uint32_t * /*format_actual*/,
121                                     uint32_t * /*usage*/,
122                                     uint32_t * /*max_buffers*/) {
123   return INVALID_OPERATION;
124 }
125 
registerStreamBuffers(uint32_t,int,buffer_handle_t *)126 int EmulatedCamera2::registerStreamBuffers(uint32_t /*stream_id*/,
127                                            int /*num_buffers*/,
128                                            buffer_handle_t * /*buffers*/) {
129   return INVALID_OPERATION;
130 }
131 
releaseStream(uint32_t)132 int EmulatedCamera2::releaseStream(uint32_t /*stream_id*/) {
133   return INVALID_OPERATION;
134 }
135 
136 /** Reprocessing input stream management */
137 
allocateReprocessStream(uint32_t,uint32_t,uint32_t,const camera2_stream_in_ops_t *,uint32_t *,uint32_t *,uint32_t *)138 int EmulatedCamera2::allocateReprocessStream(
139     uint32_t /*width*/, uint32_t /*height*/, uint32_t /*format*/,
140     const camera2_stream_in_ops_t * /*reprocess_stream_ops*/,
141     uint32_t * /*stream_id*/, uint32_t * /*consumer_usage*/,
142     uint32_t * /*max_buffers*/) {
143   return INVALID_OPERATION;
144 }
145 
allocateReprocessStreamFromStream(uint32_t,const camera2_stream_in_ops_t *,uint32_t *)146 int EmulatedCamera2::allocateReprocessStreamFromStream(
147     uint32_t /*output_stream_id*/,
148     const camera2_stream_in_ops_t * /*reprocess_stream_ops*/,
149     uint32_t * /*stream_id*/) {
150   return INVALID_OPERATION;
151 }
152 
releaseReprocessStream(uint32_t)153 int EmulatedCamera2::releaseReprocessStream(uint32_t /*stream_id*/) {
154   return INVALID_OPERATION;
155 }
156 
157 /** 3A triggering */
158 
triggerAction(uint32_t,int,int)159 int EmulatedCamera2::triggerAction(uint32_t /*trigger_id*/, int /*ext1*/,
160                                    int /*ext2*/) {
161   return INVALID_OPERATION;
162 }
163 
164 /** Custom tag query methods */
165 
getVendorSectionName(uint32_t)166 const char *EmulatedCamera2::getVendorSectionName(uint32_t /*tag*/) {
167   return NULL;
168 }
169 
getVendorTagName(uint32_t)170 const char *EmulatedCamera2::getVendorTagName(uint32_t /*tag*/) { return NULL; }
171 
getVendorTagType(uint32_t)172 int EmulatedCamera2::getVendorTagType(uint32_t /*tag*/) { return -1; }
173 
174 /** Debug methods */
175 
dump(int)176 int EmulatedCamera2::dump(int /*fd*/) { return INVALID_OPERATION; }
177 
178 /****************************************************************************
179  * Private API.
180  ***************************************************************************/
181 
182 /****************************************************************************
183  * Camera API callbacks as defined by camera2_device_ops structure.  See
184  * hardware/libhardware/include/hardware/camera2.h for information on each
185  * of these callbacks. Implemented in this class, these callbacks simply
186  * dispatch the call into an instance of EmulatedCamera2 class defined by the
187  * 'camera_device2' parameter, or set a member value in the same.
188  ***************************************************************************/
189 
getInstance(const camera2_device_t * d)190 EmulatedCamera2 *getInstance(const camera2_device_t *d) {
191   const EmulatedCamera2 *cec = static_cast<const EmulatedCamera2 *>(d);
192   return const_cast<EmulatedCamera2 *>(cec);
193 }
194 
set_request_queue_src_ops(const camera2_device_t * d,const camera2_request_queue_src_ops * queue_src_ops)195 int EmulatedCamera2::set_request_queue_src_ops(
196     const camera2_device_t *d,
197     const camera2_request_queue_src_ops *queue_src_ops) {
198   EmulatedCamera2 *ec = getInstance(d);
199   ec->mRequestQueueSrc = queue_src_ops;
200   return NO_ERROR;
201 }
202 
notify_request_queue_not_empty(const camera2_device_t * d)203 int EmulatedCamera2::notify_request_queue_not_empty(const camera2_device_t *d) {
204   EmulatedCamera2 *ec = getInstance(d);
205   return ec->requestQueueNotify();
206 }
207 
set_frame_queue_dst_ops(const camera2_device_t * d,const camera2_frame_queue_dst_ops * queue_dst_ops)208 int EmulatedCamera2::set_frame_queue_dst_ops(
209     const camera2_device_t *d,
210     const camera2_frame_queue_dst_ops *queue_dst_ops) {
211   EmulatedCamera2 *ec = getInstance(d);
212   ec->mFrameQueueDst = queue_dst_ops;
213   return NO_ERROR;
214 }
215 
get_in_progress_count(const camera2_device_t * d)216 int EmulatedCamera2::get_in_progress_count(const camera2_device_t *d) {
217   EmulatedCamera2 *ec = getInstance(d);
218   return ec->getInProgressCount();
219 }
220 
flush_captures_in_progress(const camera2_device_t * d)221 int EmulatedCamera2::flush_captures_in_progress(const camera2_device_t *d) {
222   EmulatedCamera2 *ec = getInstance(d);
223   return ec->flushCapturesInProgress();
224 }
225 
construct_default_request(const camera2_device_t * d,int request_template,camera_metadata_t ** request)226 int EmulatedCamera2::construct_default_request(const camera2_device_t *d,
227                                                int request_template,
228                                                camera_metadata_t **request) {
229   EmulatedCamera2 *ec = getInstance(d);
230   return ec->constructDefaultRequest(request_template, request);
231 }
232 
allocate_stream(const camera2_device_t * d,uint32_t width,uint32_t height,int format,const camera2_stream_ops_t * stream_ops,uint32_t * stream_id,uint32_t * format_actual,uint32_t * usage,uint32_t * max_buffers)233 int EmulatedCamera2::allocate_stream(const camera2_device_t *d, uint32_t width,
234                                      uint32_t height, int format,
235                                      const camera2_stream_ops_t *stream_ops,
236                                      uint32_t *stream_id,
237                                      uint32_t *format_actual, uint32_t *usage,
238                                      uint32_t *max_buffers) {
239   EmulatedCamera2 *ec = getInstance(d);
240   return ec->allocateStream(width, height, format, stream_ops, stream_id,
241                             format_actual, usage, max_buffers);
242 }
243 
register_stream_buffers(const camera2_device_t * d,uint32_t stream_id,int num_buffers,buffer_handle_t * buffers)244 int EmulatedCamera2::register_stream_buffers(const camera2_device_t *d,
245                                              uint32_t stream_id,
246                                              int num_buffers,
247                                              buffer_handle_t *buffers) {
248   EmulatedCamera2 *ec = getInstance(d);
249   return ec->registerStreamBuffers(stream_id, num_buffers, buffers);
250 }
release_stream(const camera2_device_t * d,uint32_t stream_id)251 int EmulatedCamera2::release_stream(const camera2_device_t *d,
252                                     uint32_t stream_id) {
253   EmulatedCamera2 *ec = getInstance(d);
254   return ec->releaseStream(stream_id);
255 }
256 
allocate_reprocess_stream(const camera2_device_t * d,uint32_t width,uint32_t height,uint32_t format,const camera2_stream_in_ops_t * reprocess_stream_ops,uint32_t * stream_id,uint32_t * consumer_usage,uint32_t * max_buffers)257 int EmulatedCamera2::allocate_reprocess_stream(
258     const camera2_device_t *d, uint32_t width, uint32_t height, uint32_t format,
259     const camera2_stream_in_ops_t *reprocess_stream_ops, uint32_t *stream_id,
260     uint32_t *consumer_usage, uint32_t *max_buffers) {
261   EmulatedCamera2 *ec = getInstance(d);
262   return ec->allocateReprocessStream(width, height, format,
263                                      reprocess_stream_ops, stream_id,
264                                      consumer_usage, max_buffers);
265 }
266 
allocate_reprocess_stream_from_stream(const camera2_device_t * d,uint32_t output_stream_id,const camera2_stream_in_ops_t * reprocess_stream_ops,uint32_t * stream_id)267 int EmulatedCamera2::allocate_reprocess_stream_from_stream(
268     const camera2_device_t *d, uint32_t output_stream_id,
269     const camera2_stream_in_ops_t *reprocess_stream_ops, uint32_t *stream_id) {
270   EmulatedCamera2 *ec = getInstance(d);
271   return ec->allocateReprocessStreamFromStream(output_stream_id,
272                                                reprocess_stream_ops, stream_id);
273 }
274 
release_reprocess_stream(const camera2_device_t * d,uint32_t stream_id)275 int EmulatedCamera2::release_reprocess_stream(const camera2_device_t *d,
276                                               uint32_t stream_id) {
277   EmulatedCamera2 *ec = getInstance(d);
278   return ec->releaseReprocessStream(stream_id);
279 }
280 
trigger_action(const camera2_device_t * d,uint32_t trigger_id,int ext1,int ext2)281 int EmulatedCamera2::trigger_action(const camera2_device_t *d,
282                                     uint32_t trigger_id, int ext1, int ext2) {
283   EmulatedCamera2 *ec = getInstance(d);
284   return ec->triggerAction(trigger_id, ext1, ext2);
285 }
286 
set_notify_callback(const camera2_device_t * d,camera2_notify_callback notify_cb,void * user)287 int EmulatedCamera2::set_notify_callback(const camera2_device_t *d,
288                                          camera2_notify_callback notify_cb,
289                                          void *user) {
290   EmulatedCamera2 *ec = getInstance(d);
291   Mutex::Autolock l(ec->mMutex);
292   ec->mNotifyCb = notify_cb;
293   ec->mNotifyUserPtr = user;
294   return NO_ERROR;
295 }
296 
get_instance_metadata(const struct camera2_device * d,camera_metadata ** instance_metadata)297 int EmulatedCamera2::get_instance_metadata(
298     const struct camera2_device *d, camera_metadata **instance_metadata) {
299   EmulatedCamera2 *ec = getInstance(d);
300   if (!ec) {
301     return INVALID_OPERATION;
302   }
303   *instance_metadata = ec->mCameraInfo;
304   return NO_ERROR;
305 }
306 
get_metadata_vendor_tag_ops(const camera2_device_t * d,vendor_tag_query_ops_t ** ops)307 int EmulatedCamera2::get_metadata_vendor_tag_ops(const camera2_device_t *d,
308                                                  vendor_tag_query_ops_t **ops) {
309   EmulatedCamera2 *ec = getInstance(d);
310   *ops = static_cast<vendor_tag_query_ops_t *>(&ec->mVendorTagOps);
311   return NO_ERROR;
312 }
313 
get_camera_vendor_section_name(const vendor_tag_query_ops_t * v,uint32_t tag)314 const char *EmulatedCamera2::get_camera_vendor_section_name(
315     const vendor_tag_query_ops_t *v, uint32_t tag) {
316   EmulatedCamera2 *ec = static_cast<const TagOps *>(v)->parent;
317   return ec->getVendorSectionName(tag);
318 }
319 
get_camera_vendor_tag_name(const vendor_tag_query_ops_t * v,uint32_t tag)320 const char *EmulatedCamera2::get_camera_vendor_tag_name(
321     const vendor_tag_query_ops_t *v, uint32_t tag) {
322   EmulatedCamera2 *ec = static_cast<const TagOps *>(v)->parent;
323   return ec->getVendorTagName(tag);
324 }
325 
get_camera_vendor_tag_type(const vendor_tag_query_ops_t * v,uint32_t tag)326 int EmulatedCamera2::get_camera_vendor_tag_type(const vendor_tag_query_ops_t *v,
327                                                 uint32_t tag) {
328   EmulatedCamera2 *ec = static_cast<const TagOps *>(v)->parent;
329   return ec->getVendorTagType(tag);
330 }
331 
dump(const camera2_device_t * d,int fd)332 int EmulatedCamera2::dump(const camera2_device_t *d, int fd) {
333   EmulatedCamera2 *ec = getInstance(d);
334   return ec->dump(fd);
335 }
336 
close(struct hw_device_t * device)337 int EmulatedCamera2::close(struct hw_device_t *device) {
338   EmulatedCamera2 *ec = static_cast<EmulatedCamera2 *>(
339       reinterpret_cast<camera2_device_t *>(device));
340   if (ec == NULL) {
341     ALOGE("%s: Unexpected NULL camera2 device", __FUNCTION__);
342     return -EINVAL;
343   }
344   return ec->closeCamera();
345 }
346 
sendNotification(int32_t msgType,int32_t ext1,int32_t ext2,int32_t ext3)347 void EmulatedCamera2::sendNotification(int32_t msgType, int32_t ext1,
348                                        int32_t ext2, int32_t ext3) {
349   camera2_notify_callback notifyCb;
350   {
351     Mutex::Autolock l(mMutex);
352     notifyCb = mNotifyCb;
353   }
354   if (notifyCb != NULL) {
355     notifyCb(msgType, ext1, ext2, ext3, mNotifyUserPtr);
356   }
357 }
358 
359 camera2_device_ops_t EmulatedCamera2::sDeviceOps = {
360     EmulatedCamera2::set_request_queue_src_ops,
361     EmulatedCamera2::notify_request_queue_not_empty,
362     EmulatedCamera2::set_frame_queue_dst_ops,
363     EmulatedCamera2::get_in_progress_count,
364     EmulatedCamera2::flush_captures_in_progress,
365     EmulatedCamera2::construct_default_request,
366     EmulatedCamera2::allocate_stream,
367     EmulatedCamera2::register_stream_buffers,
368     EmulatedCamera2::release_stream,
369     EmulatedCamera2::allocate_reprocess_stream,
370     EmulatedCamera2::allocate_reprocess_stream_from_stream,
371     EmulatedCamera2::release_reprocess_stream,
372     EmulatedCamera2::trigger_action,
373     EmulatedCamera2::set_notify_callback,
374     EmulatedCamera2::get_metadata_vendor_tag_ops,
375     EmulatedCamera2::dump,
376 #ifdef CAMERA_DEVICE_API_VERSION_2_1
377     EmulatedCamera2::get_instance_metadata,
378 #endif
379 };
380 
381 }; /* namespace android */
382