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