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 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 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 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 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 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 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 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 296 int EmulatedCameraFactory::get_number_of_cameras(void) 297 { 298 return gEmulatedCameraFactory.getEmulatedCameraNum(); 299 } 300 301 int EmulatedCameraFactory::get_camera_info(int camera_id, 302 struct camera_info* info) 303 { 304 return gEmulatedCameraFactory.getCameraInfo(camera_id, info); 305 } 306 307 int EmulatedCameraFactory::set_callbacks( 308 const camera_module_callbacks_t *callbacks) 309 { 310 return gEmulatedCameraFactory.setCallbacks(callbacks); 311 } 312 313 void EmulatedCameraFactory::get_vendor_tag_ops(vendor_tag_ops_t* ops) 314 { 315 gEmulatedCameraFactory.getVendorTagOps(ops); 316 } 317 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 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 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 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 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 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 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 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