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