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