1046205c058ab70be78163ebcacfdc344a7f8750aZhijun He/*
2046205c058ab70be78163ebcacfdc344a7f8750aZhijun He * Copyright (C) 2015 The Android Open Source Project
3046205c058ab70be78163ebcacfdc344a7f8750aZhijun He *
4046205c058ab70be78163ebcacfdc344a7f8750aZhijun He * Licensed under the Apache License, Version 2.0 (the "License");
5046205c058ab70be78163ebcacfdc344a7f8750aZhijun He * you may not use this file except in compliance with the License.
6046205c058ab70be78163ebcacfdc344a7f8750aZhijun He * You may obtain a copy of the License at
7046205c058ab70be78163ebcacfdc344a7f8750aZhijun He *
8046205c058ab70be78163ebcacfdc344a7f8750aZhijun He *      http://www.apache.org/licenses/LICENSE-2.0
9046205c058ab70be78163ebcacfdc344a7f8750aZhijun He *
10046205c058ab70be78163ebcacfdc344a7f8750aZhijun He * Unless required by applicable law or agreed to in writing, software
11046205c058ab70be78163ebcacfdc344a7f8750aZhijun He * distributed under the License is distributed on an "AS IS" BASIS,
12046205c058ab70be78163ebcacfdc344a7f8750aZhijun He * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13046205c058ab70be78163ebcacfdc344a7f8750aZhijun He * See the License for the specific language governing permissions and
14046205c058ab70be78163ebcacfdc344a7f8750aZhijun He * limitations under the License.
15046205c058ab70be78163ebcacfdc344a7f8750aZhijun He */
16046205c058ab70be78163ebcacfdc344a7f8750aZhijun He
17046205c058ab70be78163ebcacfdc344a7f8750aZhijun He//#define LOG_NDEBUG 0
18046205c058ab70be78163ebcacfdc344a7f8750aZhijun He#define LOG_TAG "UsbCameraHAL"
19046205c058ab70be78163ebcacfdc344a7f8750aZhijun He#include <cutils/log.h>
20046205c058ab70be78163ebcacfdc344a7f8750aZhijun He
21046205c058ab70be78163ebcacfdc344a7f8750aZhijun He#include <cstdlib>
22046205c058ab70be78163ebcacfdc344a7f8750aZhijun He#include <hardware/camera_common.h>
23046205c058ab70be78163ebcacfdc344a7f8750aZhijun He#include <hardware/hardware.h>
24046205c058ab70be78163ebcacfdc344a7f8750aZhijun He#include "UsbCamera.h"
25046205c058ab70be78163ebcacfdc344a7f8750aZhijun He#include "CameraHAL.h"
26046205c058ab70be78163ebcacfdc344a7f8750aZhijun He
27046205c058ab70be78163ebcacfdc344a7f8750aZhijun He/*
28046205c058ab70be78163ebcacfdc344a7f8750aZhijun He * This file serves as the entry point to the HAL.  It contains the module
29046205c058ab70be78163ebcacfdc344a7f8750aZhijun He * structure and functions used by the framework to load and interface to this
30046205c058ab70be78163ebcacfdc344a7f8750aZhijun He * HAL, as well as the handles to the individual camera devices.
31046205c058ab70be78163ebcacfdc344a7f8750aZhijun He */
32046205c058ab70be78163ebcacfdc344a7f8750aZhijun He
33046205c058ab70be78163ebcacfdc344a7f8750aZhijun Henamespace usb_camera_hal {
34046205c058ab70be78163ebcacfdc344a7f8750aZhijun He
35046205c058ab70be78163ebcacfdc344a7f8750aZhijun Hestatic CameraHAL gCameraHAL;
36046205c058ab70be78163ebcacfdc344a7f8750aZhijun He
37046205c058ab70be78163ebcacfdc344a7f8750aZhijun HeCameraHAL::CameraHAL()
38046205c058ab70be78163ebcacfdc344a7f8750aZhijun He  : mCallbacks(NULL) {
39046205c058ab70be78163ebcacfdc344a7f8750aZhijun He    // Should not allocate the camera devices for now, as it is unclear if the device is plugged.
40046205c058ab70be78163ebcacfdc344a7f8750aZhijun He
41046205c058ab70be78163ebcacfdc344a7f8750aZhijun He    // Start hotplug thread
42046205c058ab70be78163ebcacfdc344a7f8750aZhijun He    mHotplugThread = new HotplugThread(this);
43046205c058ab70be78163ebcacfdc344a7f8750aZhijun He    mHotplugThread->run("usb-camera-hotplug");
44046205c058ab70be78163ebcacfdc344a7f8750aZhijun He}
45046205c058ab70be78163ebcacfdc344a7f8750aZhijun He
46046205c058ab70be78163ebcacfdc344a7f8750aZhijun HeCameraHAL::~CameraHAL() {
47046205c058ab70be78163ebcacfdc344a7f8750aZhijun He    // Stop hotplug thread
48046205c058ab70be78163ebcacfdc344a7f8750aZhijun He    {
49046205c058ab70be78163ebcacfdc344a7f8750aZhijun He        android::Mutex::Autolock al(mModuleLock);
50046205c058ab70be78163ebcacfdc344a7f8750aZhijun He        if (mHotplugThread != NULL) {
51046205c058ab70be78163ebcacfdc344a7f8750aZhijun He            mHotplugThread->requestExit();
52046205c058ab70be78163ebcacfdc344a7f8750aZhijun He        }
53046205c058ab70be78163ebcacfdc344a7f8750aZhijun He
54046205c058ab70be78163ebcacfdc344a7f8750aZhijun He        // Delete camera device from mCameras
55046205c058ab70be78163ebcacfdc344a7f8750aZhijun He    }
56046205c058ab70be78163ebcacfdc344a7f8750aZhijun He
57046205c058ab70be78163ebcacfdc344a7f8750aZhijun He    // Joining done without holding mLock, otherwise deadlocks may ensue
58046205c058ab70be78163ebcacfdc344a7f8750aZhijun He    // as the threads try to access parent states.
59046205c058ab70be78163ebcacfdc344a7f8750aZhijun He    if (mHotplugThread != NULL) {
60046205c058ab70be78163ebcacfdc344a7f8750aZhijun He        mHotplugThread->join();
61046205c058ab70be78163ebcacfdc344a7f8750aZhijun He    }
62046205c058ab70be78163ebcacfdc344a7f8750aZhijun He
63046205c058ab70be78163ebcacfdc344a7f8750aZhijun He    delete mHotplugThread;
64046205c058ab70be78163ebcacfdc344a7f8750aZhijun He}
65046205c058ab70be78163ebcacfdc344a7f8750aZhijun He
66046205c058ab70be78163ebcacfdc344a7f8750aZhijun Heint CameraHAL::getNumberOfCameras() {
67046205c058ab70be78163ebcacfdc344a7f8750aZhijun He    android::Mutex::Autolock al(mModuleLock);
68046205c058ab70be78163ebcacfdc344a7f8750aZhijun He    ALOGV("%s: %d", __func__, mCameras.size());
69046205c058ab70be78163ebcacfdc344a7f8750aZhijun He    return static_cast<int>(mCameras.size());
70046205c058ab70be78163ebcacfdc344a7f8750aZhijun He}
71046205c058ab70be78163ebcacfdc344a7f8750aZhijun He
72046205c058ab70be78163ebcacfdc344a7f8750aZhijun Heint CameraHAL::getCameraInfo(int id, struct camera_info* info) {
73046205c058ab70be78163ebcacfdc344a7f8750aZhijun He    android::Mutex::Autolock al(mModuleLock);
74046205c058ab70be78163ebcacfdc344a7f8750aZhijun He    ALOGV("%s: camera id %d: info=%p", __func__, id, info);
75046205c058ab70be78163ebcacfdc344a7f8750aZhijun He    if (id < 0 || id >= static_cast<int>(mCameras.size())) {
76046205c058ab70be78163ebcacfdc344a7f8750aZhijun He        ALOGE("%s: Invalid camera id %d", __func__, id);
77046205c058ab70be78163ebcacfdc344a7f8750aZhijun He        return -ENODEV;
78046205c058ab70be78163ebcacfdc344a7f8750aZhijun He    }
79046205c058ab70be78163ebcacfdc344a7f8750aZhijun He
80046205c058ab70be78163ebcacfdc344a7f8750aZhijun He    return mCameras[id]->getInfo(info);
81046205c058ab70be78163ebcacfdc344a7f8750aZhijun He}
82046205c058ab70be78163ebcacfdc344a7f8750aZhijun He
83046205c058ab70be78163ebcacfdc344a7f8750aZhijun Heint CameraHAL::setCallbacks(const camera_module_callbacks_t *callbacks) {
84046205c058ab70be78163ebcacfdc344a7f8750aZhijun He    ALOGV("%s : callbacks=%p", __func__, callbacks);
85046205c058ab70be78163ebcacfdc344a7f8750aZhijun He    mCallbacks = callbacks;
86046205c058ab70be78163ebcacfdc344a7f8750aZhijun He    return 0;
87046205c058ab70be78163ebcacfdc344a7f8750aZhijun He}
88046205c058ab70be78163ebcacfdc344a7f8750aZhijun He
89046205c058ab70be78163ebcacfdc344a7f8750aZhijun Heint CameraHAL::open(const hw_module_t* mod, const char* name, hw_device_t** dev) {
90046205c058ab70be78163ebcacfdc344a7f8750aZhijun He    int id;
91046205c058ab70be78163ebcacfdc344a7f8750aZhijun He    char *nameEnd;
92046205c058ab70be78163ebcacfdc344a7f8750aZhijun He
93046205c058ab70be78163ebcacfdc344a7f8750aZhijun He    android::Mutex::Autolock al(mModuleLock);
94046205c058ab70be78163ebcacfdc344a7f8750aZhijun He    ALOGV("%s: module=%p, name=%s, device=%p", __func__, mod, name, dev);
95046205c058ab70be78163ebcacfdc344a7f8750aZhijun He    if (*name == '\0') {
96046205c058ab70be78163ebcacfdc344a7f8750aZhijun He        ALOGE("%s: Invalid camera id name is NULL", __func__);
97046205c058ab70be78163ebcacfdc344a7f8750aZhijun He        return -EINVAL;
98046205c058ab70be78163ebcacfdc344a7f8750aZhijun He    }
99046205c058ab70be78163ebcacfdc344a7f8750aZhijun He    id = strtol(name, &nameEnd, 10);
100046205c058ab70be78163ebcacfdc344a7f8750aZhijun He    if (*nameEnd != '\0') {
101046205c058ab70be78163ebcacfdc344a7f8750aZhijun He        ALOGE("%s: Invalid camera id name %s", __func__, name);
102046205c058ab70be78163ebcacfdc344a7f8750aZhijun He        return -EINVAL;
103046205c058ab70be78163ebcacfdc344a7f8750aZhijun He    } else if (id < 0 || id >= static_cast<int>(mCameras.size())) {
104046205c058ab70be78163ebcacfdc344a7f8750aZhijun He        ALOGE("%s: Invalid camera id %d", __func__, id);
105046205c058ab70be78163ebcacfdc344a7f8750aZhijun He        return -ENODEV;
106046205c058ab70be78163ebcacfdc344a7f8750aZhijun He    }
107046205c058ab70be78163ebcacfdc344a7f8750aZhijun He    return mCameras[id]->open(mod, dev);
108046205c058ab70be78163ebcacfdc344a7f8750aZhijun He}
109046205c058ab70be78163ebcacfdc344a7f8750aZhijun He
110046205c058ab70be78163ebcacfdc344a7f8750aZhijun Heextern "C" {
111046205c058ab70be78163ebcacfdc344a7f8750aZhijun He
112046205c058ab70be78163ebcacfdc344a7f8750aZhijun Hestatic int get_number_of_cameras() {
113046205c058ab70be78163ebcacfdc344a7f8750aZhijun He    return gCameraHAL.getNumberOfCameras();
114046205c058ab70be78163ebcacfdc344a7f8750aZhijun He}
115046205c058ab70be78163ebcacfdc344a7f8750aZhijun He
116046205c058ab70be78163ebcacfdc344a7f8750aZhijun Hestatic int get_camera_info(int id, struct camera_info* info) {
117046205c058ab70be78163ebcacfdc344a7f8750aZhijun He    return gCameraHAL.getCameraInfo(id, info);
118046205c058ab70be78163ebcacfdc344a7f8750aZhijun He}
119046205c058ab70be78163ebcacfdc344a7f8750aZhijun He
120046205c058ab70be78163ebcacfdc344a7f8750aZhijun Hestatic int set_callbacks(const camera_module_callbacks_t *callbacks) {
121046205c058ab70be78163ebcacfdc344a7f8750aZhijun He    return gCameraHAL.setCallbacks(callbacks);
122046205c058ab70be78163ebcacfdc344a7f8750aZhijun He}
123046205c058ab70be78163ebcacfdc344a7f8750aZhijun He
124046205c058ab70be78163ebcacfdc344a7f8750aZhijun Hestatic int open_dev(const hw_module_t* mod, const char* name, hw_device_t** dev) {
125046205c058ab70be78163ebcacfdc344a7f8750aZhijun He    return gCameraHAL.open(mod, name, dev);
126046205c058ab70be78163ebcacfdc344a7f8750aZhijun He}
127046205c058ab70be78163ebcacfdc344a7f8750aZhijun He
128046205c058ab70be78163ebcacfdc344a7f8750aZhijun Hestatic hw_module_methods_t gCameraModuleMethods = {
129046205c058ab70be78163ebcacfdc344a7f8750aZhijun He    open : open_dev
130046205c058ab70be78163ebcacfdc344a7f8750aZhijun He};
131046205c058ab70be78163ebcacfdc344a7f8750aZhijun He
132046205c058ab70be78163ebcacfdc344a7f8750aZhijun Hecamera_module_t HAL_MODULE_INFO_SYM __attribute__ ((visibility("default"))) = {
133046205c058ab70be78163ebcacfdc344a7f8750aZhijun He    common : {
134046205c058ab70be78163ebcacfdc344a7f8750aZhijun He        tag                : HARDWARE_MODULE_TAG,
135046205c058ab70be78163ebcacfdc344a7f8750aZhijun He        module_api_version : CAMERA_MODULE_API_VERSION_2_4,
136046205c058ab70be78163ebcacfdc344a7f8750aZhijun He        hal_api_version    : HARDWARE_HAL_API_VERSION,
137046205c058ab70be78163ebcacfdc344a7f8750aZhijun He        id                 : CAMERA_HARDWARE_MODULE_ID,
138046205c058ab70be78163ebcacfdc344a7f8750aZhijun He        name               : "Default USB Camera HAL",
139046205c058ab70be78163ebcacfdc344a7f8750aZhijun He        author             : "The Android Open Source Project",
140046205c058ab70be78163ebcacfdc344a7f8750aZhijun He        methods            : &gCameraModuleMethods,
141046205c058ab70be78163ebcacfdc344a7f8750aZhijun He        dso                : NULL,
142046205c058ab70be78163ebcacfdc344a7f8750aZhijun He        reserved           : {0},
143046205c058ab70be78163ebcacfdc344a7f8750aZhijun He    },
144046205c058ab70be78163ebcacfdc344a7f8750aZhijun He    get_number_of_cameras : get_number_of_cameras,
145046205c058ab70be78163ebcacfdc344a7f8750aZhijun He    get_camera_info       : get_camera_info,
146046205c058ab70be78163ebcacfdc344a7f8750aZhijun He    set_callbacks         : set_callbacks,
147046205c058ab70be78163ebcacfdc344a7f8750aZhijun He    get_vendor_tag_ops    : NULL,
148046205c058ab70be78163ebcacfdc344a7f8750aZhijun He    open_legacy           : NULL,
149046205c058ab70be78163ebcacfdc344a7f8750aZhijun He    set_torch_mode        : NULL,
150aee4782839de3103ecebca830a6bd49263a37ad3Eino-Ville Talvala    init                  : NULL,
151046205c058ab70be78163ebcacfdc344a7f8750aZhijun He    reserved              : {0},
152046205c058ab70be78163ebcacfdc344a7f8750aZhijun He};
153046205c058ab70be78163ebcacfdc344a7f8750aZhijun He} // extern "C"
154046205c058ab70be78163ebcacfdc344a7f8750aZhijun He
155046205c058ab70be78163ebcacfdc344a7f8750aZhijun He} // namespace usb_camera_hal
156