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 <cutils/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 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 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 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 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 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 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 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 217 int EmulatedCameraFactory::get_number_of_cameras() { 218 return gEmulatedCameraFactory.getEmulatedCameraNum(); 219 } 220 221 int EmulatedCameraFactory::get_camera_info(int camera_id, 222 struct camera_info *info) { 223 return gEmulatedCameraFactory.getCameraInfo(camera_id, info); 224 } 225 226 int EmulatedCameraFactory::set_callbacks( 227 const camera_module_callbacks_t *callbacks) { 228 return gEmulatedCameraFactory.setCallbacks(callbacks); 229 } 230 231 void EmulatedCameraFactory::get_vendor_tag_ops(vendor_tag_ops_t *ops) { 232 gEmulatedCameraFactory.getVendorTagOps(ops); 233 } 234 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 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 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); 316 317 // Parse the 'name', 'framedims', and 'dir' tokens. 318 char *name, *frameDims, *dir; 319 if (getTokenValue(kListNameToken, cameraStr, &name) && 320 getTokenValue(kListDimsToken, cameraStr, &frameDims) && 321 getTokenValue(kListDirToken, cameraStr, &dir)) { 322 // Push the camera info if it was all successfully parsed. 323 qemuCameras->push_back(QemuCameraInfo{ 324 .name = name, 325 .frameDims = frameDims, 326 .dir = dir, 327 }); 328 } else { 329 ALOGW("%s: Bad camera information: %s", __FUNCTION__, 330 cameraStr.c_str()); 331 } 332 // Skip over the newline for the beginning of the next line. 333 lineBegin = lineEnd + 1; 334 lineEnd = cameraListStr.find('\n', lineBegin); 335 } 336 } 337 338 void EmulatedCameraFactory::createQemuCameras( 339 const std::vector<QemuCameraInfo> &qemuCameras) { 340 /* 341 * Iterate the list, creating, and initializing emulated QEMU cameras for each 342 * entry in the list. 343 */ 344 345 /* 346 * We use this index only for determining which direction the webcam should 347 * face. Otherwise, mEmulatedCameraNum represents the camera ID and the 348 * index into mEmulatedCameras. 349 */ 350 int qemuIndex = 0; 351 for (const auto &cameraInfo : qemuCameras) { 352 /* 353 * Here, we're assuming the first webcam is intended to be the back 354 * camera and any other webcams are front cameras. 355 */ 356 int halVersion = 0; 357 if (qemuIndex == 0) { 358 halVersion = getCameraHalVersion(/* backCamera */ true); 359 } else { 360 halVersion = getCameraHalVersion(/* backCamera */ false); 361 } 362 363 // Create and initialize QEMU camera. 364 EmulatedBaseCamera *qemuCam = nullptr; 365 status_t res; 366 switch (halVersion) { 367 case 1: 368 EmulatedQemuCamera *qemuCamOne; 369 qemuCamOne = new EmulatedQemuCamera( 370 mEmulatedCameraNum, &HAL_MODULE_INFO_SYM.common); 371 if (qemuCamOne == nullptr) { 372 ALOGE("%s: Unable to instantiate EmulatedQemuCamera", 373 __FUNCTION__); 374 } else { 375 /* 376 * We have to initialize in each switch case, because 377 * EmulatedBaseCamera::Initialize has a different method 378 * signature. 379 * 380 * TODO: Having an EmulatedBaseQemuCamera class 381 * could fix this issue. 382 */ 383 res = qemuCamOne->Initialize( 384 cameraInfo.name, 385 cameraInfo.frameDims, 386 cameraInfo.dir); 387 } 388 qemuCam = qemuCamOne; 389 break; 390 case 2: 391 ALOGE("%s: QEMU support for camera hal version %d is not " 392 "implemented", __FUNCTION__, halVersion); 393 break; 394 case 3: 395 EmulatedQemuCamera3 *qemuCamThree; 396 qemuCamThree = new EmulatedQemuCamera3( 397 mEmulatedCameraNum, &HAL_MODULE_INFO_SYM.common); 398 if (qemuCamThree == nullptr) { 399 ALOGE("%s: Unable to instantiate EmulatedQemuCamera3", 400 __FUNCTION__); 401 } else { 402 res = qemuCamThree->Initialize( 403 cameraInfo.name, 404 cameraInfo.frameDims, 405 cameraInfo.dir); 406 } 407 qemuCam = qemuCamThree; 408 break; 409 default: 410 ALOGE("%s: Unknown camera hal version requested: %d", 411 __FUNCTION__, halVersion); 412 } 413 414 if (qemuCam == nullptr) { 415 ALOGE("%s: Unable to instantiate EmulatedQemuCamera", 416 __FUNCTION__); 417 } else { 418 if (res == NO_ERROR) { 419 mEmulatedCameras[mEmulatedCameraNum] = qemuCam; 420 qemuIndex++; 421 mEmulatedCameraNum++; 422 } else { 423 delete qemuCam; 424 } 425 } 426 } 427 } 428 429 void EmulatedCameraFactory::createFakeCamera(bool backCamera) { 430 int halVersion = getCameraHalVersion(backCamera); 431 432 /* 433 * Create and initialize the fake camera, using the index into 434 * mEmulatedCameras as the camera ID. 435 */ 436 switch (halVersion) { 437 case 1: 438 mEmulatedCameras[mEmulatedCameraNum] = 439 new EmulatedFakeCamera(mEmulatedCameraNum, backCamera, 440 &HAL_MODULE_INFO_SYM.common); 441 break; 442 case 2: 443 mEmulatedCameras[mEmulatedCameraNum] = 444 new EmulatedFakeCamera2(mEmulatedCameraNum, backCamera, 445 &HAL_MODULE_INFO_SYM.common); 446 break; 447 case 3: 448 { 449 const char *key = "ro.kernel.qemu.camera.fake.rotating"; 450 char prop[PROPERTY_VALUE_MAX]; 451 if (property_get(key, prop, nullptr) > 0) { 452 mEmulatedCameras[mEmulatedCameraNum] = 453 new EmulatedFakeCamera(mEmulatedCameraNum, backCamera, 454 &HAL_MODULE_INFO_SYM.common); 455 } else { 456 mEmulatedCameras[mEmulatedCameraNum] = 457 new EmulatedFakeCamera3(mEmulatedCameraNum, backCamera, 458 &HAL_MODULE_INFO_SYM.common); 459 } 460 } 461 break; 462 default: 463 ALOGE("%s: Unknown %s camera hal version requested: %d", 464 __FUNCTION__, backCamera ? "back" : "front", halVersion); 465 } 466 467 if (mEmulatedCameras[mEmulatedCameraNum] == nullptr) { 468 ALOGE("%s: Unable to instantiate fake camera class", __FUNCTION__); 469 } else { 470 ALOGV("%s: %s camera device version is %d", __FUNCTION__, 471 backCamera ? "Back" : "Front", halVersion); 472 status_t res = mEmulatedCameras[mEmulatedCameraNum]->Initialize(); 473 if (res == NO_ERROR) { 474 // Camera creation and initialization was successful. 475 mEmulatedCameraNum++; 476 } else { 477 ALOGE("%s: Unable to initialize %s camera %d: %s (%d)", 478 __FUNCTION__, backCamera ? "back" : "front", 479 mEmulatedCameraNum, strerror(-res), res); 480 delete mEmulatedCameras[mEmulatedCameraNum]; 481 } 482 } 483 } 484 485 void EmulatedCameraFactory::waitForQemuSfFakeCameraPropertyAvailable() { 486 /* 487 * Camera service may start running before qemu-props sets 488 * qemu.sf.fake_camera to any of the follwing four values: 489 * "none,front,back,both"; so we need to wait. 490 * 491 * android/camera/camera-service.c 492 * bug: 30768229 493 */ 494 int numAttempts = 100; 495 char prop[PROPERTY_VALUE_MAX]; 496 bool timeout = true; 497 for (int i = 0; i < numAttempts; ++i) { 498 if (property_get("qemu.sf.fake_camera", prop, nullptr) != 0 ) { 499 timeout = false; 500 break; 501 } 502 usleep(5000); 503 } 504 if (timeout) { 505 ALOGE("timeout (%dms) waiting for property qemu.sf.fake_camera to be set\n", 5 * numAttempts); 506 } 507 } 508 509 bool EmulatedCameraFactory::isFakeCameraEmulationOn(bool backCamera) { 510 /* 511 * Defined by 'qemu.sf.fake_camera' boot property. If the property exists, 512 * and if it's set to 'both', then fake cameras are used to emulate both 513 * sides. If it's set to 'back' or 'front', then a fake camera is used only 514 * to emulate the back or front camera, respectively. 515 */ 516 char prop[PROPERTY_VALUE_MAX]; 517 if ((property_get("qemu.sf.fake_camera", prop, nullptr) > 0) && 518 (!strcmp(prop, "both") || 519 !strcmp(prop, backCamera ? "back" : "front"))) { 520 return true; 521 } else { 522 return false; 523 } 524 } 525 526 int EmulatedCameraFactory::getCameraHalVersion(bool backCamera) { 527 /* 528 * Defined by 'qemu.sf.front_camera_hal_version' and 529 * 'qemu.sf.back_camera_hal_version' boot properties. If the property 530 * doesn't exist, it is assumed we are working with HAL v1. 531 */ 532 char prop[PROPERTY_VALUE_MAX]; 533 const char *propQuery = backCamera ? 534 "qemu.sf.back_camera_hal" : 535 "qemu.sf.front_camera_hal"; 536 if (property_get(propQuery, prop, nullptr) > 0) { 537 char *propEnd = prop; 538 int val = strtol(prop, &propEnd, 10); 539 if (*propEnd == '\0') { 540 return val; 541 } 542 // Badly formatted property. It should just be a number. 543 ALOGE("qemu.sf.back_camera_hal is not a number: %s", prop); 544 } 545 return 3; 546 } 547 548 void EmulatedCameraFactory::onStatusChanged(int cameraId, int newStatus) { 549 550 EmulatedBaseCamera *cam = mEmulatedCameras[cameraId]; 551 if (!cam) { 552 ALOGE("%s: Invalid camera ID %d", __FUNCTION__, cameraId); 553 return; 554 } 555 556 /* 557 * (Order is important) 558 * Send the callback first to framework, THEN close the camera. 559 */ 560 561 if (newStatus == cam->getHotplugStatus()) { 562 ALOGW("%s: Ignoring transition to the same status", __FUNCTION__); 563 return; 564 } 565 566 const camera_module_callbacks_t* cb = mCallbacks; 567 if (cb != nullptr && cb->camera_device_status_change != nullptr) { 568 cb->camera_device_status_change(cb, cameraId, newStatus); 569 } 570 571 if (newStatus == CAMERA_DEVICE_STATUS_NOT_PRESENT) { 572 cam->unplugCamera(); 573 } else if (newStatus == CAMERA_DEVICE_STATUS_PRESENT) { 574 cam->plugCamera(); 575 } 576 } 577 578 /******************************************************************************** 579 * Initializer for the static member structure. 580 *******************************************************************************/ 581 582 // Entry point for camera HAL API. 583 struct hw_module_methods_t EmulatedCameraFactory::mCameraModuleMethods = { 584 open: EmulatedCameraFactory::device_open 585 }; 586 587 }; // end of namespace android 588