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     waitForQemuSfFakeCameraPropertyAvailable();
59 
60     if (isBackFakeCameraEmulationOn()) {
61         /* Camera ID. */
62         const int camera_id = mEmulatedCameraNum;
63         /* Use fake camera to emulate back-facing camera. */
64         mEmulatedCameraNum++;
65 
66         /* Make sure that array is allocated (in case there were no 'qemu'
67          * cameras created. Note that we preallocate the array so it may contain
68          * two fake cameras: one facing back, and another facing front. */
69         if (mEmulatedCameras == NULL) {
70             mEmulatedCameras = new EmulatedBaseCamera*[mEmulatedCameraNum + 1];
71             if (mEmulatedCameras == NULL) {
72                 ALOGE("%s: Unable to allocate emulated camera array for %d entries",
73                      __FUNCTION__, mEmulatedCameraNum);
74                 return;
75             }
76             memset(mEmulatedCameras, 0,
77                     (mEmulatedCameraNum + 1) * sizeof(EmulatedBaseCamera*));
78         }
79 
80         /* Create, and initialize the fake camera */
81         switch (getBackCameraHalVersion()) {
82             case 1:
83                 mEmulatedCameras[camera_id] =
84                         new EmulatedFakeCamera(camera_id, true,
85                                 &HAL_MODULE_INFO_SYM.common);
86                 break;
87             case 2:
88                 mEmulatedCameras[camera_id] =
89                         new EmulatedFakeCamera2(camera_id, true,
90                                 &HAL_MODULE_INFO_SYM.common);
91                 break;
92             case 3:
93                 mEmulatedCameras[camera_id] =
94                         new EmulatedFakeCamera3(camera_id, true,
95                                 &HAL_MODULE_INFO_SYM.common);
96                 break;
97             default:
98                 ALOGE("%s: Unknown back camera hal version requested: %d", __FUNCTION__,
99                         getBackCameraHalVersion());
100         }
101         if (mEmulatedCameras[camera_id] != NULL) {
102             ALOGV("%s: Back camera device version is %d", __FUNCTION__,
103                     getBackCameraHalVersion());
104             res = mEmulatedCameras[camera_id]->Initialize();
105             if (res != NO_ERROR) {
106                 ALOGE("%s: Unable to intialize back camera %d: %s (%d)",
107                         __FUNCTION__, camera_id, strerror(-res), res);
108                 delete mEmulatedCameras[camera_id];
109                 mEmulatedCameraNum--;
110             }
111         } else {
112             mEmulatedCameraNum--;
113             ALOGE("%s: Unable to instantiate fake camera class", __FUNCTION__);
114         }
115     }
116 
117     if (isFrontFakeCameraEmulationOn()) {
118         /* Camera ID. */
119         const int camera_id = mEmulatedCameraNum;
120         /* Use fake camera to emulate front-facing camera. */
121         mEmulatedCameraNum++;
122 
123         /* Make sure that array is allocated (in case there were no 'qemu'
124          * cameras created. */
125         if (mEmulatedCameras == NULL) {
126             mEmulatedCameras = new EmulatedBaseCamera*[mEmulatedCameraNum];
127             if (mEmulatedCameras == NULL) {
128                 ALOGE("%s: Unable to allocate emulated camera array for %d entries",
129                      __FUNCTION__, mEmulatedCameraNum);
130                 return;
131             }
132             memset(mEmulatedCameras, 0,
133                     mEmulatedCameraNum * sizeof(EmulatedBaseCamera*));
134         }
135 
136         /* Create, and initialize the fake camera */
137         switch (getFrontCameraHalVersion()) {
138             case 1:
139                 mEmulatedCameras[camera_id] =
140                         new EmulatedFakeCamera(camera_id, false,
141                                 &HAL_MODULE_INFO_SYM.common);
142                 break;
143             case 2:
144                 mEmulatedCameras[camera_id] =
145                         new EmulatedFakeCamera2(camera_id, false,
146                                 &HAL_MODULE_INFO_SYM.common);
147                 break;
148             case 3:
149                 mEmulatedCameras[camera_id] =
150                         new EmulatedFakeCamera3(camera_id, false,
151                                 &HAL_MODULE_INFO_SYM.common);
152                 break;
153             default:
154                 ALOGE("%s: Unknown front camera hal version requested: %d",
155                         __FUNCTION__,
156                         getFrontCameraHalVersion());
157         }
158         if (mEmulatedCameras[camera_id] != NULL) {
159             ALOGV("%s: Front camera device version is %d", __FUNCTION__,
160                     getFrontCameraHalVersion());
161             res = mEmulatedCameras[camera_id]->Initialize();
162             if (res != NO_ERROR) {
163                 ALOGE("%s: Unable to intialize front camera %d: %s (%d)",
164                         __FUNCTION__, camera_id, strerror(-res), res);
165                 delete mEmulatedCameras[camera_id];
166                 mEmulatedCameraNum--;
167             }
168         } else {
169             mEmulatedCameraNum--;
170             ALOGE("%s: Unable to instantiate fake camera class", __FUNCTION__);
171         }
172     }
173 
174     ALOGE("%d cameras are being emulated. %d of them are fake cameras.",
175           mEmulatedCameraNum, mFakeCameraNum);
176 
177     /* Create hotplug thread */
178     {
179         Vector<int> cameraIdVector;
180         for (int i = 0; i < mEmulatedCameraNum; ++i) {
181             cameraIdVector.push_back(i);
182         }
183         mHotplugThread = new EmulatedCameraHotplugThread(&cameraIdVector[0],
184                                                          mEmulatedCameraNum);
185         mHotplugThread->run("EmulatedCameraHotplugThread");
186     }
187 
188     mConstructedOK = true;
189 }
190 
~EmulatedCameraFactory()191 EmulatedCameraFactory::~EmulatedCameraFactory()
192 {
193     if (mEmulatedCameras != NULL) {
194         for (int n = 0; n < mEmulatedCameraNum; n++) {
195             if (mEmulatedCameras[n] != NULL) {
196                 delete mEmulatedCameras[n];
197             }
198         }
199         delete[] mEmulatedCameras;
200     }
201 
202     if (mHotplugThread != NULL) {
203         mHotplugThread->requestExit();
204         mHotplugThread->join();
205     }
206 }
207 
208 /****************************************************************************
209  * Camera HAL API handlers.
210  *
211  * Each handler simply verifies existence of an appropriate EmulatedBaseCamera
212  * instance, and dispatches the call to that instance.
213  *
214  ***************************************************************************/
215 
cameraDeviceOpen(int camera_id,hw_device_t ** device)216 int EmulatedCameraFactory::cameraDeviceOpen(int camera_id, hw_device_t** device)
217 {
218     ALOGV("%s: id = %d", __FUNCTION__, camera_id);
219 
220     *device = NULL;
221 
222     if (!isConstructedOK()) {
223         ALOGE("%s: EmulatedCameraFactory has failed to initialize", __FUNCTION__);
224         return -EINVAL;
225     }
226 
227     if (camera_id < 0 || camera_id >= getEmulatedCameraNum()) {
228         ALOGE("%s: Camera id %d is out of bounds (%d)",
229              __FUNCTION__, camera_id, getEmulatedCameraNum());
230         return -ENODEV;
231     }
232 
233     return mEmulatedCameras[camera_id]->connectCamera(device);
234 }
235 
getCameraInfo(int camera_id,struct camera_info * info)236 int EmulatedCameraFactory::getCameraInfo(int camera_id, struct camera_info* info)
237 {
238     ALOGV("%s: id = %d", __FUNCTION__, camera_id);
239 
240     if (!isConstructedOK()) {
241         ALOGE("%s: EmulatedCameraFactory has failed to initialize", __FUNCTION__);
242         return -EINVAL;
243     }
244 
245     if (camera_id < 0 || camera_id >= getEmulatedCameraNum()) {
246         ALOGE("%s: Camera id %d is out of bounds (%d)",
247              __FUNCTION__, camera_id, getEmulatedCameraNum());
248         return -ENODEV;
249     }
250 
251     return mEmulatedCameras[camera_id]->getCameraInfo(info);
252 }
253 
setCallbacks(const camera_module_callbacks_t * callbacks)254 int EmulatedCameraFactory::setCallbacks(
255         const camera_module_callbacks_t *callbacks)
256 {
257     ALOGV("%s: callbacks = %p", __FUNCTION__, callbacks);
258 
259     mCallbacks = callbacks;
260 
261     return OK;
262 }
263 
getVendorTagOps(vendor_tag_ops_t * ops)264 void EmulatedCameraFactory::getVendorTagOps(vendor_tag_ops_t* ops) {
265     ALOGV("%s: ops = %p", __FUNCTION__, ops);
266 
267     // No vendor tags defined for emulator yet, so not touching ops
268 }
269 
270 /****************************************************************************
271  * Camera HAL API callbacks.
272  ***************************************************************************/
273 
device_open(const hw_module_t * module,const char * name,hw_device_t ** device)274 int EmulatedCameraFactory::device_open(const hw_module_t* module,
275                                        const char* name,
276                                        hw_device_t** device)
277 {
278     /*
279      * Simply verify the parameters, and dispatch the call inside the
280      * EmulatedCameraFactory instance.
281      */
282 
283     if (module != &HAL_MODULE_INFO_SYM.common) {
284         ALOGE("%s: Invalid module %p expected %p",
285              __FUNCTION__, module, &HAL_MODULE_INFO_SYM.common);
286         return -EINVAL;
287     }
288     if (name == NULL) {
289         ALOGE("%s: NULL name is not expected here", __FUNCTION__);
290         return -EINVAL;
291     }
292 
293     return gEmulatedCameraFactory.cameraDeviceOpen(atoi(name), device);
294 }
295 
get_number_of_cameras(void)296 int EmulatedCameraFactory::get_number_of_cameras(void)
297 {
298     return gEmulatedCameraFactory.getEmulatedCameraNum();
299 }
300 
get_camera_info(int camera_id,struct camera_info * info)301 int EmulatedCameraFactory::get_camera_info(int camera_id,
302                                            struct camera_info* info)
303 {
304     return gEmulatedCameraFactory.getCameraInfo(camera_id, info);
305 }
306 
set_callbacks(const camera_module_callbacks_t * callbacks)307 int EmulatedCameraFactory::set_callbacks(
308         const camera_module_callbacks_t *callbacks)
309 {
310     return gEmulatedCameraFactory.setCallbacks(callbacks);
311 }
312 
get_vendor_tag_ops(vendor_tag_ops_t * ops)313 void EmulatedCameraFactory::get_vendor_tag_ops(vendor_tag_ops_t* ops)
314 {
315     gEmulatedCameraFactory.getVendorTagOps(ops);
316 }
317 
open_legacy(const struct hw_module_t * module,const char * id,uint32_t halVersion,struct hw_device_t ** device)318 int EmulatedCameraFactory::open_legacy(const struct hw_module_t* module,
319         const char* id, uint32_t halVersion, struct hw_device_t** device) {
320     // Not supporting legacy open
321     return -ENOSYS;
322 }
323 
324 /********************************************************************************
325  * Internal API
326  *******************************************************************************/
327 
328 /*
329  * Camera information tokens passed in response to the "list" factory query.
330  */
331 
332 /* Device name token. */
333 static const char lListNameToken[]    = "name=";
334 /* Frame dimensions token. */
335 static const char lListDimsToken[]    = "framedims=";
336 /* Facing direction token. */
337 static const char lListDirToken[]     = "dir=";
338 
createQemuCameras()339 void EmulatedCameraFactory::createQemuCameras()
340 {
341     /* Obtain camera list. */
342     char* camera_list = NULL;
343     status_t res = mQemuClient.listCameras(&camera_list);
344     /* Empty list, or list containing just an EOL means that there were no
345      * connected cameras found. */
346     if (res != NO_ERROR || camera_list == NULL || *camera_list == '\0' ||
347         *camera_list == '\n') {
348         if (camera_list != NULL) {
349             free(camera_list);
350         }
351         return;
352     }
353 
354     /*
355      * Calculate number of connected cameras. Number of EOLs in the camera list
356      * is the number of the connected cameras.
357      */
358 
359     int num = 0;
360     const char* eol = strchr(camera_list, '\n');
361     while (eol != NULL) {
362         num++;
363         eol = strchr(eol + 1, '\n');
364     }
365 
366     /* Allocate the array for emulated camera instances. Note that we allocate
367      * two more entries for back and front fake camera emulation. */
368     mEmulatedCameras = new EmulatedBaseCamera*[num + 2];
369     if (mEmulatedCameras == NULL) {
370         ALOGE("%s: Unable to allocate emulated camera array for %d entries",
371              __FUNCTION__, num + 1);
372         free(camera_list);
373         return;
374     }
375     memset(mEmulatedCameras, 0, sizeof(EmulatedBaseCamera*) * (num + 1));
376 
377     /*
378      * Iterate the list, creating, and initializin emulated qemu cameras for each
379      * entry (line) in the list.
380      */
381 
382     int index = 0;
383     char* cur_entry = camera_list;
384     while (cur_entry != NULL && *cur_entry != '\0' && index < num) {
385         /* Find the end of the current camera entry, and terminate it with zero
386          * for simpler string manipulation. */
387         char* next_entry = strchr(cur_entry, '\n');
388         if (next_entry != NULL) {
389             *next_entry = '\0';
390             next_entry++;   // Start of the next entry.
391         }
392 
393         /* Find 'name', 'framedims', and 'dir' tokens that are required here. */
394         char* name_start = strstr(cur_entry, lListNameToken);
395         char* dim_start = strstr(cur_entry, lListDimsToken);
396         char* dir_start = strstr(cur_entry, lListDirToken);
397         if (name_start != NULL && dim_start != NULL && dir_start != NULL) {
398             /* Advance to the token values. */
399             name_start += strlen(lListNameToken);
400             dim_start += strlen(lListDimsToken);
401             dir_start += strlen(lListDirToken);
402 
403             /* Terminate token values with zero. */
404             char* s = strchr(name_start, ' ');
405             if (s != NULL) {
406                 *s = '\0';
407             }
408             s = strchr(dim_start, ' ');
409             if (s != NULL) {
410                 *s = '\0';
411             }
412             s = strchr(dir_start, ' ');
413             if (s != NULL) {
414                 *s = '\0';
415             }
416 
417             /* Create and initialize qemu camera. */
418             EmulatedQemuCamera* qemu_cam =
419                 new EmulatedQemuCamera(index, &HAL_MODULE_INFO_SYM.common);
420             if (NULL != qemu_cam) {
421                 res = qemu_cam->Initialize(name_start, dim_start, dir_start);
422                 if (res == NO_ERROR) {
423                     mEmulatedCameras[index] = qemu_cam;
424                     index++;
425                 } else {
426                     delete qemu_cam;
427                 }
428             } else {
429                 ALOGE("%s: Unable to instantiate EmulatedQemuCamera",
430                      __FUNCTION__);
431             }
432         } else {
433             ALOGW("%s: Bad camera information: %s", __FUNCTION__, cur_entry);
434         }
435 
436         cur_entry = next_entry;
437     }
438 
439     mEmulatedCameraNum = index;
440 }
441 
waitForQemuSfFakeCameraPropertyAvailable()442 void EmulatedCameraFactory::waitForQemuSfFakeCameraPropertyAvailable() {
443     // Camera service may start running before qemu-props sets qemu.sf.fake_camera to
444     // any of the follwing four values: "none,front,back,both"; so we need to wait.
445     // android/camera/camera-service.c
446     // bug: 30768229
447     int numAttempts = 100;
448     char prop[PROPERTY_VALUE_MAX];
449     bool timeout = true;
450     for (int i = 0; i < numAttempts; ++i) {
451         if (property_get("qemu.sf.fake_camera", prop, NULL) != 0 ) {
452             timeout = false;
453             break;
454         }
455         usleep(5000);
456     }
457     if (timeout) {
458         ALOGE("timeout (%dms) waiting for property qemu.sf.fake_camera to be set\n", 5 * numAttempts);
459     }
460 }
461 
isBackFakeCameraEmulationOn()462 bool EmulatedCameraFactory::isBackFakeCameraEmulationOn()
463 {
464     /* Defined by 'qemu.sf.fake_camera' boot property: if property exist, and
465      * is set to 'both', or 'back', then fake camera is used to emulate back
466      * camera. */
467     char prop[PROPERTY_VALUE_MAX];
468     if ((property_get("qemu.sf.fake_camera", prop, NULL) > 0) &&
469         (!strcmp(prop, "both") || !strcmp(prop, "back"))) {
470         return true;
471     } else {
472         return false;
473     }
474 }
475 
getBackCameraHalVersion()476 int EmulatedCameraFactory::getBackCameraHalVersion()
477 {
478     /* Defined by 'qemu.sf.back_camera_hal_version' boot property: if the
479      * property doesn't exist, it is assumed to be 1. */
480     char prop[PROPERTY_VALUE_MAX];
481     if (property_get("qemu.sf.back_camera_hal", prop, NULL) > 0) {
482         char *prop_end = prop;
483         int val = strtol(prop, &prop_end, 10);
484         if (*prop_end == '\0') {
485             return val;
486         }
487         // Badly formatted property, should just be a number
488         ALOGE("qemu.sf.back_camera_hal is not a number: %s", prop);
489     }
490     return 1;
491 }
492 
isFrontFakeCameraEmulationOn()493 bool EmulatedCameraFactory::isFrontFakeCameraEmulationOn()
494 {
495     /* Defined by 'qemu.sf.fake_camera' boot property: if property exist, and
496      * is set to 'both', or 'front', then fake camera is used to emulate front
497      * camera. */
498     char prop[PROPERTY_VALUE_MAX];
499     if ((property_get("qemu.sf.fake_camera", prop, NULL) > 0) &&
500         (!strcmp(prop, "both") || !strcmp(prop, "front"))) {
501         return true;
502     } else {
503         return false;
504     }
505 }
506 
getFrontCameraHalVersion()507 int EmulatedCameraFactory::getFrontCameraHalVersion()
508 {
509     /* Defined by 'qemu.sf.front_camera_hal_version' boot property: if the
510      * property doesn't exist, it is assumed to be 1. */
511     char prop[PROPERTY_VALUE_MAX];
512     if (property_get("qemu.sf.front_camera_hal", prop, NULL) > 0) {
513         char *prop_end = prop;
514         int val = strtol(prop, &prop_end, 10);
515         if (*prop_end == '\0') {
516             return val;
517         }
518         // Badly formatted property, should just be a number
519         ALOGE("qemu.sf.front_camera_hal is not a number: %s", prop);
520     }
521     return 1;
522 }
523 
onStatusChanged(int cameraId,int newStatus)524 void EmulatedCameraFactory::onStatusChanged(int cameraId, int newStatus) {
525 
526     EmulatedBaseCamera *cam = mEmulatedCameras[cameraId];
527     if (!cam) {
528         ALOGE("%s: Invalid camera ID %d", __FUNCTION__, cameraId);
529         return;
530     }
531 
532     /**
533      * (Order is important)
534      * Send the callback first to framework, THEN close the camera.
535      */
536 
537     if (newStatus == cam->getHotplugStatus()) {
538         ALOGW("%s: Ignoring transition to the same status", __FUNCTION__);
539         return;
540     }
541 
542     const camera_module_callbacks_t* cb = mCallbacks;
543     if (cb != NULL && cb->camera_device_status_change != NULL) {
544         cb->camera_device_status_change(cb, cameraId, newStatus);
545     }
546 
547     if (newStatus == CAMERA_DEVICE_STATUS_NOT_PRESENT) {
548         cam->unplugCamera();
549     } else if (newStatus == CAMERA_DEVICE_STATUS_PRESENT) {
550         cam->plugCamera();
551     }
552 
553 }
554 
555 /********************************************************************************
556  * Initializer for the static member structure.
557  *******************************************************************************/
558 
559 /* Entry point for camera HAL API. */
560 struct hw_module_methods_t EmulatedCameraFactory::mCameraModuleMethods = {
561     open: EmulatedCameraFactory::device_open
562 };
563 
564 }; /* namespace android */
565