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();
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 
262 /****************************************************************************
263  * Camera HAL API callbacks.
264  ***************************************************************************/
265 
device_open(const hw_module_t * module,const char * name,hw_device_t ** device)266 int EmulatedCameraFactory::device_open(const hw_module_t* module,
267                                        const char* name,
268                                        hw_device_t** device)
269 {
270     /*
271      * Simply verify the parameters, and dispatch the call inside the
272      * EmulatedCameraFactory instance.
273      */
274 
275     if (module != &HAL_MODULE_INFO_SYM.common) {
276         ALOGE("%s: Invalid module %p expected %p",
277              __FUNCTION__, module, &HAL_MODULE_INFO_SYM.common);
278         return -EINVAL;
279     }
280     if (name == NULL) {
281         ALOGE("%s: NULL name is not expected here", __FUNCTION__);
282         return -EINVAL;
283     }
284 
285     return gEmulatedCameraFactory.cameraDeviceOpen(atoi(name), device);
286 }
287 
get_number_of_cameras(void)288 int EmulatedCameraFactory::get_number_of_cameras(void)
289 {
290     return gEmulatedCameraFactory.getEmulatedCameraNum();
291 }
292 
get_camera_info(int camera_id,struct camera_info * info)293 int EmulatedCameraFactory::get_camera_info(int camera_id,
294                                            struct camera_info* info)
295 {
296     return gEmulatedCameraFactory.getCameraInfo(camera_id, info);
297 }
298 
set_callbacks(const camera_module_callbacks_t * callbacks)299 int EmulatedCameraFactory::set_callbacks(
300         const camera_module_callbacks_t *callbacks)
301 {
302     return gEmulatedCameraFactory.setCallbacks(callbacks);
303 }
304 
305 /********************************************************************************
306  * Internal API
307  *******************************************************************************/
308 
309 /*
310  * Camera information tokens passed in response to the "list" factory query.
311  */
312 
313 /* Device name token. */
314 static const char lListNameToken[]    = "name=";
315 /* Frame dimensions token. */
316 static const char lListDimsToken[]    = "framedims=";
317 /* Facing direction token. */
318 static const char lListDirToken[]     = "dir=";
319 
createQemuCameras()320 void EmulatedCameraFactory::createQemuCameras()
321 {
322     /* Obtain camera list. */
323     char* camera_list = NULL;
324     status_t res = mQemuClient.listCameras(&camera_list);
325     /* Empty list, or list containing just an EOL means that there were no
326      * connected cameras found. */
327     if (res != NO_ERROR || camera_list == NULL || *camera_list == '\0' ||
328         *camera_list == '\n') {
329         if (camera_list != NULL) {
330             free(camera_list);
331         }
332         return;
333     }
334 
335     /*
336      * Calculate number of connected cameras. Number of EOLs in the camera list
337      * is the number of the connected cameras.
338      */
339 
340     int num = 0;
341     const char* eol = strchr(camera_list, '\n');
342     while (eol != NULL) {
343         num++;
344         eol = strchr(eol + 1, '\n');
345     }
346 
347     /* Allocate the array for emulated camera instances. Note that we allocate
348      * two more entries for back and front fake camera emulation. */
349     mEmulatedCameras = new EmulatedBaseCamera*[num + 2];
350     if (mEmulatedCameras == NULL) {
351         ALOGE("%s: Unable to allocate emulated camera array for %d entries",
352              __FUNCTION__, num + 1);
353         free(camera_list);
354         return;
355     }
356     memset(mEmulatedCameras, 0, sizeof(EmulatedBaseCamera*) * (num + 1));
357 
358     /*
359      * Iterate the list, creating, and initializin emulated qemu cameras for each
360      * entry (line) in the list.
361      */
362 
363     int index = 0;
364     char* cur_entry = camera_list;
365     while (cur_entry != NULL && *cur_entry != '\0' && index < num) {
366         /* Find the end of the current camera entry, and terminate it with zero
367          * for simpler string manipulation. */
368         char* next_entry = strchr(cur_entry, '\n');
369         if (next_entry != NULL) {
370             *next_entry = '\0';
371             next_entry++;   // Start of the next entry.
372         }
373 
374         /* Find 'name', 'framedims', and 'dir' tokens that are required here. */
375         char* name_start = strstr(cur_entry, lListNameToken);
376         char* dim_start = strstr(cur_entry, lListDimsToken);
377         char* dir_start = strstr(cur_entry, lListDirToken);
378         if (name_start != NULL && dim_start != NULL && dir_start != NULL) {
379             /* Advance to the token values. */
380             name_start += strlen(lListNameToken);
381             dim_start += strlen(lListDimsToken);
382             dir_start += strlen(lListDirToken);
383 
384             /* Terminate token values with zero. */
385             char* s = strchr(name_start, ' ');
386             if (s != NULL) {
387                 *s = '\0';
388             }
389             s = strchr(dim_start, ' ');
390             if (s != NULL) {
391                 *s = '\0';
392             }
393             s = strchr(dir_start, ' ');
394             if (s != NULL) {
395                 *s = '\0';
396             }
397 
398             /* Create and initialize qemu camera. */
399             EmulatedQemuCamera* qemu_cam =
400                 new EmulatedQemuCamera(index, &HAL_MODULE_INFO_SYM.common);
401             if (NULL != qemu_cam) {
402                 res = qemu_cam->Initialize(name_start, dim_start, dir_start);
403                 if (res == NO_ERROR) {
404                     mEmulatedCameras[index] = qemu_cam;
405                     index++;
406                 } else {
407                     delete qemu_cam;
408                 }
409             } else {
410                 ALOGE("%s: Unable to instantiate EmulatedQemuCamera",
411                      __FUNCTION__);
412             }
413         } else {
414             ALOGW("%s: Bad camera information: %s", __FUNCTION__, cur_entry);
415         }
416 
417         cur_entry = next_entry;
418     }
419 
420     mEmulatedCameraNum = index;
421 }
422 
isBackFakeCameraEmulationOn()423 bool EmulatedCameraFactory::isBackFakeCameraEmulationOn()
424 {
425     /* Defined by 'qemu.sf.fake_camera' boot property: if property exist, and
426      * is set to 'both', or 'back', then fake camera is used to emulate back
427      * camera. */
428     char prop[PROPERTY_VALUE_MAX];
429     if ((property_get("qemu.sf.fake_camera", prop, NULL) > 0) &&
430         (!strcmp(prop, "both") || !strcmp(prop, "back"))) {
431         return true;
432     } else {
433         return false;
434     }
435 }
436 
getBackCameraHalVersion()437 int EmulatedCameraFactory::getBackCameraHalVersion()
438 {
439     /* Defined by 'qemu.sf.back_camera_hal_version' boot property: if the
440      * property doesn't exist, it is assumed to be 1. */
441     char prop[PROPERTY_VALUE_MAX];
442     if (property_get("qemu.sf.back_camera_hal", prop, NULL) > 0) {
443         char *prop_end = prop;
444         int val = strtol(prop, &prop_end, 10);
445         if (*prop_end == '\0') {
446             return val;
447         }
448         // Badly formatted property, should just be a number
449         ALOGE("qemu.sf.back_camera_hal is not a number: %s", prop);
450     }
451     return 1;
452 }
453 
isFrontFakeCameraEmulationOn()454 bool EmulatedCameraFactory::isFrontFakeCameraEmulationOn()
455 {
456     /* Defined by 'qemu.sf.fake_camera' boot property: if property exist, and
457      * is set to 'both', or 'front', then fake camera is used to emulate front
458      * camera. */
459     char prop[PROPERTY_VALUE_MAX];
460     if ((property_get("qemu.sf.fake_camera", prop, NULL) > 0) &&
461         (!strcmp(prop, "both") || !strcmp(prop, "front"))) {
462         return true;
463     } else {
464         return false;
465     }
466 }
467 
getFrontCameraHalVersion()468 int EmulatedCameraFactory::getFrontCameraHalVersion()
469 {
470     /* Defined by 'qemu.sf.front_camera_hal_version' boot property: if the
471      * property doesn't exist, it is assumed to be 1. */
472     char prop[PROPERTY_VALUE_MAX];
473     if (property_get("qemu.sf.front_camera_hal", prop, NULL) > 0) {
474         char *prop_end = prop;
475         int val = strtol(prop, &prop_end, 10);
476         if (*prop_end == '\0') {
477             return val;
478         }
479         // Badly formatted property, should just be a number
480         ALOGE("qemu.sf.front_camera_hal is not a number: %s", prop);
481     }
482     return 1;
483 }
484 
onStatusChanged(int cameraId,int newStatus)485 void EmulatedCameraFactory::onStatusChanged(int cameraId, int newStatus) {
486 
487     EmulatedBaseCamera *cam = mEmulatedCameras[cameraId];
488     if (!cam) {
489         ALOGE("%s: Invalid camera ID %d", __FUNCTION__, cameraId);
490         return;
491     }
492 
493     /**
494      * (Order is important)
495      * Send the callback first to framework, THEN close the camera.
496      */
497 
498     if (newStatus == cam->getHotplugStatus()) {
499         ALOGW("%s: Ignoring transition to the same status", __FUNCTION__);
500         return;
501     }
502 
503     const camera_module_callbacks_t* cb = mCallbacks;
504     if (cb != NULL && cb->camera_device_status_change != NULL) {
505         cb->camera_device_status_change(cb, cameraId, newStatus);
506     }
507 
508     if (newStatus == CAMERA_DEVICE_STATUS_NOT_PRESENT) {
509         cam->unplugCamera();
510     } else if (newStatus == CAMERA_DEVICE_STATUS_PRESENT) {
511         cam->plugCamera();
512     }
513 
514 }
515 
516 /********************************************************************************
517  * Initializer for the static member structure.
518  *******************************************************************************/
519 
520 /* Entry point for camera HAL API. */
521 struct hw_module_methods_t EmulatedCameraFactory::mCameraModuleMethods = {
522     open: EmulatedCameraFactory::device_open
523 };
524 
525 }; /* namespace android */
526