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 "EmulatedCameraFactory.h" 30 31 extern camera_module_t HAL_MODULE_INFO_SYM; 32 33 /* A global instance of EmulatedCameraFactory is statically instantiated and 34 * initialized when camera emulation HAL is loaded. 35 */ 36 android::EmulatedCameraFactory gEmulatedCameraFactory; 37 38 namespace android { 39 40 EmulatedCameraFactory::EmulatedCameraFactory() 41 : mQemuClient(), 42 mEmulatedCameras(NULL), 43 mEmulatedCameraNum(0), 44 mFakeCameraNum(0), 45 mConstructedOK(false) 46 { 47 status_t res; 48 /* Connect to the factory service in the emulator, and create Qemu cameras. */ 49 if (mQemuClient.connectClient(NULL) == NO_ERROR) { 50 /* Connection has succeeded. Create emulated cameras for each camera 51 * device, reported by the service. */ 52 createQemuCameras(); 53 } 54 55 if (isBackFakeCameraEmulationOn()) { 56 /* Camera ID. */ 57 const int camera_id = mEmulatedCameraNum; 58 /* Use fake camera to emulate back-facing camera. */ 59 mEmulatedCameraNum++; 60 61 /* Make sure that array is allocated (in case there were no 'qemu' 62 * cameras created. Note that we preallocate the array so it may contain 63 * two fake cameras: one facing back, and another facing front. */ 64 if (mEmulatedCameras == NULL) { 65 mEmulatedCameras = new EmulatedBaseCamera*[mEmulatedCameraNum + 1]; 66 if (mEmulatedCameras == NULL) { 67 ALOGE("%s: Unable to allocate emulated camera array for %d entries", 68 __FUNCTION__, mEmulatedCameraNum); 69 return; 70 } 71 memset(mEmulatedCameras, 0, 72 (mEmulatedCameraNum + 1) * sizeof(EmulatedBaseCamera*)); 73 } 74 75 /* Create, and initialize the fake camera */ 76 switch (getBackCameraHalVersion()) { 77 case 1: 78 mEmulatedCameras[camera_id] = 79 new EmulatedFakeCamera(camera_id, true, 80 &HAL_MODULE_INFO_SYM.common); 81 break; 82 case 2: 83 mEmulatedCameras[camera_id] = 84 new EmulatedFakeCamera2(camera_id, true, 85 &HAL_MODULE_INFO_SYM.common); 86 break; 87 default: 88 ALOGE("%s: Unknown back camera hal version requested: %d", __FUNCTION__, 89 getBackCameraHalVersion()); 90 } 91 if (mEmulatedCameras[camera_id] != NULL) { 92 ALOGV("%s: Back camera device version is %d", __FUNCTION__, 93 getBackCameraHalVersion()); 94 res = mEmulatedCameras[camera_id]->Initialize(); 95 if (res != NO_ERROR) { 96 ALOGE("%s: Unable to intialize back camera %d: %s (%d)", 97 __FUNCTION__, camera_id, strerror(-res), res); 98 delete mEmulatedCameras[camera_id]; 99 mEmulatedCameraNum--; 100 } 101 } else { 102 mEmulatedCameraNum--; 103 ALOGE("%s: Unable to instantiate fake camera class", __FUNCTION__); 104 } 105 } 106 107 if (isFrontFakeCameraEmulationOn()) { 108 /* Camera ID. */ 109 const int camera_id = mEmulatedCameraNum; 110 /* Use fake camera to emulate front-facing camera. */ 111 mEmulatedCameraNum++; 112 113 /* Make sure that array is allocated (in case there were no 'qemu' 114 * cameras created. */ 115 if (mEmulatedCameras == NULL) { 116 mEmulatedCameras = new EmulatedBaseCamera*[mEmulatedCameraNum]; 117 if (mEmulatedCameras == NULL) { 118 ALOGE("%s: Unable to allocate emulated camera array for %d entries", 119 __FUNCTION__, mEmulatedCameraNum); 120 return; 121 } 122 memset(mEmulatedCameras, 0, 123 mEmulatedCameraNum * sizeof(EmulatedBaseCamera*)); 124 } 125 126 /* Create, and initialize the fake camera */ 127 switch (getFrontCameraHalVersion()) { 128 case 1: 129 mEmulatedCameras[camera_id] = 130 new EmulatedFakeCamera(camera_id, false, 131 &HAL_MODULE_INFO_SYM.common); 132 break; 133 case 2: 134 mEmulatedCameras[camera_id] = 135 new EmulatedFakeCamera2(camera_id, false, 136 &HAL_MODULE_INFO_SYM.common); 137 break; 138 default: 139 ALOGE("%s: Unknown front camera hal version requested: %d", 140 __FUNCTION__, 141 getFrontCameraHalVersion()); 142 } 143 if (mEmulatedCameras[camera_id] != NULL) { 144 ALOGV("%s: Front camera device version is %d", __FUNCTION__, 145 getFrontCameraHalVersion()); 146 res = mEmulatedCameras[camera_id]->Initialize(); 147 if (res != NO_ERROR) { 148 ALOGE("%s: Unable to intialize front camera %d: %s (%d)", 149 __FUNCTION__, camera_id, strerror(-res), res); 150 delete mEmulatedCameras[camera_id]; 151 mEmulatedCameraNum--; 152 } 153 } else { 154 mEmulatedCameraNum--; 155 ALOGE("%s: Unable to instantiate fake camera class", __FUNCTION__); 156 } 157 } 158 159 ALOGV("%d cameras are being emulated. %d of them are fake cameras.", 160 mEmulatedCameraNum, mFakeCameraNum); 161 162 mConstructedOK = true; 163 } 164 165 EmulatedCameraFactory::~EmulatedCameraFactory() 166 { 167 if (mEmulatedCameras != NULL) { 168 for (int n = 0; n < mEmulatedCameraNum; n++) { 169 if (mEmulatedCameras[n] != NULL) { 170 delete mEmulatedCameras[n]; 171 } 172 } 173 delete[] mEmulatedCameras; 174 } 175 } 176 177 /**************************************************************************** 178 * Camera HAL API handlers. 179 * 180 * Each handler simply verifies existence of an appropriate EmulatedBaseCamera 181 * instance, and dispatches the call to that instance. 182 * 183 ***************************************************************************/ 184 185 int EmulatedCameraFactory::cameraDeviceOpen(int camera_id, hw_device_t** device) 186 { 187 ALOGV("%s: id = %d", __FUNCTION__, camera_id); 188 189 *device = NULL; 190 191 if (!isConstructedOK()) { 192 ALOGE("%s: EmulatedCameraFactory has failed to initialize", __FUNCTION__); 193 return -EINVAL; 194 } 195 196 if (camera_id < 0 || camera_id >= getEmulatedCameraNum()) { 197 ALOGE("%s: Camera id %d is out of bounds (%d)", 198 __FUNCTION__, camera_id, getEmulatedCameraNum()); 199 return -EINVAL; 200 } 201 202 return mEmulatedCameras[camera_id]->connectCamera(device); 203 } 204 205 int EmulatedCameraFactory::getCameraInfo(int camera_id, struct camera_info* info) 206 { 207 ALOGV("%s: id = %d", __FUNCTION__, camera_id); 208 209 if (!isConstructedOK()) { 210 ALOGE("%s: EmulatedCameraFactory has failed to initialize", __FUNCTION__); 211 return -EINVAL; 212 } 213 214 if (camera_id < 0 || camera_id >= getEmulatedCameraNum()) { 215 ALOGE("%s: Camera id %d is out of bounds (%d)", 216 __FUNCTION__, camera_id, getEmulatedCameraNum()); 217 return -EINVAL; 218 } 219 220 return mEmulatedCameras[camera_id]->getCameraInfo(info); 221 } 222 223 /**************************************************************************** 224 * Camera HAL API callbacks. 225 ***************************************************************************/ 226 227 int EmulatedCameraFactory::device_open(const hw_module_t* module, 228 const char* name, 229 hw_device_t** device) 230 { 231 /* 232 * Simply verify the parameters, and dispatch the call inside the 233 * EmulatedCameraFactory instance. 234 */ 235 236 if (module != &HAL_MODULE_INFO_SYM.common) { 237 ALOGE("%s: Invalid module %p expected %p", 238 __FUNCTION__, module, &HAL_MODULE_INFO_SYM.common); 239 return -EINVAL; 240 } 241 if (name == NULL) { 242 ALOGE("%s: NULL name is not expected here", __FUNCTION__); 243 return -EINVAL; 244 } 245 246 return gEmulatedCameraFactory.cameraDeviceOpen(atoi(name), device); 247 } 248 249 int EmulatedCameraFactory::get_number_of_cameras(void) 250 { 251 return gEmulatedCameraFactory.getEmulatedCameraNum(); 252 } 253 254 int EmulatedCameraFactory::get_camera_info(int camera_id, 255 struct camera_info* info) 256 { 257 return gEmulatedCameraFactory.getCameraInfo(camera_id, info); 258 } 259 260 /******************************************************************************** 261 * Internal API 262 *******************************************************************************/ 263 264 /* 265 * Camera information tokens passed in response to the "list" factory query. 266 */ 267 268 /* Device name token. */ 269 static const char lListNameToken[] = "name="; 270 /* Frame dimensions token. */ 271 static const char lListDimsToken[] = "framedims="; 272 /* Facing direction token. */ 273 static const char lListDirToken[] = "dir="; 274 275 void EmulatedCameraFactory::createQemuCameras() 276 { 277 /* Obtain camera list. */ 278 char* camera_list = NULL; 279 status_t res = mQemuClient.listCameras(&camera_list); 280 /* Empty list, or list containing just an EOL means that there were no 281 * connected cameras found. */ 282 if (res != NO_ERROR || camera_list == NULL || *camera_list == '\0' || 283 *camera_list == '\n') { 284 if (camera_list != NULL) { 285 free(camera_list); 286 } 287 return; 288 } 289 290 /* 291 * Calculate number of connected cameras. Number of EOLs in the camera list 292 * is the number of the connected cameras. 293 */ 294 295 int num = 0; 296 const char* eol = strchr(camera_list, '\n'); 297 while (eol != NULL) { 298 num++; 299 eol = strchr(eol + 1, '\n'); 300 } 301 302 /* Allocate the array for emulated camera instances. Note that we allocate 303 * two more entries for back and front fake camera emulation. */ 304 mEmulatedCameras = new EmulatedBaseCamera*[num + 2]; 305 if (mEmulatedCameras == NULL) { 306 ALOGE("%s: Unable to allocate emulated camera array for %d entries", 307 __FUNCTION__, num + 1); 308 free(camera_list); 309 return; 310 } 311 memset(mEmulatedCameras, 0, sizeof(EmulatedBaseCamera*) * (num + 1)); 312 313 /* 314 * Iterate the list, creating, and initializin emulated qemu cameras for each 315 * entry (line) in the list. 316 */ 317 318 int index = 0; 319 char* cur_entry = camera_list; 320 while (cur_entry != NULL && *cur_entry != '\0' && index < num) { 321 /* Find the end of the current camera entry, and terminate it with zero 322 * for simpler string manipulation. */ 323 char* next_entry = strchr(cur_entry, '\n'); 324 if (next_entry != NULL) { 325 *next_entry = '\0'; 326 next_entry++; // Start of the next entry. 327 } 328 329 /* Find 'name', 'framedims', and 'dir' tokens that are required here. */ 330 char* name_start = strstr(cur_entry, lListNameToken); 331 char* dim_start = strstr(cur_entry, lListDimsToken); 332 char* dir_start = strstr(cur_entry, lListDirToken); 333 if (name_start != NULL && dim_start != NULL && dir_start != NULL) { 334 /* Advance to the token values. */ 335 name_start += strlen(lListNameToken); 336 dim_start += strlen(lListDimsToken); 337 dir_start += strlen(lListDirToken); 338 339 /* Terminate token values with zero. */ 340 char* s = strchr(name_start, ' '); 341 if (s != NULL) { 342 *s = '\0'; 343 } 344 s = strchr(dim_start, ' '); 345 if (s != NULL) { 346 *s = '\0'; 347 } 348 s = strchr(dir_start, ' '); 349 if (s != NULL) { 350 *s = '\0'; 351 } 352 353 /* Create and initialize qemu camera. */ 354 EmulatedQemuCamera* qemu_cam = 355 new EmulatedQemuCamera(index, &HAL_MODULE_INFO_SYM.common); 356 if (NULL != qemu_cam) { 357 res = qemu_cam->Initialize(name_start, dim_start, dir_start); 358 if (res == NO_ERROR) { 359 mEmulatedCameras[index] = qemu_cam; 360 index++; 361 } else { 362 delete qemu_cam; 363 } 364 } else { 365 ALOGE("%s: Unable to instantiate EmulatedQemuCamera", 366 __FUNCTION__); 367 } 368 } else { 369 ALOGW("%s: Bad camera information: %s", __FUNCTION__, cur_entry); 370 } 371 372 cur_entry = next_entry; 373 } 374 375 mEmulatedCameraNum = index; 376 } 377 378 bool EmulatedCameraFactory::isBackFakeCameraEmulationOn() 379 { 380 /* Defined by 'qemu.sf.fake_camera' boot property: if property exist, and 381 * is set to 'both', or 'back', then fake camera is used to emulate back 382 * camera. */ 383 char prop[PROPERTY_VALUE_MAX]; 384 if ((property_get("qemu.sf.fake_camera", prop, NULL) > 0) && 385 (!strcmp(prop, "both") || !strcmp(prop, "back"))) { 386 return true; 387 } else { 388 return false; 389 } 390 } 391 392 int EmulatedCameraFactory::getBackCameraHalVersion() 393 { 394 /* Defined by 'qemu.sf.back_camera_hal_version' boot property: if the 395 * property doesn't exist, it is assumed to be 1. */ 396 char prop[PROPERTY_VALUE_MAX]; 397 if (property_get("qemu.sf.back_camera_hal", prop, NULL) > 0) { 398 char *prop_end = prop; 399 int val = strtol(prop, &prop_end, 10); 400 if (*prop_end == '\0') { 401 return val; 402 } 403 // Badly formatted property, should just be a number 404 ALOGE("qemu.sf.back_camera_hal is not a number: %s", prop); 405 } 406 return 1; 407 } 408 409 bool EmulatedCameraFactory::isFrontFakeCameraEmulationOn() 410 { 411 /* Defined by 'qemu.sf.fake_camera' boot property: if property exist, and 412 * is set to 'both', or 'front', then fake camera is used to emulate front 413 * camera. */ 414 char prop[PROPERTY_VALUE_MAX]; 415 if ((property_get("qemu.sf.fake_camera", prop, NULL) > 0) && 416 (!strcmp(prop, "both") || !strcmp(prop, "front"))) { 417 return true; 418 } else { 419 return false; 420 } 421 } 422 423 int EmulatedCameraFactory::getFrontCameraHalVersion() 424 { 425 /* Defined by 'qemu.sf.front_camera_hal_version' boot property: if the 426 * property doesn't exist, it is assumed to be 1. */ 427 char prop[PROPERTY_VALUE_MAX]; 428 if (property_get("qemu.sf.front_camera_hal", prop, NULL) > 0) { 429 char *prop_end = prop; 430 int val = strtol(prop, &prop_end, 10); 431 if (*prop_end == '\0') { 432 return val; 433 } 434 // Badly formatted property, should just be a number 435 ALOGE("qemu.sf.front_camera_hal is not a number: %s", prop); 436 } 437 return 1; 438 } 439 440 /******************************************************************************** 441 * Initializer for the static member structure. 442 *******************************************************************************/ 443 444 /* Entry point for camera HAL API. */ 445 struct hw_module_methods_t EmulatedCameraFactory::mCameraModuleMethods = { 446 open: EmulatedCameraFactory::device_open 447 }; 448 449 }; /* namespace android */ 450