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
25 #include "EmulatedCameraFactory.h"
26 #include "EmulatedCameraHotplugThread.h"
27 #include "EmulatedFakeCamera.h"
28 #include "EmulatedFakeCamera2.h"
29 #include "EmulatedFakeCamera3.h"
30 #include "EmulatedQemuCamera.h"
31 #include "EmulatedQemuCamera3.h"
32
33 #include <log/log.h>
34 #include <cutils/properties.h>
35
36 extern camera_module_t HAL_MODULE_INFO_SYM;
37
38 /*
39 * A global instance of EmulatedCameraFactory is statically instantiated and
40 * initialized when camera emulation HAL is loaded.
41 */
42 android::EmulatedCameraFactory gEmulatedCameraFactory;
43
44 namespace android {
45
EmulatedCameraFactory()46 EmulatedCameraFactory::EmulatedCameraFactory() :
47 mQemuClient(),
48 mEmulatedCameras(nullptr),
49 mEmulatedCameraNum(0),
50 mFakeCameraNum(0),
51 mConstructedOK(false),
52 mCallbacks(nullptr) {
53
54 /*
55 * Figure out how many cameras need to be created, so we can allocate the
56 * array of emulated cameras before populating it.
57 */
58 int emulatedCamerasSize = 0;
59
60 // QEMU Cameras
61 std::vector<QemuCameraInfo> qemuCameras;
62 if (mQemuClient.connectClient(nullptr) == NO_ERROR) {
63 findQemuCameras(&qemuCameras);
64 emulatedCamerasSize += qemuCameras.size();
65 }
66
67 waitForQemuSfFakeCameraPropertyAvailable();
68 // Fake Cameras
69 if (isFakeCameraEmulationOn(/* backCamera */ true)) {
70 mFakeCameraNum++;
71 }
72 if (isFakeCameraEmulationOn(/* backCamera */ false)) {
73 mFakeCameraNum++;
74 }
75 emulatedCamerasSize += mFakeCameraNum;
76
77 /*
78 * We have the number of cameras we need to create, now allocate space for
79 * them.
80 */
81 mEmulatedCameras = new EmulatedBaseCamera*[emulatedCamerasSize];
82 if (mEmulatedCameras == nullptr) {
83 ALOGE("%s: Unable to allocate emulated camera array for %d entries",
84 __FUNCTION__, mEmulatedCameraNum);
85 return;
86 }
87
88 createQemuCameras(qemuCameras);
89
90 // Create fake cameras, if enabled.
91 if (isFakeCameraEmulationOn(/* backCamera */ true)) {
92 createFakeCamera(/* backCamera */ true);
93 }
94 if (isFakeCameraEmulationOn(/* backCamera */ false)) {
95 createFakeCamera(/* backCamera */ false);
96 }
97
98 ALOGE("%d cameras are being emulated. %d of them are fake cameras.",
99 mEmulatedCameraNum, mFakeCameraNum);
100
101 // Create hotplug thread.
102 {
103 Vector<int> cameraIdVector;
104 for (int i = 0; i < mEmulatedCameraNum; ++i) {
105 cameraIdVector.push_back(i);
106 }
107 mHotplugThread = new EmulatedCameraHotplugThread(&cameraIdVector[0],
108 mEmulatedCameraNum);
109 mHotplugThread->run("EmulatedCameraHotplugThread");
110 }
111
112 mConstructedOK = true;
113 }
114
~EmulatedCameraFactory()115 EmulatedCameraFactory::~EmulatedCameraFactory() {
116 if (mEmulatedCameras != nullptr) {
117 for (int n = 0; n < mEmulatedCameraNum; n++) {
118 if (mEmulatedCameras[n] != nullptr) {
119 delete mEmulatedCameras[n];
120 }
121 }
122 delete[] mEmulatedCameras;
123 }
124
125 if (mHotplugThread != nullptr) {
126 mHotplugThread->requestExit();
127 mHotplugThread->join();
128 }
129 }
130
131 /******************************************************************************
132 * Camera HAL API handlers.
133 *
134 * Each handler simply verifies existence of an appropriate EmulatedBaseCamera
135 * instance, and dispatches the call to that instance.
136 *
137 *****************************************************************************/
138
cameraDeviceOpen(int cameraId,hw_device_t ** device)139 int EmulatedCameraFactory::cameraDeviceOpen(int cameraId,
140 hw_device_t **device) {
141 ALOGV("%s: id = %d", __FUNCTION__, cameraId);
142
143 *device = nullptr;
144
145 if (!isConstructedOK()) {
146 ALOGE("%s: EmulatedCameraFactory has failed to initialize",
147 __FUNCTION__);
148 return -EINVAL;
149 }
150
151 if (cameraId < 0 || cameraId >= getEmulatedCameraNum()) {
152 ALOGE("%s: Camera id %d is out of bounds (%d)",
153 __FUNCTION__, cameraId, getEmulatedCameraNum());
154 return -ENODEV;
155 }
156
157 return mEmulatedCameras[cameraId]->connectCamera(device);
158 }
159
getCameraInfo(int cameraId,struct camera_info * info)160 int EmulatedCameraFactory::getCameraInfo(int cameraId,
161 struct camera_info *info) {
162 ALOGV("%s: id = %d", __FUNCTION__, cameraId);
163
164 if (!isConstructedOK()) {
165 ALOGE("%s: EmulatedCameraFactory has failed to initialize",
166 __FUNCTION__);
167 return -EINVAL;
168 }
169
170 if (cameraId < 0 || cameraId >= getEmulatedCameraNum()) {
171 ALOGE("%s: Camera id %d is out of bounds (%d)",
172 __FUNCTION__, cameraId, getEmulatedCameraNum());
173 return -ENODEV;
174 }
175
176 return mEmulatedCameras[cameraId]->getCameraInfo(info);
177 }
178
setCallbacks(const camera_module_callbacks_t * callbacks)179 int EmulatedCameraFactory::setCallbacks(
180 const camera_module_callbacks_t *callbacks) {
181 ALOGV("%s: callbacks = %p", __FUNCTION__, callbacks);
182
183 mCallbacks = callbacks;
184
185 return OK;
186 }
187
getVendorTagOps(vendor_tag_ops_t * ops)188 void EmulatedCameraFactory::getVendorTagOps(vendor_tag_ops_t* ops) {
189 ALOGV("%s: ops = %p", __FUNCTION__, ops);
190 // No vendor tags defined for emulator yet, so not touching ops.
191 }
192
193 /****************************************************************************
194 * Camera HAL API callbacks.
195 ***************************************************************************/
196
device_open(const hw_module_t * module,const char * name,hw_device_t ** device)197 int EmulatedCameraFactory::device_open(const hw_module_t *module, const char
198 *name, hw_device_t **device) {
199 /*
200 * Simply verify the parameters, and dispatch the call inside the
201 * EmulatedCameraFactory instance.
202 */
203
204 if (module != &HAL_MODULE_INFO_SYM.common) {
205 ALOGE("%s: Invalid module %p expected %p",
206 __FUNCTION__, module, &HAL_MODULE_INFO_SYM.common);
207 return -EINVAL;
208 }
209 if (name == nullptr) {
210 ALOGE("%s: NULL name is not expected here", __FUNCTION__);
211 return -EINVAL;
212 }
213
214 return gEmulatedCameraFactory.cameraDeviceOpen(atoi(name), device);
215 }
216
get_number_of_cameras()217 int EmulatedCameraFactory::get_number_of_cameras() {
218 return gEmulatedCameraFactory.getEmulatedCameraNum();
219 }
220
get_camera_info(int camera_id,struct camera_info * info)221 int EmulatedCameraFactory::get_camera_info(int camera_id,
222 struct camera_info *info) {
223 return gEmulatedCameraFactory.getCameraInfo(camera_id, info);
224 }
225
set_callbacks(const camera_module_callbacks_t * callbacks)226 int EmulatedCameraFactory::set_callbacks(
227 const camera_module_callbacks_t *callbacks) {
228 return gEmulatedCameraFactory.setCallbacks(callbacks);
229 }
230
get_vendor_tag_ops(vendor_tag_ops_t * ops)231 void EmulatedCameraFactory::get_vendor_tag_ops(vendor_tag_ops_t *ops) {
232 gEmulatedCameraFactory.getVendorTagOps(ops);
233 }
234
open_legacy(const struct hw_module_t * module,const char * id,uint32_t halVersion,struct hw_device_t ** device)235 int EmulatedCameraFactory::open_legacy(const struct hw_module_t *module,
236 const char *id, uint32_t halVersion, struct hw_device_t **device) {
237 // Not supporting legacy open.
238 return -ENOSYS;
239 }
240
241 /********************************************************************************
242 * Internal API
243 *******************************************************************************/
244
245 /*
246 * Camera information tokens passed in response to the "list" factory query.
247 */
248
249 // Device name token.
250 static const char *kListNameToken = "name=";
251 // Frame dimensions token.
252 static const char *kListDimsToken = "framedims=";
253 // Facing direction token.
254 static const char *kListDirToken = "dir=";
255
256
getTokenValue(const char * token,const std::string & s,char ** value)257 bool EmulatedCameraFactory::getTokenValue(const char *token,
258 const std::string &s, char **value) {
259 // Find the start of the token.
260 size_t tokenStart = s.find(token);
261 if (tokenStart == std::string::npos) {
262 return false;
263 }
264
265 // Advance to the beginning of the token value.
266 size_t valueStart = tokenStart + strlen(token);
267
268 // Find the length of the token value.
269 size_t valueLength = s.find(' ', valueStart) - valueStart;
270
271 // Extract the value substring.
272 std::string valueStr = s.substr(valueStart, valueLength);
273
274 // Convert to char*.
275 *value = new char[valueStr.length() + 1];
276 if (*value == nullptr) {
277 return false;
278 }
279 strcpy(*value, valueStr.c_str());
280
281 ALOGV("%s: Parsed value is \"%s\"", __FUNCTION__, *value);
282
283 return true;
284 }
285
findQemuCameras(std::vector<QemuCameraInfo> * qemuCameras)286 void EmulatedCameraFactory::findQemuCameras(
287 std::vector<QemuCameraInfo> *qemuCameras) {
288 // Obtain camera list.
289 char *cameraList = nullptr;
290 status_t res = mQemuClient.listCameras(&cameraList);
291
292 /*
293 * Empty list, or list containing just an EOL means that there were no
294 * connected cameras found.
295 */
296 if (res != NO_ERROR || cameraList == nullptr || *cameraList == '\0' ||
297 *cameraList == '\n') {
298 if (cameraList != nullptr) {
299 free(cameraList);
300 }
301 return;
302 }
303
304 /*
305 * Calculate number of connected cameras. Number of EOLs in the camera list
306 * is the number of the connected cameras.
307 */
308
309 std::string cameraListStr(cameraList);
310 free(cameraList);
311
312 size_t lineBegin = 0;
313 size_t lineEnd = cameraListStr.find('\n');
314 while (lineEnd != std::string::npos) {
315 std::string cameraStr = cameraListStr.substr(lineBegin, lineEnd - lineBegin);
316 // Parse the 'name', 'framedims', and 'dir' tokens.
317 char *name, *frameDims, *dir;
318 if (getTokenValue(kListNameToken, cameraStr, &name) &&
319 getTokenValue(kListDimsToken, cameraStr, &frameDims) &&
320 getTokenValue(kListDirToken, cameraStr, &dir)) {
321 // Push the camera info if it was all successfully parsed.
322 qemuCameras->push_back(QemuCameraInfo{
323 .name = name,
324 .frameDims = frameDims,
325 .dir = dir,
326 });
327 } else {
328 ALOGW("%s: Bad camera information: %s", __FUNCTION__,
329 cameraStr.c_str());
330 }
331 // Skip over the newline for the beginning of the next line.
332 lineBegin = lineEnd + 1;
333 lineEnd = cameraListStr.find('\n', lineBegin);
334 }
335 }
336
createQemuCameras(const std::vector<QemuCameraInfo> & qemuCameras)337 void EmulatedCameraFactory::createQemuCameras(
338 const std::vector<QemuCameraInfo> &qemuCameras) {
339 /*
340 * Iterate the list, creating, and initializing emulated QEMU cameras for each
341 * entry in the list.
342 */
343
344 /*
345 * We use this index only for determining which direction the webcam should
346 * face. Otherwise, mEmulatedCameraNum represents the camera ID and the
347 * index into mEmulatedCameras.
348 */
349 int qemuIndex = 0;
350 for (const auto &cameraInfo : qemuCameras) {
351 /*
352 * Here, we're assuming the first webcam is intended to be the back
353 * camera and any other webcams are front cameras.
354 */
355 int halVersion = 0;
356 if (qemuIndex == 0) {
357 halVersion = getCameraHalVersion(/* backCamera */ true);
358 } else {
359 halVersion = getCameraHalVersion(/* backCamera */ false);
360 }
361
362 // Create and initialize QEMU camera.
363 EmulatedBaseCamera *qemuCam = nullptr;
364 status_t res;
365 switch (halVersion) {
366 case 1:
367 EmulatedQemuCamera *qemuCamOne;
368 qemuCamOne = new EmulatedQemuCamera(
369 mEmulatedCameraNum, &HAL_MODULE_INFO_SYM.common);
370 if (qemuCamOne == nullptr) {
371 ALOGE("%s: Unable to instantiate EmulatedQemuCamera",
372 __FUNCTION__);
373 } else {
374 /*
375 * We have to initialize in each switch case, because
376 * EmulatedBaseCamera::Initialize has a different method
377 * signature.
378 *
379 * TODO: Having an EmulatedBaseQemuCamera class
380 * could fix this issue.
381 */
382 res = qemuCamOne->Initialize(
383 cameraInfo.name,
384 cameraInfo.frameDims,
385 cameraInfo.dir);
386 }
387 qemuCam = qemuCamOne;
388 break;
389 case 2:
390 ALOGE("%s: QEMU support for camera hal version %d is not "
391 "implemented", __FUNCTION__, halVersion);
392 break;
393 case 3:
394 EmulatedQemuCamera3 *qemuCamThree;
395 qemuCamThree = new EmulatedQemuCamera3(
396 mEmulatedCameraNum, &HAL_MODULE_INFO_SYM.common);
397 if (qemuCamThree == nullptr) {
398 ALOGE("%s: Unable to instantiate EmulatedQemuCamera3",
399 __FUNCTION__);
400 } else {
401 res = qemuCamThree->Initialize(
402 cameraInfo.name,
403 cameraInfo.frameDims,
404 cameraInfo.dir);
405 }
406 qemuCam = qemuCamThree;
407 break;
408 default:
409 ALOGE("%s: Unknown camera hal version requested: %d",
410 __FUNCTION__, halVersion);
411 }
412
413 if (qemuCam == nullptr) {
414 ALOGE("%s: Unable to instantiate EmulatedQemuCamera",
415 __FUNCTION__);
416 } else {
417 if (res == NO_ERROR) {
418 mEmulatedCameras[mEmulatedCameraNum] = qemuCam;
419 qemuIndex++;
420 mEmulatedCameraNum++;
421 } else {
422 delete qemuCam;
423 }
424 }
425 }
426 }
427
createFakeCamera(bool backCamera)428 void EmulatedCameraFactory::createFakeCamera(bool backCamera) {
429 int halVersion = getCameraHalVersion(backCamera);
430
431 /*
432 * Create and initialize the fake camera, using the index into
433 * mEmulatedCameras as the camera ID.
434 */
435 switch (halVersion) {
436 case 1:
437 mEmulatedCameras[mEmulatedCameraNum] =
438 new EmulatedFakeCamera(mEmulatedCameraNum, backCamera,
439 &HAL_MODULE_INFO_SYM.common);
440 break;
441 case 2:
442 mEmulatedCameras[mEmulatedCameraNum] =
443 new EmulatedFakeCamera2(mEmulatedCameraNum, backCamera,
444 &HAL_MODULE_INFO_SYM.common);
445 break;
446 case 3:
447 {
448 const char *key = "ro.kernel.qemu.camera.fake.rotating";
449 char prop[PROPERTY_VALUE_MAX];
450 if (property_get(key, prop, nullptr) > 0) {
451 mEmulatedCameras[mEmulatedCameraNum] =
452 new EmulatedFakeCamera(mEmulatedCameraNum, backCamera,
453 &HAL_MODULE_INFO_SYM.common);
454 } else {
455 mEmulatedCameras[mEmulatedCameraNum] =
456 new EmulatedFakeCamera3(mEmulatedCameraNum, backCamera,
457 &HAL_MODULE_INFO_SYM.common);
458 }
459 }
460 break;
461 default:
462 ALOGE("%s: Unknown %s camera hal version requested: %d",
463 __FUNCTION__, backCamera ? "back" : "front", halVersion);
464 }
465
466 if (mEmulatedCameras[mEmulatedCameraNum] == nullptr) {
467 ALOGE("%s: Unable to instantiate fake camera class", __FUNCTION__);
468 } else {
469 ALOGV("%s: %s camera device version is %d", __FUNCTION__,
470 backCamera ? "Back" : "Front", halVersion);
471 status_t res = mEmulatedCameras[mEmulatedCameraNum]->Initialize();
472 if (res == NO_ERROR) {
473 // Camera creation and initialization was successful.
474 mEmulatedCameraNum++;
475 } else {
476 ALOGE("%s: Unable to initialize %s camera %d: %s (%d)",
477 __FUNCTION__, backCamera ? "back" : "front",
478 mEmulatedCameraNum, strerror(-res), res);
479 delete mEmulatedCameras[mEmulatedCameraNum];
480 }
481 }
482 }
483
waitForQemuSfFakeCameraPropertyAvailable()484 void EmulatedCameraFactory::waitForQemuSfFakeCameraPropertyAvailable() {
485 /*
486 * Camera service may start running before qemu-props sets
487 * qemu.sf.fake_camera to any of the follwing four values:
488 * "none,front,back,both"; so we need to wait.
489 *
490 * android/camera/camera-service.c
491 * bug: 30768229
492 */
493 int numAttempts = 100;
494 char prop[PROPERTY_VALUE_MAX];
495 bool timeout = true;
496 for (int i = 0; i < numAttempts; ++i) {
497 if (property_get("qemu.sf.fake_camera", prop, nullptr) != 0 ) {
498 timeout = false;
499 break;
500 }
501 usleep(5000);
502 }
503 if (timeout) {
504 ALOGE("timeout (%dms) waiting for property qemu.sf.fake_camera to be set\n", 5 * numAttempts);
505 }
506 }
507
isFakeCameraEmulationOn(bool backCamera)508 bool EmulatedCameraFactory::isFakeCameraEmulationOn(bool backCamera) {
509 /*
510 * Defined by 'qemu.sf.fake_camera' boot property. If the property exists,
511 * and if it's set to 'both', then fake cameras are used to emulate both
512 * sides. If it's set to 'back' or 'front', then a fake camera is used only
513 * to emulate the back or front camera, respectively.
514 */
515 char prop[PROPERTY_VALUE_MAX];
516 if ((property_get("qemu.sf.fake_camera", prop, nullptr) > 0) &&
517 (!strcmp(prop, "both") ||
518 !strcmp(prop, backCamera ? "back" : "front"))) {
519 return true;
520 } else {
521 return false;
522 }
523 }
524
getCameraHalVersion(bool backCamera)525 int EmulatedCameraFactory::getCameraHalVersion(bool backCamera) {
526 /*
527 * Defined by 'qemu.sf.front_camera_hal_version' and
528 * 'qemu.sf.back_camera_hal_version' boot properties. If the property
529 * doesn't exist, it is assumed we are working with HAL v1.
530 */
531 char prop[PROPERTY_VALUE_MAX];
532 const char *propQuery = backCamera ?
533 "qemu.sf.back_camera_hal" :
534 "qemu.sf.front_camera_hal";
535 if (property_get(propQuery, prop, nullptr) > 0) {
536 char *propEnd = prop;
537 int val = strtol(prop, &propEnd, 10);
538 if (*propEnd == '\0') {
539 return val;
540 }
541 // Badly formatted property. It should just be a number.
542 ALOGE("qemu.sf.back_camera_hal is not a number: %s", prop);
543 }
544 return 3;
545 }
546
onStatusChanged(int cameraId,int newStatus)547 void EmulatedCameraFactory::onStatusChanged(int cameraId, int newStatus) {
548
549 EmulatedBaseCamera *cam = mEmulatedCameras[cameraId];
550 if (!cam) {
551 ALOGE("%s: Invalid camera ID %d", __FUNCTION__, cameraId);
552 return;
553 }
554
555 /*
556 * (Order is important)
557 * Send the callback first to framework, THEN close the camera.
558 */
559
560 if (newStatus == cam->getHotplugStatus()) {
561 ALOGW("%s: Ignoring transition to the same status", __FUNCTION__);
562 return;
563 }
564
565 const camera_module_callbacks_t* cb = mCallbacks;
566 if (cb != nullptr && cb->camera_device_status_change != nullptr) {
567 cb->camera_device_status_change(cb, cameraId, newStatus);
568 }
569
570 if (newStatus == CAMERA_DEVICE_STATUS_NOT_PRESENT) {
571 cam->unplugCamera();
572 } else if (newStatus == CAMERA_DEVICE_STATUS_PRESENT) {
573 cam->plugCamera();
574 }
575 }
576
577 /********************************************************************************
578 * Initializer for the static member structure.
579 *******************************************************************************/
580
581 // Entry point for camera HAL API.
582 struct hw_module_methods_t EmulatedCameraFactory::mCameraModuleMethods = {
583 .open = EmulatedCameraFactory::device_open
584 };
585
586 }; // end of namespace android
587