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 
EmulatedCameraFactory()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     if (isBackFakeCameraEmulationOn()) {
59         /* Camera ID. */
60         const int camera_id = mEmulatedCameraNum;
61         /* Use fake camera to emulate back-facing camera. */
62         mEmulatedCameraNum++;
63 
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);
72                 return;
73             }
74             memset(mEmulatedCameras, 0,
75                     (mEmulatedCameraNum + 1) * sizeof(EmulatedBaseCamera*));
76         }
77 
78         /* Create, and initialize the fake camera */
79         switch (getBackCameraHalVersion()) {
80             case 1:
81                 mEmulatedCameras[camera_id] =
82                         new EmulatedFakeCamera(camera_id, true,
83                                 &HAL_MODULE_INFO_SYM.common);
84                 break;
85             case 2:
86                 mEmulatedCameras[camera_id] =
87                         new EmulatedFakeCamera2(camera_id, true,
88                                 &HAL_MODULE_INFO_SYM.common);
89                 break;
90             case 3:
91                 mEmulatedCameras[camera_id] =
92                         new EmulatedFakeCamera3(camera_id, true,
93                                 &HAL_MODULE_INFO_SYM.common);
94                 break;
95             default:
96                 ALOGE("%s: Unknown back camera hal version requested: %d", __FUNCTION__,
97                         getBackCameraHalVersion());
98         }
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--;
108             }
109         } else {
110             mEmulatedCameraNum--;
111             ALOGE("%s: Unable to instantiate fake camera class", __FUNCTION__);
112         }
113     }
114 
115     if (isFrontFakeCameraEmulationOn()) {
116         /* Camera ID. */
117         const int camera_id = mEmulatedCameraNum;
118         /* Use fake camera to emulate front-facing camera. */
119         mEmulatedCameraNum++;
120 
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);
128                 return;
129             }
130             memset(mEmulatedCameras, 0,
131                     mEmulatedCameraNum * sizeof(EmulatedBaseCamera*));
132         }
133 
134         /* Create, and initialize the fake camera */
135         switch (getFrontCameraHalVersion()) {
136             case 1:
137                 mEmulatedCameras[camera_id] =
138                         new EmulatedFakeCamera(camera_id, false,
139                                 &HAL_MODULE_INFO_SYM.common);
140                 break;
141             case 2:
142                 mEmulatedCameras[camera_id] =
143                         new EmulatedFakeCamera2(camera_id, false,
144                                 &HAL_MODULE_INFO_SYM.common);
145                 break;
146             case 3:
147                 mEmulatedCameras[camera_id] =
148                         new EmulatedFakeCamera3(camera_id, false,
149                                 &HAL_MODULE_INFO_SYM.common);
150                 break;
151             default:
152                 ALOGE("%s: Unknown front camera hal version requested: %d",
153                         __FUNCTION__,
154                         getFrontCameraHalVersion());
155         }
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--;
165             }
166         } else {
167             mEmulatedCameraNum--;
168             ALOGE("%s: Unable to instantiate fake camera class", __FUNCTION__);
169         }
170     }
171 
172     ALOGV("%d cameras are being emulated. %d of them are fake cameras.",
173           mEmulatedCameraNum, mFakeCameraNum);
174 
175     /* Create hotplug thread */
176     {
177         Vector<int> cameraIdVector;
178         for (int i = 0; i < mEmulatedCameraNum; ++i) {
179             cameraIdVector.push_back(i);
180         }
181         mHotplugThread = new EmulatedCameraHotplugThread(&cameraIdVector[0],
182                                                          mEmulatedCameraNum);
183         mHotplugThread->run("EmulatedCameraHotplugThread");
184     }
185 
186     mConstructedOK = true;
187 }
188 
~EmulatedCameraFactory()189 EmulatedCameraFactory::~EmulatedCameraFactory()
190 {
191     if (mEmulatedCameras != NULL) {
192         for (int n = 0; n < mEmulatedCameraNum; n++) {
193             if (mEmulatedCameras[n] != NULL) {
194                 delete mEmulatedCameras[n];
195             }
196         }
197         delete[] mEmulatedCameras;
198     }
199 
200     if (mHotplugThread != NULL) {
201         mHotplugThread->requestExit();
202         mHotplugThread->join();
203     }
204 }
205 
206 /****************************************************************************
207  * Camera HAL API handlers.
208  *
209  * Each handler simply verifies existence of an appropriate EmulatedBaseCamera
210  * instance, and dispatches the call to that instance.
211  *
212  ***************************************************************************/
213 
cameraDeviceOpen(int camera_id,hw_device_t ** device)214 int EmulatedCameraFactory::cameraDeviceOpen(int camera_id, hw_device_t** device)
215 {
216     ALOGV("%s: id = %d", __FUNCTION__, camera_id);
217 
218     *device = NULL;
219 
220     if (!isConstructedOK()) {
221         ALOGE("%s: EmulatedCameraFactory has failed to initialize", __FUNCTION__);
222         return -EINVAL;
223     }
224 
225     if (camera_id < 0 || camera_id >= getEmulatedCameraNum()) {
226         ALOGE("%s: Camera id %d is out of bounds (%d)",
227              __FUNCTION__, camera_id, getEmulatedCameraNum());
228         return -ENODEV;
229     }
230 
231     return mEmulatedCameras[camera_id]->connectCamera(device);
232 }
233 
getCameraInfo(int camera_id,struct camera_info * info)234 int EmulatedCameraFactory::getCameraInfo(int camera_id, struct camera_info* info)
235 {
236     ALOGV("%s: id = %d", __FUNCTION__, camera_id);
237 
238     if (!isConstructedOK()) {
239         ALOGE("%s: EmulatedCameraFactory has failed to initialize", __FUNCTION__);
240         return -EINVAL;
241     }
242 
243     if (camera_id < 0 || camera_id >= getEmulatedCameraNum()) {
244         ALOGE("%s: Camera id %d is out of bounds (%d)",
245              __FUNCTION__, camera_id, getEmulatedCameraNum());
246         return -ENODEV;
247     }
248 
249     return mEmulatedCameras[camera_id]->getCameraInfo(info);
250 }
251 
setCallbacks(const camera_module_callbacks_t * callbacks)252 int EmulatedCameraFactory::setCallbacks(
253         const camera_module_callbacks_t *callbacks)
254 {
255     ALOGV("%s: callbacks = %p", __FUNCTION__, callbacks);
256 
257     mCallbacks = callbacks;
258 
259     return OK;
260 }
261 
getVendorTagOps(vendor_tag_ops_t * ops)262 void EmulatedCameraFactory::getVendorTagOps(vendor_tag_ops_t* ops) {
263     ALOGV("%s: ops = %p", __FUNCTION__, ops);
264 
265     // No vendor tags defined for emulator yet, so not touching ops
266 }
267 
268 /****************************************************************************
269  * Camera HAL API callbacks.
270  ***************************************************************************/
271 
device_open(const hw_module_t * module,const char * name,hw_device_t ** device)272 int EmulatedCameraFactory::device_open(const hw_module_t* module,
273                                        const char* name,
274                                        hw_device_t** device)
275 {
276     /*
277      * Simply verify the parameters, and dispatch the call inside the
278      * EmulatedCameraFactory instance.
279      */
280 
281     if (module != &HAL_MODULE_INFO_SYM.common) {
282         ALOGE("%s: Invalid module %p expected %p",
283              __FUNCTION__, module, &HAL_MODULE_INFO_SYM.common);
284         return -EINVAL;
285     }
286     if (name == NULL) {
287         ALOGE("%s: NULL name is not expected here", __FUNCTION__);
288         return -EINVAL;
289     }
290 
291     return gEmulatedCameraFactory.cameraDeviceOpen(atoi(name), device);
292 }
293 
get_number_of_cameras(void)294 int EmulatedCameraFactory::get_number_of_cameras(void)
295 {
296     return gEmulatedCameraFactory.getEmulatedCameraNum();
297 }
298 
get_camera_info(int camera_id,struct camera_info * info)299 int EmulatedCameraFactory::get_camera_info(int camera_id,
300                                            struct camera_info* info)
301 {
302     return gEmulatedCameraFactory.getCameraInfo(camera_id, info);
303 }
304 
set_callbacks(const camera_module_callbacks_t * callbacks)305 int EmulatedCameraFactory::set_callbacks(
306         const camera_module_callbacks_t *callbacks)
307 {
308     return gEmulatedCameraFactory.setCallbacks(callbacks);
309 }
310 
get_vendor_tag_ops(vendor_tag_ops_t * ops)311 void EmulatedCameraFactory::get_vendor_tag_ops(vendor_tag_ops_t* ops)
312 {
313     gEmulatedCameraFactory.getVendorTagOps(ops);
314 }
315 
open_legacy(const struct hw_module_t * module,const char * id,uint32_t halVersion,struct hw_device_t ** device)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
319     return -ENOSYS;
320 }
321 
322 /********************************************************************************
323  * Internal API
324  *******************************************************************************/
325 
326 /*
327  * Camera information tokens passed in response to the "list" factory query.
328  */
329 
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=";
336 
createQemuCameras()337 void EmulatedCameraFactory::createQemuCameras()
338 {
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) {
347             free(camera_list);
348         }
349         return;
350     }
351 
352     /*
353      * Calculate number of connected cameras. Number of EOLs in the camera list
354      * is the number of the connected cameras.
355      */
356 
357     int num = 0;
358     const char* eol = strchr(camera_list, '\n');
359     while (eol != NULL) {
360         num++;
361         eol = strchr(eol + 1, '\n');
362     }
363 
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);
370         free(camera_list);
371         return;
372     }
373     memset(mEmulatedCameras, 0, sizeof(EmulatedBaseCamera*) * (num + 1));
374 
375     /*
376      * Iterate the list, creating, and initializin emulated qemu cameras for each
377      * entry (line) in the list.
378      */
379 
380     int index = 0;
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) {
387             *next_entry = '\0';
388             next_entry++;   // Start of the next entry.
389         }
390 
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);
400 
401             /* Terminate token values with zero. */
402             char* s = strchr(name_start, ' ');
403             if (s != NULL) {
404                 *s = '\0';
405             }
406             s = strchr(dim_start, ' ');
407             if (s != NULL) {
408                 *s = '\0';
409             }
410             s = strchr(dir_start, ' ');
411             if (s != NULL) {
412                 *s = '\0';
413             }
414 
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;
422                     index++;
423                 } else {
424                     delete qemu_cam;
425                 }
426             } else {
427                 ALOGE("%s: Unable to instantiate EmulatedQemuCamera",
428                      __FUNCTION__);
429             }
430         } else {
431             ALOGW("%s: Bad camera information: %s", __FUNCTION__, cur_entry);
432         }
433 
434         cur_entry = next_entry;
435     }
436 
437     mEmulatedCameraNum = index;
438 }
439 
isBackFakeCameraEmulationOn()440 bool EmulatedCameraFactory::isBackFakeCameraEmulationOn()
441 {
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
444      * camera. */
445     char prop[PROPERTY_VALUE_MAX];
446     if ((property_get("qemu.sf.fake_camera", prop, NULL) > 0) &&
447         (!strcmp(prop, "both") || !strcmp(prop, "back"))) {
448         return true;
449     } else {
450         return false;
451     }
452 }
453 
getBackCameraHalVersion()454 int EmulatedCameraFactory::getBackCameraHalVersion()
455 {
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') {
463             return val;
464         }
465         // Badly formatted property, should just be a number
466         ALOGE("qemu.sf.back_camera_hal is not a number: %s", prop);
467     }
468     return 1;
469 }
470 
isFrontFakeCameraEmulationOn()471 bool EmulatedCameraFactory::isFrontFakeCameraEmulationOn()
472 {
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
475      * camera. */
476     char prop[PROPERTY_VALUE_MAX];
477     if ((property_get("qemu.sf.fake_camera", prop, NULL) > 0) &&
478         (!strcmp(prop, "both") || !strcmp(prop, "front"))) {
479         return true;
480     } else {
481         return false;
482     }
483 }
484 
getFrontCameraHalVersion()485 int EmulatedCameraFactory::getFrontCameraHalVersion()
486 {
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') {
494             return val;
495         }
496         // Badly formatted property, should just be a number
497         ALOGE("qemu.sf.front_camera_hal is not a number: %s", prop);
498     }
499     return 1;
500 }
501 
onStatusChanged(int cameraId,int newStatus)502 void EmulatedCameraFactory::onStatusChanged(int cameraId, int newStatus) {
503 
504     EmulatedBaseCamera *cam = mEmulatedCameras[cameraId];
505     if (!cam) {
506         ALOGE("%s: Invalid camera ID %d", __FUNCTION__, cameraId);
507         return;
508     }
509 
510     /**
511      * (Order is important)
512      * Send the callback first to framework, THEN close the camera.
513      */
514 
515     if (newStatus == cam->getHotplugStatus()) {
516         ALOGW("%s: Ignoring transition to the same status", __FUNCTION__);
517         return;
518     }
519 
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);
523     }
524 
525     if (newStatus == CAMERA_DEVICE_STATUS_NOT_PRESENT) {
526         cam->unplugCamera();
527     } else if (newStatus == CAMERA_DEVICE_STATUS_PRESENT) {
528         cam->plugCamera();
529     }
530 
531 }
532 
533 /********************************************************************************
534  * Initializer for the static member structure.
535  *******************************************************************************/
536 
537 /* Entry point for camera HAL API. */
538 struct hw_module_methods_t EmulatedCameraFactory::mCameraModuleMethods = {
539     open: EmulatedCameraFactory::device_open
540 };
541 
542 }; /* namespace android */
543