1/*
2 * Copyright (C) 2015 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//#define LOG_NDEBUG 0
18#define LOG_TAG "Camera"
19
20#include <errno.h>
21#include <stdio.h>
22#include <string.h>
23#include <time.h>
24
25#include <cstdlib>
26
27#include <log/log.h>
28#include <utils/Mutex.h>
29
30#define ATRACE_TAG (ATRACE_TAG_CAMERA | ATRACE_TAG_HAL)
31#include <utils/Trace.h>
32
33#include <hardware/camera3.h>
34#include <system/camera_metadata.h>
35#include <system/graphics.h>
36
37#include "CameraHAL.h"
38#include "Metadata.h"
39#include "Stream.h"
40
41#include "Camera.h"
42
43namespace usb_camera_hal {
44
45extern "C" {
46// Shim passed to the framework to close an opened device.
47static int close_device(hw_device_t* dev) {
48    camera3_device_t* cam_dev = reinterpret_cast<camera3_device_t*>(dev);
49    Camera* cam = static_cast<Camera*>(cam_dev->priv);
50    return cam->close();
51}
52
53// Get handle to camera from device priv data
54static Camera *camdev_to_camera(const camera3_device_t *dev) {
55    return reinterpret_cast<Camera*>(dev->priv);
56}
57
58static int initialize(const camera3_device_t *dev,
59        const camera3_callback_ops_t *callback_ops) {
60    return camdev_to_camera(dev)->initialize(callback_ops);
61}
62
63static int configure_streams(const camera3_device_t *dev,
64        camera3_stream_configuration_t *stream_list) {
65    return camdev_to_camera(dev)->configureStreams(stream_list);
66}
67
68static const camera_metadata_t *construct_default_request_settings(
69        const camera3_device_t *dev, int type) {
70    return camdev_to_camera(dev)->constructDefaultRequestSettings(type);
71}
72
73static int process_capture_request(const camera3_device_t *dev,
74        camera3_capture_request_t *request) {
75    return camdev_to_camera(dev)->processCaptureRequest(request);
76}
77
78static void dump(const camera3_device_t *dev, int fd) {
79    camdev_to_camera(dev)->dump(fd);
80}
81
82static int flush(const camera3_device_t *dev) {
83    return camdev_to_camera(dev)->flush();
84}
85
86} // extern "C"
87
88const camera3_device_ops_t Camera::sOps = {
89    .initialize = usb_camera_hal::initialize,
90    .configure_streams = usb_camera_hal::configure_streams,
91    .register_stream_buffers = NULL,
92    .construct_default_request_settings
93        = usb_camera_hal::construct_default_request_settings,
94    .process_capture_request = usb_camera_hal::process_capture_request,
95    .get_metadata_vendor_tag_ops = NULL,
96    .dump = usb_camera_hal::dump,
97    .flush = usb_camera_hal::flush,
98    .reserved = {0},
99};
100
101Camera::Camera(int id)
102          : mId(id),
103            mStaticInfo(NULL),
104            mBusy(false),
105            mCallbackOps(NULL),
106            mSettings(NULL),
107            mIsInitialized(false) {
108    memset(&mTemplates, 0, sizeof(mTemplates));
109    memset(&mDevice, 0, sizeof(mDevice));
110    mDevice.common.tag    = HARDWARE_DEVICE_TAG;
111    // TODO: Upgrade to HAL3.3
112    mDevice.common.version = CAMERA_DEVICE_API_VERSION_3_2;
113    mDevice.common.close  = close_device;
114    mDevice.ops           = const_cast<camera3_device_ops_t*>(&sOps);
115    mDevice.priv          = this;
116}
117
118Camera::~Camera() {
119    if (mStaticInfo != NULL) {
120        free_camera_metadata(mStaticInfo);
121    }
122
123    for (int i = 0; i < CAMERA3_TEMPLATE_COUNT; i++) {
124        free_camera_metadata(mTemplates[i]);
125    }
126
127    if (mSettings != NULL) {
128        free_camera_metadata(mSettings);
129    }
130}
131
132int Camera::open(const hw_module_t *module, hw_device_t **device) {
133    ALOGI("%s:%d: Opening camera device", __func__, mId);
134    ATRACE_CALL();
135    android::Mutex::Autolock al(mDeviceLock);
136
137    if (mBusy) {
138        ALOGE("%s:%d: Error! Camera device already opened", __func__, mId);
139        return -EBUSY;
140    }
141
142    mBusy = true;
143    mDevice.common.module = const_cast<hw_module_t*>(module);
144    *device = &mDevice.common;
145    return openDevice();
146}
147
148int Camera::getInfo(struct camera_info *info) {
149    android::Mutex::Autolock al(mStaticInfoLock);
150
151    // TODO: update to CAMERA_FACING_EXTERNAL once the HAL API changes are merged.
152    info->facing = CAMERA_FACING_FRONT;
153    info->orientation = 0;
154    info->device_version = mDevice.common.version;
155    if (mStaticInfo == NULL) {
156        initStaticInfo();
157    }
158    info->static_camera_characteristics = mStaticInfo;
159    return 0;
160}
161
162void Camera::updateInfo() {
163    android::Mutex::Autolock al(mStaticInfoLock);
164    initStaticInfo();
165}
166
167int Camera::close() {
168    ALOGI("%s:%d: Closing camera device", __func__, mId);
169    ATRACE_CALL();
170    android::Mutex::Autolock al(mDeviceLock);
171
172    if (!mBusy) {
173        ALOGE("%s:%d: Error! Camera device not open", __func__, mId);
174        return -EINVAL;
175    }
176
177    mBusy = false;
178    mIsInitialized = false;
179    return closeDevice();
180}
181
182int Camera::initialize(const camera3_callback_ops_t *callback_ops) {
183    int res;
184
185    ALOGV("%s:%d: callback_ops=%p", __func__, mId, callback_ops);
186    ATRACE_CALL();
187    android::Mutex::Autolock al(mDeviceLock);
188
189    mCallbackOps = callback_ops;
190    // per-device specific initialization
191    res = initDevice();
192    if (res != 0) {
193        ALOGE("%s:%d: Failed to initialize device!", __func__, mId);
194        return res;
195    }
196
197    mIsInitialized = true;
198    return 0;
199}
200
201int Camera::configureStreams(camera3_stream_configuration_t *stream_config) {
202    camera3_stream_t *astream;
203    android::Vector<Stream *> newStreams;
204
205    ALOGV("%s:%d: stream_config=%p", __func__, mId, stream_config);
206    ATRACE_CALL();
207    android::Mutex::Autolock al(mDeviceLock);
208    if (!mIsInitialized) {
209        ALOGE("Device is not initialized yet");
210        return -EINVAL;
211    }
212
213    if (stream_config == NULL) {
214        ALOGE("%s:%d: NULL stream configuration array", __func__, mId);
215        return -EINVAL;
216    }
217    if (stream_config->num_streams == 0) {
218        ALOGE("%s:%d: Empty stream configuration array", __func__, mId);
219        return -EINVAL;
220    }
221
222    ALOGV("%s:%d: Number of Streams: %d", __func__, mId,
223            stream_config->num_streams);
224    // Mark all current streams unused for now
225    for (size_t i = 0; i < mStreams.size(); i++) {
226        mStreams[i]->mReuse = false;
227    }
228    // Fill new stream array with reused streams and new streams
229    for (unsigned int i = 0; i < stream_config->num_streams; i++) {
230        astream = stream_config->streams[i];
231        if (astream->max_buffers > 0) {
232            ALOGV("%s:%d: Reusing stream %d", __func__, mId, i);
233            newStreams.add(reuseStreamLocked(astream));
234        } else {
235            ALOGV("%s:%d: Creating new stream %d", __func__, mId, i);
236            newStreams.add(new Stream(mId, astream));
237        }
238
239        if (newStreams[i] == NULL) {
240            ALOGE("%s:%d: Error processing stream %d", __func__, mId, i);
241            goto err_out;
242        }
243        astream->priv = reinterpret_cast<void *>(newStreams[i]);
244    }
245
246    // Verify the set of streams in aggregate
247    if (!isValidStreamSetLocked(newStreams)) {
248        ALOGE("%s:%d: Invalid stream set", __func__, mId);
249        goto err_out;
250    }
251
252    // Set up all streams (calculate usage/max_buffers for each)
253    setupStreamsLocked(newStreams);
254
255    // Destroy all old streams and replace stream array with new one
256    destroyStreamsLocked(mStreams);
257    mStreams = newStreams;
258
259    // Clear out last seen settings metadata
260    updateSettingsLocked(NULL);
261    return 0;
262
263err_out:
264    // Clean up temporary streams, preserve existing mStreams
265    destroyStreamsLocked(newStreams);
266    return -EINVAL;
267}
268
269void Camera::destroyStreamsLocked(android::Vector<Stream *> &streams) {
270    for (size_t i = 0; i < streams.size(); i++) {
271        delete streams[i];
272    }
273    streams.clear();
274}
275
276Stream *Camera::reuseStreamLocked(camera3_stream_t *astream) {
277    Stream *priv = reinterpret_cast<Stream*>(astream->priv);
278    // Verify the re-used stream's parameters match
279    if (!priv->isValidReuseStream(mId, astream)) {
280        ALOGE("%s:%d: Mismatched parameter in reused stream", __func__, mId);
281        return NULL;
282    }
283    // Mark stream to be reused
284    priv->mReuse = true;
285    return priv;
286}
287
288bool Camera::isValidStreamSetLocked(const android::Vector<Stream *> &streams) {
289    int inputs = 0;
290    int outputs = 0;
291
292    if (streams.isEmpty()) {
293        ALOGE("%s:%d: Zero count stream configuration streams", __func__, mId);
294        return false;
295    }
296    // Validate there is at most one input stream and at least one output stream
297    for (size_t i = 0; i < streams.size(); i++) {
298        // A stream may be both input and output (bidirectional)
299        if (streams[i]->isInputType())
300            inputs++;
301        if (streams[i]->isOutputType())
302            outputs++;
303    }
304    ALOGV("%s:%d: Configuring %d output streams and %d input streams",
305            __func__, mId, outputs, inputs);
306    if (outputs < 1) {
307        ALOGE("%s:%d: Stream config must have >= 1 output", __func__, mId);
308        return false;
309    }
310    if (inputs > 1) {
311        ALOGE("%s:%d: Stream config must have <= 1 input", __func__, mId);
312        return false;
313    }
314    // TODO: check for correct number of Bayer/YUV/JPEG/Encoder streams
315    return true;
316}
317
318void Camera::setupStreamsLocked(android::Vector<Stream *> &streams) {
319    /*
320     * This is where the HAL has to decide internally how to handle all of the
321     * streams, and then produce usage and max_buffer values for each stream.
322     * Note, the stream vector has been checked before this point for ALL invalid
323     * conditions, so it must find a successful configuration for this stream
324     * array.  The HAL may not return an error from this point.
325     *
326     * TODO: we just set all streams to be the same dummy values;
327     * real implementations will want to avoid USAGE_SW_{READ|WRITE}_OFTEN.
328     */
329    for (size_t i = 0; i < streams.size(); i++) {
330        uint32_t usage = 0;
331
332        if (streams[i]->isOutputType())
333            usage |= GRALLOC_USAGE_SW_WRITE_OFTEN |
334                     GRALLOC_USAGE_HW_CAMERA_WRITE;
335        if (streams[i]->isInputType())
336            usage |= GRALLOC_USAGE_SW_READ_OFTEN |
337                     GRALLOC_USAGE_HW_CAMERA_READ;
338
339        streams[i]->setUsage(usage);
340        streams[i]->setMaxBuffers(1);
341    }
342}
343
344bool Camera::isValidTemplateType(int type) {
345    return type >= 1 && type < CAMERA3_TEMPLATE_COUNT;
346}
347
348const camera_metadata_t* Camera::constructDefaultRequestSettings(int type) {
349    ALOGV("%s:%d: type=%d", __func__, mId, type);
350    android::Mutex::Autolock al(mDeviceLock);
351
352    if (!isValidTemplateType(type)) {
353        ALOGE("%s:%d: Invalid template request type: %d", __func__, mId, type);
354        return NULL;
355    }
356
357    // DO NOT try to initialize the device here, it will be guaranteed deadlock.
358    if (!mIsInitialized) {
359        ALOGE("Device is not initialized yet");
360        return NULL;
361    }
362
363    return mTemplates[type];
364}
365
366// This implementation is a copy-paste, probably we should override (or move) this to
367// device specific class.
368int Camera::processCaptureRequest(camera3_capture_request_t *request) {
369    camera3_capture_result result;
370    ALOGV("%s:%d: request=%p", __func__, mId, request);
371    ATRACE_CALL();
372    android::Mutex::Autolock al(mDeviceLock);
373
374    if (request == NULL) {
375        ALOGE("%s:%d: NULL request recieved", __func__, mId);
376        return -EINVAL;
377    }
378
379    ALOGV("%s:%d: Request Frame:%d Settings:%p", __func__, mId,
380            request->frame_number, request->settings);
381
382    // NULL indicates use last settings
383    if (request->settings == NULL) {
384        if (mSettings == NULL) {
385            ALOGE("%s:%d: NULL settings without previous set Frame:%d Req:%p",
386                    __func__, mId, request->frame_number, request);
387            return -EINVAL;
388        }
389    } else {
390        updateSettingsLocked(request->settings);
391    }
392
393    if (request->input_buffer != NULL) {
394        ALOGV("%s:%d: Reprocessing input buffer is not supported yet", __func__, mId);
395        return -EINVAL;
396    } else {
397        ALOGV("%s:%d: Capturing new frame.", __func__, mId);
398
399        if (!isValidCaptureSettings(request->settings)) {
400            ALOGE("%s:%d: Invalid settings for capture request: %p",
401                    __func__, mId, request->settings);
402            return -EINVAL;
403        }
404    }
405
406    if (request->num_output_buffers <= 0) {
407        ALOGE("%s:%d: Invalid number of output buffers: %d", __func__, mId,
408                request->num_output_buffers);
409        return -EINVAL;
410    }
411    result.num_output_buffers = request->num_output_buffers;
412    result.output_buffers = new camera3_stream_buffer_t[result.num_output_buffers];
413    for (unsigned int i = 0; i < request->num_output_buffers; i++) {
414        int res = processCaptureBuffer(&request->output_buffers[i],
415                const_cast<camera3_stream_buffer_t*>(&result.output_buffers[i]));
416        if (res) {
417            delete [] result.output_buffers;
418            // TODO: this should probably be a total device failure; transient for now
419            return -EINVAL;
420        }
421    }
422
423    result.frame_number = request->frame_number;
424    // TODO: return actual captured/reprocessed settings
425    result.result = request->settings;
426    // TODO: asynchronously return results
427    notifyShutter(request->frame_number, 0);
428    mCallbackOps->process_capture_result(mCallbackOps, &result);
429
430    // Free up capture result related resources, HAL owns the capture result, and it
431    // is only valid during the process_capture_result call.
432    delete[] result.output_buffers;
433
434    return 0;
435}
436
437int Camera::flush() {
438    int res;
439
440    ALOGV("%s:%d: flush device", __func__, mId);
441    // per-device specific flush
442    res = flushDevice();
443    if (res != 0) {
444        ALOGE("%s:%d: Failed to flush device!", __func__, mId);
445        return res;
446    }
447    return 0;
448}
449
450void Camera::updateSettingsLocked(const camera_metadata_t *new_settings) {
451    if (mSettings != NULL) {
452        free_camera_metadata(mSettings);
453        mSettings = NULL;
454    }
455
456    if (new_settings != NULL)
457        mSettings = clone_camera_metadata(new_settings);
458}
459
460void Camera::notifyShutter(uint32_t frame_number, uint64_t timestamp) {
461    int res;
462    struct timespec ts;
463
464    // If timestamp is 0, get timestamp from right now instead
465    if (timestamp == 0) {
466        ALOGW("%s:%d: No timestamp provided, using CLOCK_BOOTTIME",
467                __func__, mId);
468        res = clock_gettime(CLOCK_BOOTTIME, &ts);
469        if (res == 0) {
470            timestamp = ts.tv_sec * 1000000000ULL + ts.tv_nsec;
471        } else {
472            ALOGE("%s:%d: No timestamp and failed to get CLOCK_BOOTTIME %s(%d)",
473                    __func__, mId, strerror(errno), errno);
474        }
475    }
476    camera3_notify_msg_t m;
477    memset(&m, 0, sizeof(m));
478    m.type = CAMERA3_MSG_SHUTTER;
479    m.message.shutter.frame_number = frame_number;
480    m.message.shutter.timestamp = timestamp;
481    mCallbackOps->notify(mCallbackOps, &m);
482}
483
484void Camera::dump(int fd) {
485    ALOGV("%s:%d: Dumping to fd %d", __func__, mId, fd);
486    ATRACE_CALL();
487    android::Mutex::Autolock al(mDeviceLock);
488
489    dprintf(fd, "Camera ID: %d (Busy: %d)\n", mId, mBusy);
490
491    // TODO: dump all settings
492    dprintf(fd, "Most Recent Settings: (%p)\n", mSettings);
493
494    dprintf(fd, "Number of streams: %zu\n", mStreams.size());
495    for (size_t i = 0; i < mStreams.size(); i++) {
496        dprintf(fd, "Stream %zu/%zu:\n", i, mStreams.size());
497        mStreams[i]->dump(fd);
498    }
499}
500
501const char* Camera::templateToString(int type) {
502    switch (type) {
503    case CAMERA3_TEMPLATE_PREVIEW:
504        return "CAMERA3_TEMPLATE_PREVIEW";
505    case CAMERA3_TEMPLATE_STILL_CAPTURE:
506        return "CAMERA3_TEMPLATE_STILL_CAPTURE";
507    case CAMERA3_TEMPLATE_VIDEO_RECORD:
508        return "CAMERA3_TEMPLATE_VIDEO_RECORD";
509    case CAMERA3_TEMPLATE_VIDEO_SNAPSHOT:
510        return "CAMERA3_TEMPLATE_VIDEO_SNAPSHOT";
511    case CAMERA3_TEMPLATE_ZERO_SHUTTER_LAG:
512        return "CAMERA3_TEMPLATE_ZERO_SHUTTER_LAG";
513    case CAMERA3_TEMPLATE_MANUAL:
514        return "CAMERA3_TEMPLATE_MANUAL";
515    }
516
517    return "Invalid template type!";
518}
519
520int Camera::setTemplate(int type, camera_metadata_t *settings) {
521    android::Mutex::Autolock al(mDeviceLock);
522
523    if (!isValidTemplateType(type)) {
524        ALOGE("%s:%d: Invalid template request type: %d", __func__, mId, type);
525        return -EINVAL;
526    }
527
528    if (mTemplates[type] != NULL) {
529        ALOGE("%s:%d: Setting already constructed template type %s(%d)",
530                __func__, mId, templateToString(type), type);
531        return -EINVAL;
532    }
533
534    // Make a durable copy of the underlying metadata
535    mTemplates[type] = clone_camera_metadata(settings);
536    if (mTemplates[type] == NULL) {
537        ALOGE("%s:%d: Failed to clone metadata %p for template type %s(%d)",
538                __func__, mId, settings, templateToString(type), type);
539        return -EINVAL;
540    }
541    return 0;
542}
543
544} // namespace usb_camera_hal
545