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