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 <cutils/log.h>
25 #include <cutils/properties.h>
26 #include "EmulatedQemuCamera.h"
27 #include "EmulatedFakeCamera.h"
28 #include "EmulatedFakeCamera2.h"
29 #include "EmulatedFakeCamera3.h"
30 #include "EmulatedCameraHotplugThread.h"
31 #include "EmulatedCameraFactory.h"
32
33 extern camera_module_t HAL_MODULE_INFO_SYM;
34
35 /* A global instance of EmulatedCameraFactory is statically instantiated and
36 * initialized when camera emulation HAL is loaded.
37 */
38 android::EmulatedCameraFactory gEmulatedCameraFactory;
39
40 namespace android {
41
EmulatedCameraFactory()42 EmulatedCameraFactory::EmulatedCameraFactory()
43 : mQemuClient(),
44 mEmulatedCameras(NULL),
45 mEmulatedCameraNum(0),
46 mFakeCameraNum(0),
47 mConstructedOK(false),
48 mCallbacks(NULL)
49 {
50 status_t res;
51 /* Connect to the factory service in the emulator, and create Qemu cameras. */
52 if (mQemuClient.connectClient(NULL) == NO_ERROR) {
53 /* Connection has succeeded. Create emulated cameras for each camera
54 * device, reported by the service. */
55 createQemuCameras();
56 }
57
58 if (isBackFakeCameraEmulationOn()) {
59 /* Camera ID. */
60 const int camera_id = mEmulatedCameraNum;
61 /* Use fake camera to emulate back-facing camera. */
62 mEmulatedCameraNum++;
63
64 /* Make sure that array is allocated (in case there were no 'qemu'
65 * cameras created. Note that we preallocate the array so it may contain
66 * two fake cameras: one facing back, and another facing front. */
67 if (mEmulatedCameras == NULL) {
68 mEmulatedCameras = new EmulatedBaseCamera*[mEmulatedCameraNum + 1];
69 if (mEmulatedCameras == NULL) {
70 ALOGE("%s: Unable to allocate emulated camera array for %d entries",
71 __FUNCTION__, mEmulatedCameraNum);
72 return;
73 }
74 memset(mEmulatedCameras, 0,
75 (mEmulatedCameraNum + 1) * sizeof(EmulatedBaseCamera*));
76 }
77
78 /* Create, and initialize the fake camera */
79 switch (getBackCameraHalVersion()) {
80 case 1:
81 mEmulatedCameras[camera_id] =
82 new EmulatedFakeCamera(camera_id, true,
83 &HAL_MODULE_INFO_SYM.common);
84 break;
85 case 2:
86 mEmulatedCameras[camera_id] =
87 new EmulatedFakeCamera2(camera_id, true,
88 &HAL_MODULE_INFO_SYM.common);
89 break;
90 case 3:
91 mEmulatedCameras[camera_id] =
92 new EmulatedFakeCamera3(camera_id, true,
93 &HAL_MODULE_INFO_SYM.common);
94 break;
95 default:
96 ALOGE("%s: Unknown back camera hal version requested: %d", __FUNCTION__,
97 getBackCameraHalVersion());
98 }
99 if (mEmulatedCameras[camera_id] != NULL) {
100 ALOGV("%s: Back camera device version is %d", __FUNCTION__,
101 getBackCameraHalVersion());
102 res = mEmulatedCameras[camera_id]->Initialize();
103 if (res != NO_ERROR) {
104 ALOGE("%s: Unable to intialize back camera %d: %s (%d)",
105 __FUNCTION__, camera_id, strerror(-res), res);
106 delete mEmulatedCameras[camera_id];
107 mEmulatedCameraNum--;
108 }
109 } else {
110 mEmulatedCameraNum--;
111 ALOGE("%s: Unable to instantiate fake camera class", __FUNCTION__);
112 }
113 }
114
115 if (isFrontFakeCameraEmulationOn()) {
116 /* Camera ID. */
117 const int camera_id = mEmulatedCameraNum;
118 /* Use fake camera to emulate front-facing camera. */
119 mEmulatedCameraNum++;
120
121 /* Make sure that array is allocated (in case there were no 'qemu'
122 * cameras created. */
123 if (mEmulatedCameras == NULL) {
124 mEmulatedCameras = new EmulatedBaseCamera*[mEmulatedCameraNum];
125 if (mEmulatedCameras == NULL) {
126 ALOGE("%s: Unable to allocate emulated camera array for %d entries",
127 __FUNCTION__, mEmulatedCameraNum);
128 return;
129 }
130 memset(mEmulatedCameras, 0,
131 mEmulatedCameraNum * sizeof(EmulatedBaseCamera*));
132 }
133
134 /* Create, and initialize the fake camera */
135 switch (getFrontCameraHalVersion()) {
136 case 1:
137 mEmulatedCameras[camera_id] =
138 new EmulatedFakeCamera(camera_id, false,
139 &HAL_MODULE_INFO_SYM.common);
140 break;
141 case 2:
142 mEmulatedCameras[camera_id] =
143 new EmulatedFakeCamera2(camera_id, false,
144 &HAL_MODULE_INFO_SYM.common);
145 break;
146 case 3:
147 mEmulatedCameras[camera_id] =
148 new EmulatedFakeCamera3(camera_id, false,
149 &HAL_MODULE_INFO_SYM.common);
150 break;
151 default:
152 ALOGE("%s: Unknown front camera hal version requested: %d",
153 __FUNCTION__,
154 getFrontCameraHalVersion());
155 }
156 if (mEmulatedCameras[camera_id] != NULL) {
157 ALOGV("%s: Front camera device version is %d", __FUNCTION__,
158 getFrontCameraHalVersion());
159 res = mEmulatedCameras[camera_id]->Initialize();
160 if (res != NO_ERROR) {
161 ALOGE("%s: Unable to intialize front camera %d: %s (%d)",
162 __FUNCTION__, camera_id, strerror(-res), res);
163 delete mEmulatedCameras[camera_id];
164 mEmulatedCameraNum--;
165 }
166 } else {
167 mEmulatedCameraNum--;
168 ALOGE("%s: Unable to instantiate fake camera class", __FUNCTION__);
169 }
170 }
171
172 ALOGV("%d cameras are being emulated. %d of them are fake cameras.",
173 mEmulatedCameraNum, mFakeCameraNum);
174
175 /* Create hotplug thread */
176 {
177 Vector<int> cameraIdVector;
178 for (int i = 0; i < mEmulatedCameraNum; ++i) {
179 cameraIdVector.push_back(i);
180 }
181 mHotplugThread = new EmulatedCameraHotplugThread(&cameraIdVector[0],
182 mEmulatedCameraNum);
183 mHotplugThread->run("EmulatedCameraHotplugThread");
184 }
185
186 mConstructedOK = true;
187 }
188
~EmulatedCameraFactory()189 EmulatedCameraFactory::~EmulatedCameraFactory()
190 {
191 if (mEmulatedCameras != NULL) {
192 for (int n = 0; n < mEmulatedCameraNum; n++) {
193 if (mEmulatedCameras[n] != NULL) {
194 delete mEmulatedCameras[n];
195 }
196 }
197 delete[] mEmulatedCameras;
198 }
199
200 if (mHotplugThread != NULL) {
201 mHotplugThread->requestExit();
202 mHotplugThread->join();
203 }
204 }
205
206 /****************************************************************************
207 * Camera HAL API handlers.
208 *
209 * Each handler simply verifies existence of an appropriate EmulatedBaseCamera
210 * instance, and dispatches the call to that instance.
211 *
212 ***************************************************************************/
213
cameraDeviceOpen(int camera_id,hw_device_t ** device)214 int EmulatedCameraFactory::cameraDeviceOpen(int camera_id, hw_device_t** device)
215 {
216 ALOGV("%s: id = %d", __FUNCTION__, camera_id);
217
218 *device = NULL;
219
220 if (!isConstructedOK()) {
221 ALOGE("%s: EmulatedCameraFactory has failed to initialize", __FUNCTION__);
222 return -EINVAL;
223 }
224
225 if (camera_id < 0 || camera_id >= getEmulatedCameraNum()) {
226 ALOGE("%s: Camera id %d is out of bounds (%d)",
227 __FUNCTION__, camera_id, getEmulatedCameraNum());
228 return -ENODEV;
229 }
230
231 return mEmulatedCameras[camera_id]->connectCamera(device);
232 }
233
getCameraInfo(int camera_id,struct camera_info * info)234 int EmulatedCameraFactory::getCameraInfo(int camera_id, struct camera_info* info)
235 {
236 ALOGV("%s: id = %d", __FUNCTION__, camera_id);
237
238 if (!isConstructedOK()) {
239 ALOGE("%s: EmulatedCameraFactory has failed to initialize", __FUNCTION__);
240 return -EINVAL;
241 }
242
243 if (camera_id < 0 || camera_id >= getEmulatedCameraNum()) {
244 ALOGE("%s: Camera id %d is out of bounds (%d)",
245 __FUNCTION__, camera_id, getEmulatedCameraNum());
246 return -ENODEV;
247 }
248
249 return mEmulatedCameras[camera_id]->getCameraInfo(info);
250 }
251
setCallbacks(const camera_module_callbacks_t * callbacks)252 int EmulatedCameraFactory::setCallbacks(
253 const camera_module_callbacks_t *callbacks)
254 {
255 ALOGV("%s: callbacks = %p", __FUNCTION__, callbacks);
256
257 mCallbacks = callbacks;
258
259 return OK;
260 }
261
getVendorTagOps(vendor_tag_ops_t * ops)262 void EmulatedCameraFactory::getVendorTagOps(vendor_tag_ops_t* ops) {
263 ALOGV("%s: ops = %p", __FUNCTION__, ops);
264
265 // No vendor tags defined for emulator yet, so not touching ops
266 }
267
268 /****************************************************************************
269 * Camera HAL API callbacks.
270 ***************************************************************************/
271
device_open(const hw_module_t * module,const char * name,hw_device_t ** device)272 int EmulatedCameraFactory::device_open(const hw_module_t* module,
273 const char* name,
274 hw_device_t** device)
275 {
276 /*
277 * Simply verify the parameters, and dispatch the call inside the
278 * EmulatedCameraFactory instance.
279 */
280
281 if (module != &HAL_MODULE_INFO_SYM.common) {
282 ALOGE("%s: Invalid module %p expected %p",
283 __FUNCTION__, module, &HAL_MODULE_INFO_SYM.common);
284 return -EINVAL;
285 }
286 if (name == NULL) {
287 ALOGE("%s: NULL name is not expected here", __FUNCTION__);
288 return -EINVAL;
289 }
290
291 return gEmulatedCameraFactory.cameraDeviceOpen(atoi(name), device);
292 }
293
get_number_of_cameras(void)294 int EmulatedCameraFactory::get_number_of_cameras(void)
295 {
296 return gEmulatedCameraFactory.getEmulatedCameraNum();
297 }
298
get_camera_info(int camera_id,struct camera_info * info)299 int EmulatedCameraFactory::get_camera_info(int camera_id,
300 struct camera_info* info)
301 {
302 return gEmulatedCameraFactory.getCameraInfo(camera_id, info);
303 }
304
set_callbacks(const camera_module_callbacks_t * callbacks)305 int EmulatedCameraFactory::set_callbacks(
306 const camera_module_callbacks_t *callbacks)
307 {
308 return gEmulatedCameraFactory.setCallbacks(callbacks);
309 }
310
get_vendor_tag_ops(vendor_tag_ops_t * ops)311 void EmulatedCameraFactory::get_vendor_tag_ops(vendor_tag_ops_t* ops)
312 {
313 gEmulatedCameraFactory.getVendorTagOps(ops);
314 }
315
open_legacy(const struct hw_module_t * module,const char * id,uint32_t halVersion,struct hw_device_t ** device)316 int EmulatedCameraFactory::open_legacy(const struct hw_module_t* module,
317 const char* id, uint32_t halVersion, struct hw_device_t** device) {
318 // Not supporting legacy open
319 return -ENOSYS;
320 }
321
322 /********************************************************************************
323 * Internal API
324 *******************************************************************************/
325
326 /*
327 * Camera information tokens passed in response to the "list" factory query.
328 */
329
330 /* Device name token. */
331 static const char lListNameToken[] = "name=";
332 /* Frame dimensions token. */
333 static const char lListDimsToken[] = "framedims=";
334 /* Facing direction token. */
335 static const char lListDirToken[] = "dir=";
336
createQemuCameras()337 void EmulatedCameraFactory::createQemuCameras()
338 {
339 /* Obtain camera list. */
340 char* camera_list = NULL;
341 status_t res = mQemuClient.listCameras(&camera_list);
342 /* Empty list, or list containing just an EOL means that there were no
343 * connected cameras found. */
344 if (res != NO_ERROR || camera_list == NULL || *camera_list == '\0' ||
345 *camera_list == '\n') {
346 if (camera_list != NULL) {
347 free(camera_list);
348 }
349 return;
350 }
351
352 /*
353 * Calculate number of connected cameras. Number of EOLs in the camera list
354 * is the number of the connected cameras.
355 */
356
357 int num = 0;
358 const char* eol = strchr(camera_list, '\n');
359 while (eol != NULL) {
360 num++;
361 eol = strchr(eol + 1, '\n');
362 }
363
364 /* Allocate the array for emulated camera instances. Note that we allocate
365 * two more entries for back and front fake camera emulation. */
366 mEmulatedCameras = new EmulatedBaseCamera*[num + 2];
367 if (mEmulatedCameras == NULL) {
368 ALOGE("%s: Unable to allocate emulated camera array for %d entries",
369 __FUNCTION__, num + 1);
370 free(camera_list);
371 return;
372 }
373 memset(mEmulatedCameras, 0, sizeof(EmulatedBaseCamera*) * (num + 1));
374
375 /*
376 * Iterate the list, creating, and initializin emulated qemu cameras for each
377 * entry (line) in the list.
378 */
379
380 int index = 0;
381 char* cur_entry = camera_list;
382 while (cur_entry != NULL && *cur_entry != '\0' && index < num) {
383 /* Find the end of the current camera entry, and terminate it with zero
384 * for simpler string manipulation. */
385 char* next_entry = strchr(cur_entry, '\n');
386 if (next_entry != NULL) {
387 *next_entry = '\0';
388 next_entry++; // Start of the next entry.
389 }
390
391 /* Find 'name', 'framedims', and 'dir' tokens that are required here. */
392 char* name_start = strstr(cur_entry, lListNameToken);
393 char* dim_start = strstr(cur_entry, lListDimsToken);
394 char* dir_start = strstr(cur_entry, lListDirToken);
395 if (name_start != NULL && dim_start != NULL && dir_start != NULL) {
396 /* Advance to the token values. */
397 name_start += strlen(lListNameToken);
398 dim_start += strlen(lListDimsToken);
399 dir_start += strlen(lListDirToken);
400
401 /* Terminate token values with zero. */
402 char* s = strchr(name_start, ' ');
403 if (s != NULL) {
404 *s = '\0';
405 }
406 s = strchr(dim_start, ' ');
407 if (s != NULL) {
408 *s = '\0';
409 }
410 s = strchr(dir_start, ' ');
411 if (s != NULL) {
412 *s = '\0';
413 }
414
415 /* Create and initialize qemu camera. */
416 EmulatedQemuCamera* qemu_cam =
417 new EmulatedQemuCamera(index, &HAL_MODULE_INFO_SYM.common);
418 if (NULL != qemu_cam) {
419 res = qemu_cam->Initialize(name_start, dim_start, dir_start);
420 if (res == NO_ERROR) {
421 mEmulatedCameras[index] = qemu_cam;
422 index++;
423 } else {
424 delete qemu_cam;
425 }
426 } else {
427 ALOGE("%s: Unable to instantiate EmulatedQemuCamera",
428 __FUNCTION__);
429 }
430 } else {
431 ALOGW("%s: Bad camera information: %s", __FUNCTION__, cur_entry);
432 }
433
434 cur_entry = next_entry;
435 }
436
437 mEmulatedCameraNum = index;
438 }
439
isBackFakeCameraEmulationOn()440 bool EmulatedCameraFactory::isBackFakeCameraEmulationOn()
441 {
442 /* Defined by 'qemu.sf.fake_camera' boot property: if property exist, and
443 * is set to 'both', or 'back', then fake camera is used to emulate back
444 * camera. */
445 char prop[PROPERTY_VALUE_MAX];
446 if ((property_get("qemu.sf.fake_camera", prop, NULL) > 0) &&
447 (!strcmp(prop, "both") || !strcmp(prop, "back"))) {
448 return true;
449 } else {
450 return false;
451 }
452 }
453
getBackCameraHalVersion()454 int EmulatedCameraFactory::getBackCameraHalVersion()
455 {
456 /* Defined by 'qemu.sf.back_camera_hal_version' boot property: if the
457 * property doesn't exist, it is assumed to be 1. */
458 char prop[PROPERTY_VALUE_MAX];
459 if (property_get("qemu.sf.back_camera_hal", prop, NULL) > 0) {
460 char *prop_end = prop;
461 int val = strtol(prop, &prop_end, 10);
462 if (*prop_end == '\0') {
463 return val;
464 }
465 // Badly formatted property, should just be a number
466 ALOGE("qemu.sf.back_camera_hal is not a number: %s", prop);
467 }
468 return 1;
469 }
470
isFrontFakeCameraEmulationOn()471 bool EmulatedCameraFactory::isFrontFakeCameraEmulationOn()
472 {
473 /* Defined by 'qemu.sf.fake_camera' boot property: if property exist, and
474 * is set to 'both', or 'front', then fake camera is used to emulate front
475 * camera. */
476 char prop[PROPERTY_VALUE_MAX];
477 if ((property_get("qemu.sf.fake_camera", prop, NULL) > 0) &&
478 (!strcmp(prop, "both") || !strcmp(prop, "front"))) {
479 return true;
480 } else {
481 return false;
482 }
483 }
484
getFrontCameraHalVersion()485 int EmulatedCameraFactory::getFrontCameraHalVersion()
486 {
487 /* Defined by 'qemu.sf.front_camera_hal_version' boot property: if the
488 * property doesn't exist, it is assumed to be 1. */
489 char prop[PROPERTY_VALUE_MAX];
490 if (property_get("qemu.sf.front_camera_hal", prop, NULL) > 0) {
491 char *prop_end = prop;
492 int val = strtol(prop, &prop_end, 10);
493 if (*prop_end == '\0') {
494 return val;
495 }
496 // Badly formatted property, should just be a number
497 ALOGE("qemu.sf.front_camera_hal is not a number: %s", prop);
498 }
499 return 1;
500 }
501
onStatusChanged(int cameraId,int newStatus)502 void EmulatedCameraFactory::onStatusChanged(int cameraId, int newStatus) {
503
504 EmulatedBaseCamera *cam = mEmulatedCameras[cameraId];
505 if (!cam) {
506 ALOGE("%s: Invalid camera ID %d", __FUNCTION__, cameraId);
507 return;
508 }
509
510 /**
511 * (Order is important)
512 * Send the callback first to framework, THEN close the camera.
513 */
514
515 if (newStatus == cam->getHotplugStatus()) {
516 ALOGW("%s: Ignoring transition to the same status", __FUNCTION__);
517 return;
518 }
519
520 const camera_module_callbacks_t* cb = mCallbacks;
521 if (cb != NULL && cb->camera_device_status_change != NULL) {
522 cb->camera_device_status_change(cb, cameraId, newStatus);
523 }
524
525 if (newStatus == CAMERA_DEVICE_STATUS_NOT_PRESENT) {
526 cam->unplugCamera();
527 } else if (newStatus == CAMERA_DEVICE_STATUS_PRESENT) {
528 cam->plugCamera();
529 }
530
531 }
532
533 /********************************************************************************
534 * Initializer for the static member structure.
535 *******************************************************************************/
536
537 /* Entry point for camera HAL API. */
538 struct hw_module_methods_t EmulatedCameraFactory::mCameraModuleMethods = {
539 open: EmulatedCameraFactory::device_open
540 };
541
542 }; /* namespace android */
543