2 * Copyright (C) 2011 The Android Open Source Project
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
18 * Contains implementation of a class EmulatedCameraFactory that manages cameras
19 * available for emulation.
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"
33 extern camera_module_t HAL_MODULE_INFO_SYM;
35 /* A global instance of EmulatedCameraFactory is statically instantiated and
36 * initialized when camera emulation HAL is loaded.
38 android::EmulatedCameraFactory gEmulatedCameraFactory;
42 EmulatedCameraFactory::EmulatedCameraFactory()
44 mEmulatedCameras(NULL),
45 mEmulatedCameraNum(0),
47 mConstructedOK(false),
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. */
58 if (isBackFakeCameraEmulationOn()) {
60 const int camera_id = mEmulatedCameraNum;
61 /* Use fake camera to emulate back-facing camera. */
64 /* Make sure that array is allocated (in case there were no 'qemu'
65 * cameras created. Note that we preallocate the array so it may contain
66 * two fake cameras: one facing back, and another facing front. */
67 if (mEmulatedCameras == NULL) {
68 mEmulatedCameras = new EmulatedBaseCamera*[mEmulatedCameraNum + 1];
69 if (mEmulatedCameras == NULL) {
70 ALOGE("%s: Unable to allocate emulated camera array for %d entries",
71 __FUNCTION__, mEmulatedCameraNum);
74 memset(mEmulatedCameras, 0,
75 (mEmulatedCameraNum + 1) * sizeof(EmulatedBaseCamera*));
78 /* Create, and initialize the fake camera */
79 switch (getBackCameraHalVersion()) {
81 mEmulatedCameras[camera_id] =
82 new EmulatedFakeCamera(camera_id, true,
83 &HAL_MODULE_INFO_SYM.common);
86 mEmulatedCameras[camera_id] =
87 new EmulatedFakeCamera2(camera_id, true,
88 &HAL_MODULE_INFO_SYM.common);
91 mEmulatedCameras[camera_id] =
92 new EmulatedFakeCamera3(camera_id, true,
93 &HAL_MODULE_INFO_SYM.common);
96 ALOGE("%s: Unknown back camera hal version requested: %d", __FUNCTION__,
97 getBackCameraHalVersion());
99 if (mEmulatedCameras[camera_id] != NULL) {
100 ALOGV("%s: Back camera device version is %d", __FUNCTION__,
101 getBackCameraHalVersion());
102 res = mEmulatedCameras[camera_id]->Initialize();
103 if (res != NO_ERROR) {
104 ALOGE("%s: Unable to intialize back camera %d: %s (%d)",
105 __FUNCTION__, camera_id, strerror(-res), res);
106 delete mEmulatedCameras[camera_id];
107 mEmulatedCameraNum--;
110 mEmulatedCameraNum--;
111 ALOGE("%s: Unable to instantiate fake camera class", __FUNCTION__);
115 if (isFrontFakeCameraEmulationOn()) {
117 const int camera_id = mEmulatedCameraNum;
118 /* Use fake camera to emulate front-facing camera. */
119 mEmulatedCameraNum++;
121 /* Make sure that array is allocated (in case there were no 'qemu'
122 * cameras created. */
123 if (mEmulatedCameras == NULL) {
124 mEmulatedCameras = new EmulatedBaseCamera*[mEmulatedCameraNum];
125 if (mEmulatedCameras == NULL) {
126 ALOGE("%s: Unable to allocate emulated camera array for %d entries",
127 __FUNCTION__, mEmulatedCameraNum);
130 memset(mEmulatedCameras, 0,
131 mEmulatedCameraNum * sizeof(EmulatedBaseCamera*));
134 /* Create, and initialize the fake camera */
135 switch (getFrontCameraHalVersion()) {
137 mEmulatedCameras[camera_id] =
138 new EmulatedFakeCamera(camera_id, false,
139 &HAL_MODULE_INFO_SYM.common);
142 mEmulatedCameras[camera_id] =
143 new EmulatedFakeCamera2(camera_id, false,
144 &HAL_MODULE_INFO_SYM.common);
147 mEmulatedCameras[camera_id] =
148 new EmulatedFakeCamera3(camera_id, false,
149 &HAL_MODULE_INFO_SYM.common);
152 ALOGE("%s: Unknown front camera hal version requested: %d",
154 getFrontCameraHalVersion());
156 if (mEmulatedCameras[camera_id] != NULL) {
157 ALOGV("%s: Front camera device version is %d", __FUNCTION__,
158 getFrontCameraHalVersion());
159 res = mEmulatedCameras[camera_id]->Initialize();
160 if (res != NO_ERROR) {
161 ALOGE("%s: Unable to intialize front camera %d: %s (%d)",
162 __FUNCTION__, camera_id, strerror(-res), res);
163 delete mEmulatedCameras[camera_id];
164 mEmulatedCameraNum--;
167 mEmulatedCameraNum--;
168 ALOGE("%s: Unable to instantiate fake camera class", __FUNCTION__);
172 ALOGV("%d cameras are being emulated. %d of them are fake cameras.",
173 mEmulatedCameraNum, mFakeCameraNum);
175 /* Create hotplug thread */
177 Vector<int> cameraIdVector;
178 for (int i = 0; i < mEmulatedCameraNum; ++i) {
179 cameraIdVector.push_back(i);
181 mHotplugThread = new EmulatedCameraHotplugThread(&cameraIdVector[0],
183 mHotplugThread->run("EmulatedCameraHotplugThread");
186 mConstructedOK = true;
189 EmulatedCameraFactory::~EmulatedCameraFactory()
191 if (mEmulatedCameras != NULL) {
192 for (int n = 0; n < mEmulatedCameraNum; n++) {
193 if (mEmulatedCameras[n] != NULL) {
194 delete mEmulatedCameras[n];
197 delete[] mEmulatedCameras;
200 if (mHotplugThread != NULL) {
201 mHotplugThread->requestExit();
202 mHotplugThread->join();
206 /****************************************************************************
207 * Camera HAL API handlers.
209 * Each handler simply verifies existence of an appropriate EmulatedBaseCamera
210 * instance, and dispatches the call to that instance.
212 ***************************************************************************/
214 int EmulatedCameraFactory::cameraDeviceOpen(int camera_id, hw_device_t** device)
216 ALOGV("%s: id = %d", __FUNCTION__, camera_id);
220 if (!isConstructedOK()) {
221 ALOGE("%s: EmulatedCameraFactory has failed to initialize", __FUNCTION__);
225 if (camera_id < 0 || camera_id >= getEmulatedCameraNum()) {
226 ALOGE("%s: Camera id %d is out of bounds (%d)",
227 __FUNCTION__, camera_id, getEmulatedCameraNum());
231 return mEmulatedCameras[camera_id]->connectCamera(device);
234 int EmulatedCameraFactory::getCameraInfo(int camera_id, struct camera_info* info)
236 ALOGV("%s: id = %d", __FUNCTION__, camera_id);
238 if (!isConstructedOK()) {
239 ALOGE("%s: EmulatedCameraFactory has failed to initialize", __FUNCTION__);
243 if (camera_id < 0 || camera_id >= getEmulatedCameraNum()) {
244 ALOGE("%s: Camera id %d is out of bounds (%d)",
245 __FUNCTION__, camera_id, getEmulatedCameraNum());
249 return mEmulatedCameras[camera_id]->getCameraInfo(info);
252 int EmulatedCameraFactory::setCallbacks(
253 const camera_module_callbacks_t *callbacks)
255 ALOGV("%s: callbacks = %p", __FUNCTION__, callbacks);
257 mCallbacks = callbacks;
262 void EmulatedCameraFactory::getVendorTagOps(vendor_tag_ops_t* ops) {
263 ALOGV("%s: ops = %p", __FUNCTION__, ops);
265 // No vendor tags defined for emulator yet, so not touching ops
268 /****************************************************************************
269 * Camera HAL API callbacks.
270 ***************************************************************************/
272 int EmulatedCameraFactory::device_open(const hw_module_t* module,
274 hw_device_t** device)
277 * Simply verify the parameters, and dispatch the call inside the
278 * EmulatedCameraFactory instance.
281 if (module != &HAL_MODULE_INFO_SYM.common) {
282 ALOGE("%s: Invalid module %p expected %p",
283 __FUNCTION__, module, &HAL_MODULE_INFO_SYM.common);
287 ALOGE("%s: NULL name is not expected here", __FUNCTION__);
291 return gEmulatedCameraFactory.cameraDeviceOpen(atoi(name), device);
294 int EmulatedCameraFactory::get_number_of_cameras(void)
296 return gEmulatedCameraFactory.getEmulatedCameraNum();
299 int EmulatedCameraFactory::get_camera_info(int camera_id,
300 struct camera_info* info)
302 return gEmulatedCameraFactory.getCameraInfo(camera_id, info);
305 int EmulatedCameraFactory::set_callbacks(
306 const camera_module_callbacks_t *callbacks)
308 return gEmulatedCameraFactory.setCallbacks(callbacks);
311 void EmulatedCameraFactory::get_vendor_tag_ops(vendor_tag_ops_t* ops)
313 gEmulatedCameraFactory.getVendorTagOps(ops);
316 int EmulatedCameraFactory::open_legacy(const struct hw_module_t* module,
317 const char* id, uint32_t halVersion, struct hw_device_t** device) {
318 // Not supporting legacy open
322 /********************************************************************************
324 *******************************************************************************/
327 * Camera information tokens passed in response to the "list" factory query.
330 /* Device name token. */
331 static const char lListNameToken[] = "name=";
332 /* Frame dimensions token. */
333 static const char lListDimsToken[] = "framedims=";
334 /* Facing direction token. */
335 static const char lListDirToken[] = "dir=";
337 void EmulatedCameraFactory::createQemuCameras()
339 /* Obtain camera list. */
340 char* camera_list = NULL;
341 status_t res = mQemuClient.listCameras(&camera_list);
342 /* Empty list, or list containing just an EOL means that there were no
343 * connected cameras found. */
344 if (res != NO_ERROR || camera_list == NULL || *camera_list == '\0' ||
345 *camera_list == '\n') {
346 if (camera_list != NULL) {
353 * Calculate number of connected cameras. Number of EOLs in the camera list
354 * is the number of the connected cameras.
358 const char* eol = strchr(camera_list, '\n');
359 while (eol != NULL) {
361 eol = strchr(eol + 1, '\n');
364 /* Allocate the array for emulated camera instances. Note that we allocate
365 * two more entries for back and front fake camera emulation. */
366 mEmulatedCameras = new EmulatedBaseCamera*[num + 2];
367 if (mEmulatedCameras == NULL) {
368 ALOGE("%s: Unable to allocate emulated camera array for %d entries",
369 __FUNCTION__, num + 1);
373 memset(mEmulatedCameras, 0, sizeof(EmulatedBaseCamera*) * (num + 1));
376 * Iterate the list, creating, and initializin emulated qemu cameras for each
377 * entry (line) in the list.
381 char* cur_entry = camera_list;
382 while (cur_entry != NULL && *cur_entry != '\0' && index < num) {
383 /* Find the end of the current camera entry, and terminate it with zero
384 * for simpler string manipulation. */
385 char* next_entry = strchr(cur_entry, '\n');
386 if (next_entry != NULL) {
388 next_entry++; // Start of the next entry.
391 /* Find 'name', 'framedims', and 'dir' tokens that are required here. */
392 char* name_start = strstr(cur_entry, lListNameToken);
393 char* dim_start = strstr(cur_entry, lListDimsToken);
394 char* dir_start = strstr(cur_entry, lListDirToken);
395 if (name_start != NULL && dim_start != NULL && dir_start != NULL) {
396 /* Advance to the token values. */
397 name_start += strlen(lListNameToken);
398 dim_start += strlen(lListDimsToken);
399 dir_start += strlen(lListDirToken);
401 /* Terminate token values with zero. */
402 char* s = strchr(name_start, ' ');
406 s = strchr(dim_start, ' ');
410 s = strchr(dir_start, ' ');
415 /* Create and initialize qemu camera. */
416 EmulatedQemuCamera* qemu_cam =
417 new EmulatedQemuCamera(index, &HAL_MODULE_INFO_SYM.common);
418 if (NULL != qemu_cam) {
419 res = qemu_cam->Initialize(name_start, dim_start, dir_start);
420 if (res == NO_ERROR) {
421 mEmulatedCameras[index] = qemu_cam;
427 ALOGE("%s: Unable to instantiate EmulatedQemuCamera",
431 ALOGW("%s: Bad camera information: %s", __FUNCTION__, cur_entry);
434 cur_entry = next_entry;
437 mEmulatedCameraNum = index;
440 bool EmulatedCameraFactory::isBackFakeCameraEmulationOn()
442 /* Defined by 'qemu.sf.fake_camera' boot property: if property exist, and
443 * is set to 'both', or 'back', then fake camera is used to emulate back
445 char prop[PROPERTY_VALUE_MAX];
446 if ((property_get("qemu.sf.fake_camera", prop, NULL) > 0) &&
447 (!strcmp(prop, "both") || !strcmp(prop, "back"))) {
454 int EmulatedCameraFactory::getBackCameraHalVersion()
456 /* Defined by 'qemu.sf.back_camera_hal_version' boot property: if the
457 * property doesn't exist, it is assumed to be 1. */
458 char prop[PROPERTY_VALUE_MAX];
459 if (property_get("qemu.sf.back_camera_hal", prop, NULL) > 0) {
460 char *prop_end = prop;
461 int val = strtol(prop, &prop_end, 10);
462 if (*prop_end == '\0') {
465 // Badly formatted property, should just be a number
466 ALOGE("qemu.sf.back_camera_hal is not a number: %s", prop);
471 bool EmulatedCameraFactory::isFrontFakeCameraEmulationOn()
473 /* Defined by 'qemu.sf.fake_camera' boot property: if property exist, and
474 * is set to 'both', or 'front', then fake camera is used to emulate front
476 char prop[PROPERTY_VALUE_MAX];
477 if ((property_get("qemu.sf.fake_camera", prop, NULL) > 0) &&
478 (!strcmp(prop, "both") || !strcmp(prop, "front"))) {
485 int EmulatedCameraFactory::getFrontCameraHalVersion()
487 /* Defined by 'qemu.sf.front_camera_hal_version' boot property: if the
488 * property doesn't exist, it is assumed to be 1. */
489 char prop[PROPERTY_VALUE_MAX];
490 if (property_get("qemu.sf.front_camera_hal", prop, NULL) > 0) {
491 char *prop_end = prop;
492 int val = strtol(prop, &prop_end, 10);
493 if (*prop_end == '\0') {
496 // Badly formatted property, should just be a number
497 ALOGE("qemu.sf.front_camera_hal is not a number: %s", prop);
502 void EmulatedCameraFactory::onStatusChanged(int cameraId, int newStatus) {
504 EmulatedBaseCamera *cam = mEmulatedCameras[cameraId];
506 ALOGE("%s: Invalid camera ID %d", __FUNCTION__, cameraId);
511 * (Order is important)
512 * Send the callback first to framework, THEN close the camera.
515 if (newStatus == cam->getHotplugStatus()) {
516 ALOGW("%s: Ignoring transition to the same status", __FUNCTION__);
520 const camera_module_callbacks_t* cb = mCallbacks;
521 if (cb != NULL && cb->camera_device_status_change != NULL) {
522 cb->camera_device_status_change(cb, cameraId, newStatus);
525 if (newStatus == CAMERA_DEVICE_STATUS_NOT_PRESENT) {
527 } else if (newStatus == CAMERA_DEVICE_STATUS_PRESENT) {
533 /********************************************************************************
534 * Initializer for the static member structure.
535 *******************************************************************************/
537 /* Entry point for camera HAL API. */
538 struct hw_module_methods_t EmulatedCameraFactory::mCameraModuleMethods = {
539 open: EmulatedCameraFactory::device_open
542 }; /* namespace android */