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