1 /*
2 * Copyright (C) 2011 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 EmulatedCameraFactory that manages cameras
19 * available for emulation.
20 */
21
22 #define LOG_NDEBUG 0
23 #define LOG_TAG "EmulatedCamera_Factory"
24 #include <log/log.h>
25 #include <cutils/properties.h>
26 #include "EmulatedFakeCamera.h"
27
28 #include "EmulatedCameraHotplugThread.h"
29 #include "EmulatedFakeCamera2.h"
30
31 #include "EmulatedFakeCamera3.h"
32
33 #include "EmulatedCameraFactory.h"
34
35 extern camera_module_t HAL_MODULE_INFO_SYM;
36
37 namespace android {
Instance()38 EmulatedCameraFactory& EmulatedCameraFactory::Instance() {
39 static EmulatedCameraFactory* factory = new EmulatedCameraFactory;
40 return *factory;
41 }
42
EmulatedCameraFactory()43 EmulatedCameraFactory::EmulatedCameraFactory()
44 : mCallbacks(NULL)
45 {
46 mCameraConfiguration.Init();
47 const std::vector<cuttlefish::CameraDefinition>& cameras =
48 mCameraConfiguration.cameras();
49 for (size_t camera_index = 0; camera_index < cameras.size(); ++camera_index) {
50 mCameraDefinitions.push(cameras[camera_index]);
51 /* Reserve a spot for camera, but don't create just yet. */
52 mEmulatedCameras.push(NULL);
53 }
54
55 ALOGV("%zu cameras are being emulated.", getEmulatedCameraNum());
56
57 /* Create hotplug thread */
58 {
59 mHotplugThread = new EmulatedCameraHotplugThread(getEmulatedCameraNum());
60 mHotplugThread->run("EmulatedCameraHotplugThread");
61 }
62 }
63
getOrCreateFakeCamera(size_t cameraId)64 EmulatedBaseCamera* EmulatedCameraFactory::getOrCreateFakeCamera(
65 size_t cameraId) {
66 std::lock_guard lock(mEmulatedCamerasMutex);
67
68 if (cameraId >= getEmulatedCameraNum()) {
69 ALOGE("%s: Invalid camera ID: %zu", __FUNCTION__, cameraId);
70 return NULL;
71 }
72
73 if (mEmulatedCameras[cameraId] != NULL) {
74 return mEmulatedCameras[cameraId];
75 }
76
77 const cuttlefish::CameraDefinition& definition = mCameraDefinitions[cameraId];
78 bool is_back_facing =
79 (definition.orientation == cuttlefish::CameraDefinition::kBack);
80
81 EmulatedBaseCamera* camera;
82 /* Create, and initialize the fake camera */
83 switch (definition.hal_version) {
84 case cuttlefish::CameraDefinition::kHalV1:
85 camera = new EmulatedFakeCamera(cameraId, is_back_facing,
86 &HAL_MODULE_INFO_SYM.common);
87 break;
88 case cuttlefish::CameraDefinition::kHalV2:
89 camera = new EmulatedFakeCamera2(cameraId, is_back_facing,
90 &HAL_MODULE_INFO_SYM.common);
91 break;
92 case cuttlefish::CameraDefinition::kHalV3:
93 camera = new EmulatedFakeCamera3(cameraId, is_back_facing,
94 &HAL_MODULE_INFO_SYM.common);
95 break;
96 default:
97 ALOGE("%s: Unsupported camera hal version requested: %d", __FUNCTION__,
98 definition.hal_version);
99 return NULL;
100 }
101
102 ALOGI("%s: Camera device %zu hal version is %d", __FUNCTION__, cameraId,
103 definition.hal_version);
104 int res = camera->Initialize(definition);
105
106 if (res != NO_ERROR) {
107 ALOGE("%s: Unable to intialize camera %zu: %s (%d)", __FUNCTION__, cameraId,
108 strerror(-res), res);
109 delete camera;
110 return NULL;
111 }
112
113 ALOGI("%s: Inserting camera", __FUNCTION__);
114 mEmulatedCameras.replaceAt(camera, cameraId);
115 ALOGI("%s: Done", __FUNCTION__);
116 return camera;
117 }
118
~EmulatedCameraFactory()119 EmulatedCameraFactory::~EmulatedCameraFactory() {
120 for (size_t n = 0; n < mEmulatedCameras.size(); n++) {
121 if (mEmulatedCameras[n] != NULL) {
122 delete mEmulatedCameras[n];
123 }
124 }
125
126 if (mHotplugThread != NULL) {
127 mHotplugThread->requestExit();
128 mHotplugThread->join();
129 }
130 }
131
132 /****************************************************************************
133 * Camera HAL API handlers.
134 *
135 * Each handler simply verifies existence of an appropriate EmulatedBaseCamera
136 * instance, and dispatches the call to that instance.
137 *
138 ***************************************************************************/
139
cameraDeviceOpen(int camera_id,hw_device_t ** device)140 int EmulatedCameraFactory::cameraDeviceOpen(int camera_id,
141 hw_device_t** device) {
142 ALOGV("%s: id = %d", __FUNCTION__, camera_id);
143
144 *device = NULL;
145
146 EmulatedBaseCamera* camera = getOrCreateFakeCamera(camera_id);
147 if (camera == NULL) return -EINVAL;
148
149 return camera->connectCamera(device);
150 }
151
getCameraInfo(int camera_id,struct camera_info * info)152 int EmulatedCameraFactory::getCameraInfo(int camera_id,
153 struct camera_info* info) {
154 ALOGV("%s: id = %d", __FUNCTION__, camera_id);
155
156 EmulatedBaseCamera* camera = getOrCreateFakeCamera(camera_id);
157 if (camera == NULL) return -EINVAL;
158
159 return camera->getCameraInfo(info);
160 }
161
setCallbacks(const camera_module_callbacks_t * callbacks)162 int EmulatedCameraFactory::setCallbacks(
163 const camera_module_callbacks_t* callbacks) {
164 ALOGV("%s: callbacks = %p", __FUNCTION__, callbacks);
165
166 mCallbacks = callbacks;
167
168 return OK;
169 }
170
getVendorTagOps(vendor_tag_ops_t * ops)171 void EmulatedCameraFactory::getVendorTagOps(vendor_tag_ops_t* ops) {
172 ALOGV("%s: ops = %p", __FUNCTION__, ops);
173
174 // No vendor tags defined for emulator yet, so not touching ops
175 }
176
setTorchMode(const char * camera_id,bool enabled)177 int EmulatedCameraFactory::setTorchMode(const char* camera_id, bool enabled) {
178 ALOGV("%s: camera_id = %s, enabled =%d", __FUNCTION__, camera_id, enabled);
179
180 EmulatedBaseCamera* camera = getOrCreateFakeCamera(atoi(camera_id));
181 if (camera == NULL) return -EINVAL;
182
183 return camera->setTorchMode(enabled);
184 }
185
186 /****************************************************************************
187 * Camera HAL API callbacks.
188 ***************************************************************************/
189
device_open(const hw_module_t * module,const char * name,hw_device_t ** device)190 int EmulatedCameraFactory::device_open(const hw_module_t* module,
191 const char* name, hw_device_t** device) {
192 /*
193 * Simply verify the parameters, and dispatch the call inside the
194 * EmulatedCameraFactory instance.
195 */
196
197 if (module != &HAL_MODULE_INFO_SYM.common) {
198 ALOGE("%s: Invalid module %p expected %p", __FUNCTION__, module,
199 &HAL_MODULE_INFO_SYM.common);
200 return -EINVAL;
201 }
202 if (name == NULL) {
203 ALOGE("%s: NULL name is not expected here", __FUNCTION__);
204 return -EINVAL;
205 }
206
207 return EmulatedCameraFactory::Instance().cameraDeviceOpen(atoi(name), device);
208 }
209
get_number_of_cameras(void)210 int EmulatedCameraFactory::get_number_of_cameras(void) {
211 return EmulatedCameraFactory::Instance().getEmulatedCameraNum();
212 }
213
get_camera_info(int camera_id,struct camera_info * info)214 int EmulatedCameraFactory::get_camera_info(int camera_id,
215 struct camera_info* info) {
216 return EmulatedCameraFactory::Instance().getCameraInfo(camera_id, info);
217 }
218
set_callbacks(const camera_module_callbacks_t * callbacks)219 int EmulatedCameraFactory::set_callbacks(
220 const camera_module_callbacks_t* callbacks) {
221 return EmulatedCameraFactory::Instance().setCallbacks(callbacks);
222 }
223
get_vendor_tag_ops(vendor_tag_ops_t * ops)224 void EmulatedCameraFactory::get_vendor_tag_ops(vendor_tag_ops_t* ops) {
225 EmulatedCameraFactory::Instance().getVendorTagOps(ops);
226 }
227
open_legacy(const struct hw_module_t *,const char *,uint32_t,struct hw_device_t **)228 int EmulatedCameraFactory::open_legacy(const struct hw_module_t* /*module*/,
229 const char* /*id*/,
230 uint32_t /*halVersion*/,
231 struct hw_device_t** /*device*/) {
232 // Not supporting legacy open
233 return -ENOSYS;
234 }
235
set_torch_mode(const char * camera_id,bool enabled)236 int EmulatedCameraFactory::set_torch_mode(const char* camera_id, bool enabled) {
237 return EmulatedCameraFactory::Instance().setTorchMode(camera_id, enabled);
238 }
239
240 /********************************************************************************
241 * Internal API
242 *******************************************************************************/
243
onStatusChanged(int cameraId,int newStatus)244 void EmulatedCameraFactory::onStatusChanged(int cameraId, int newStatus) {
245 EmulatedBaseCamera* cam = getOrCreateFakeCamera(cameraId);
246 if (!cam) {
247 ALOGE("%s: Invalid camera ID %d", __FUNCTION__, cameraId);
248 return;
249 }
250
251 /**
252 * (Order is important)
253 * Send the callback first to framework, THEN close the camera.
254 */
255
256 if (newStatus == cam->getHotplugStatus()) {
257 ALOGW("%s: Ignoring transition to the same status", __FUNCTION__);
258 return;
259 }
260
261 const camera_module_callbacks_t* cb = mCallbacks;
262 if (cb != NULL && cb->camera_device_status_change != NULL) {
263 cb->camera_device_status_change(cb, cameraId, newStatus);
264 }
265
266 if (newStatus == CAMERA_DEVICE_STATUS_NOT_PRESENT) {
267 cam->unplugCamera();
268 } else if (newStatus == CAMERA_DEVICE_STATUS_PRESENT) {
269 cam->plugCamera();
270 }
271 }
272
onTorchModeStatusChanged(int cameraId,int newStatus)273 void EmulatedCameraFactory::onTorchModeStatusChanged(int cameraId,
274 int newStatus) {
275 EmulatedBaseCamera* cam = getOrCreateFakeCamera(cameraId);
276 if (!cam) {
277 ALOGE("%s: Invalid camera ID %d", __FUNCTION__, cameraId);
278 return;
279 }
280
281 const camera_module_callbacks_t* cb = mCallbacks;
282 if (cb != NULL && cb->torch_mode_status_change != NULL) {
283 char id[10];
284 sprintf(id, "%d", cameraId);
285 cb->torch_mode_status_change(cb, id, newStatus);
286 }
287 }
288
289 /********************************************************************************
290 * Initializer for the static member structure.
291 *******************************************************************************/
292
293 /* Entry point for camera HAL API. */
294 struct hw_module_methods_t EmulatedCameraFactory::mCameraModuleMethods = {
295 .open = EmulatedCameraFactory::device_open};
296
297 }; /* namespace android */
298