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 "EmulatedCameraFactory.h" 29 30 extern camera_module_t HAL_MODULE_INFO_SYM; 31 32 /* A global instance of EmulatedCameraFactory is statically instantiated and 33 * initialized when camera emulation HAL is loaded. 34 */ 35 android::EmulatedCameraFactory gEmulatedCameraFactory; 36 37 namespace android { 38 39 EmulatedCameraFactory::EmulatedCameraFactory() 40 : mQemuClient(), 41 mEmulatedCameras(NULL), 42 mEmulatedCameraNum(0), 43 mFakeCameraID(-1), 44 mConstructedOK(false) 45 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 (isFakeCameraEmulationOn()) { 55 /* ID fake camera with the number of created 'qemud' cameras. */ 56 mFakeCameraID = mEmulatedCameraNum; 57 mEmulatedCameraNum++; 58 59 /* Make sure that array is allocated (in case there were no 'qemu' 60 * cameras created. */ 61 if (mEmulatedCameras == NULL) { 62 mEmulatedCameras = new EmulatedCamera*[mEmulatedCameraNum]; 63 if (mEmulatedCameras == NULL) { 64 LOGE("%s: Unable to allocate emulated camera array for %d entries", 65 __FUNCTION__, mEmulatedCameraNum); 66 return; 67 } 68 memset(mEmulatedCameras, 0, mEmulatedCameraNum * sizeof(EmulatedCamera*)); 69 } 70 71 /* Create, and initialize the fake camera */ 72 mEmulatedCameras[mFakeCameraID] = 73 new EmulatedFakeCamera(mFakeCameraID, &HAL_MODULE_INFO_SYM.common); 74 if (mEmulatedCameras[mFakeCameraID] != NULL) { 75 if (mEmulatedCameras[mFakeCameraID]->Initialize() != NO_ERROR) { 76 delete mEmulatedCameras[mFakeCameraID]; 77 mEmulatedCameras--; 78 mFakeCameraID = -1; 79 } 80 } else { 81 mEmulatedCameras--; 82 mFakeCameraID = -1; 83 LOGE("%s: Unable to instantiate fake camera class", __FUNCTION__); 84 } 85 } else { 86 LOGD("Fake camera emulation is disabled."); 87 } 88 89 LOGV("%d cameras are being emulated. Fake camera ID is %d", 90 mEmulatedCameraNum, mFakeCameraID); 91 92 mConstructedOK = true; 93 } 94 95 EmulatedCameraFactory::~EmulatedCameraFactory() 96 { 97 if (mEmulatedCameras != NULL) { 98 for (int n = 0; n < mEmulatedCameraNum; n++) { 99 if (mEmulatedCameras[n] != NULL) { 100 delete mEmulatedCameras[n]; 101 } 102 } 103 delete[] mEmulatedCameras; 104 } 105 } 106 107 /**************************************************************************** 108 * Camera HAL API handlers. 109 * 110 * Each handler simply verifies existence of an appropriate EmulatedCamera 111 * instance, and dispatches the call to that instance. 112 * 113 ***************************************************************************/ 114 115 int EmulatedCameraFactory::cameraDeviceOpen(int camera_id, hw_device_t** device) 116 { 117 LOGV("%s: id = %d", __FUNCTION__, camera_id); 118 119 *device = NULL; 120 121 if (!isConstructedOK()) { 122 LOGE("%s: EmulatedCameraFactory has failed to initialize", __FUNCTION__); 123 return -EINVAL; 124 } 125 126 if (camera_id < 0 || camera_id >= getEmulatedCameraNum()) { 127 LOGE("%s: Camera id %d is out of bounds (%d)", 128 __FUNCTION__, camera_id, getEmulatedCameraNum()); 129 return -EINVAL; 130 } 131 132 return mEmulatedCameras[camera_id]->connectCamera(device); 133 } 134 135 int EmulatedCameraFactory::getCameraInfo(int camera_id, struct camera_info* info) 136 { 137 LOGV("%s: id = %d", __FUNCTION__, camera_id); 138 139 if (!isConstructedOK()) { 140 LOGE("%s: EmulatedCameraFactory has failed to initialize", __FUNCTION__); 141 return -EINVAL; 142 } 143 144 if (camera_id < 0 || camera_id >= getEmulatedCameraNum()) { 145 LOGE("%s: Camera id %d is out of bounds (%d)", 146 __FUNCTION__, camera_id, getEmulatedCameraNum()); 147 return -EINVAL; 148 } 149 150 return mEmulatedCameras[camera_id]->getCameraInfo(info); 151 } 152 153 /**************************************************************************** 154 * Camera HAL API callbacks. 155 ***************************************************************************/ 156 157 int EmulatedCameraFactory::device_open(const hw_module_t* module, 158 const char* name, 159 hw_device_t** device) 160 { 161 /* 162 * Simply verify the parameters, and dispatch the call inside the 163 * EmulatedCameraFactory instance. 164 */ 165 166 if (module != &HAL_MODULE_INFO_SYM.common) { 167 LOGE("%s: Invalid module %p expected %p", 168 __FUNCTION__, module, &HAL_MODULE_INFO_SYM.common); 169 return -EINVAL; 170 } 171 if (name == NULL) { 172 LOGE("%s: NULL name is not expected here", __FUNCTION__); 173 return -EINVAL; 174 } 175 176 return gEmulatedCameraFactory.cameraDeviceOpen(atoi(name), device); 177 } 178 179 int EmulatedCameraFactory::get_number_of_cameras(void) 180 { 181 return gEmulatedCameraFactory.getEmulatedCameraNum(); 182 } 183 184 int EmulatedCameraFactory::get_camera_info(int camera_id, 185 struct camera_info* info) 186 { 187 return gEmulatedCameraFactory.getCameraInfo(camera_id, info); 188 } 189 190 /******************************************************************************** 191 * Internal API 192 *******************************************************************************/ 193 194 /* 195 * Camera information tokens passed in response to the "list" factory query. 196 */ 197 198 /* Device name token. */ 199 static const char lListNameToken[] = "name="; 200 /* Frame dimensions token. */ 201 static const char lListDimsToken[] = "framedims="; 202 /* Facing direction token. */ 203 static const char lListDirToken[] = "dir="; 204 205 void EmulatedCameraFactory::createQemuCameras() 206 { 207 /* Obtain camera list. */ 208 char* camera_list = NULL; 209 status_t res = mQemuClient.listCameras(&camera_list); 210 /* Empty list, or list containing just an EOL means that there were no 211 * connected cameras found. */ 212 if (res != NO_ERROR || camera_list == NULL || *camera_list == '\0' || 213 *camera_list == '\n') { 214 if (camera_list != NULL) { 215 free(camera_list); 216 } 217 return; 218 } 219 220 /* 221 * Calculate number of connected cameras. Number of EOLs in the camera list 222 * is the number of the connected cameras. 223 */ 224 225 int num = 0; 226 const char* eol = strchr(camera_list, '\n'); 227 while (eol != NULL) { 228 num++; 229 eol = strchr(eol + 1, '\n'); 230 } 231 232 /* Allocate the array for emulated camera instances. Note that we allocate 233 * one more entry for the fake camera emulation. */ 234 mEmulatedCameras = new EmulatedCamera*[num + 1]; 235 if (mEmulatedCameras == NULL) { 236 LOGE("%s: Unable to allocate emulated camera array for %d entries", 237 __FUNCTION__, num + 1); 238 free(camera_list); 239 return; 240 } 241 memset(mEmulatedCameras, 0, sizeof(EmulatedCamera*) * (num + 1)); 242 243 /* 244 * Iterate the list, creating, and initializin emulated qemu cameras for each 245 * entry (line) in the list. 246 */ 247 248 int index = 0; 249 char* cur_entry = camera_list; 250 while (cur_entry != NULL && *cur_entry != '\0' && index < num) { 251 /* Find the end of the current camera entry, and terminate it with zero 252 * for simpler string manipulation. */ 253 char* next_entry = strchr(cur_entry, '\n'); 254 if (next_entry != NULL) { 255 *next_entry = '\0'; 256 next_entry++; // Start of the next entry. 257 } 258 259 /* Find 'name', 'framedims', and 'dir' tokens that are required here. */ 260 char* name_start = strstr(cur_entry, lListNameToken); 261 char* dim_start = strstr(cur_entry, lListDimsToken); 262 char* dir_start = strstr(cur_entry, lListDirToken); 263 if (name_start != NULL && dim_start != NULL && dir_start != NULL) { 264 /* Advance to the token values. */ 265 name_start += strlen(lListNameToken); 266 dim_start += strlen(lListDimsToken); 267 dir_start += strlen(lListDirToken); 268 269 /* Terminate token values with zero. */ 270 char* s = strchr(name_start, ' '); 271 if (s != NULL) { 272 *s = '\0'; 273 } 274 s = strchr(dim_start, ' '); 275 if (s != NULL) { 276 *s = '\0'; 277 } 278 s = strchr(dir_start, ' '); 279 if (s != NULL) { 280 *s = '\0'; 281 } 282 283 /* Create and initialize qemu camera. */ 284 EmulatedQemuCamera* qemu_cam = 285 new EmulatedQemuCamera(index, &HAL_MODULE_INFO_SYM.common); 286 if (NULL != qemu_cam) { 287 res = qemu_cam->Initialize(name_start, dim_start, dir_start); 288 if (res == NO_ERROR) { 289 mEmulatedCameras[index] = qemu_cam; 290 index++; 291 } else { 292 delete qemu_cam; 293 } 294 } else { 295 LOGE("%s: Unable to instantiate EmulatedQemuCamera", 296 __FUNCTION__); 297 } 298 } else { 299 LOGW("%s: Bad camera information: %s", __FUNCTION__, cur_entry); 300 } 301 302 cur_entry = next_entry; 303 } 304 305 mEmulatedCameraNum = index; 306 } 307 308 bool EmulatedCameraFactory::isFakeCameraEmulationOn() 309 { 310 /* Defined by 'qemu.sf.fake_camera' boot property: If property is there 311 * and contains 'off', fake camera emulation is disabled. */ 312 char prop[PROPERTY_VALUE_MAX]; 313 if (property_get("qemu.sf.fake_camera", prop, NULL) <= 0 || 314 strcmp(prop, "off")) { 315 return true; 316 } else { 317 return false; 318 } 319 } 320 321 /******************************************************************************** 322 * Initializer for the static member structure. 323 *******************************************************************************/ 324 325 /* Entry point for camera HAL API. */ 326 struct hw_module_methods_t EmulatedCameraFactory::mCameraModuleMethods = { 327 open: EmulatedCameraFactory::device_open 328 }; 329 330 }; /* namespace android */ 331