• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "EmulatedCameraFactory.h"
30 
31 extern camera_module_t HAL_MODULE_INFO_SYM;
32 
33 /* A global instance of EmulatedCameraFactory is statically instantiated and
34  * initialized when camera emulation HAL is loaded.
35  */
36 android::EmulatedCameraFactory  gEmulatedCameraFactory;
37 
38 namespace android {
39 
EmulatedCameraFactory()40 EmulatedCameraFactory::EmulatedCameraFactory()
41         : mQemuClient(),
42           mEmulatedCameras(NULL),
43           mEmulatedCameraNum(0),
44           mFakeCameraNum(0),
45           mConstructedOK(false)
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 (isBackFakeCameraEmulationOn()) {
55         /* Camera ID. */
56         const int camera_id = mEmulatedCameraNum;
57         /* Use fake camera to emulate back-facing camera. */
58         mEmulatedCameraNum++;
59 
60         /* Make sure that array is allocated (in case there were no 'qemu'
61          * cameras created. Note that we preallocate the array so it may contain
62          * two fake cameras: one facing back, and another facing front. */
63         if (mEmulatedCameras == NULL) {
64             mEmulatedCameras = new EmulatedBaseCamera*[mEmulatedCameraNum + 1];
65             if (mEmulatedCameras == NULL) {
66                 ALOGE("%s: Unable to allocate emulated camera array for %d entries",
67                      __FUNCTION__, mEmulatedCameraNum);
68                 return;
69             }
70             memset(mEmulatedCameras, 0,
71                     (mEmulatedCameraNum + 1) * sizeof(EmulatedBaseCamera*));
72         }
73 
74         /* Create, and initialize the fake camera */
75         switch (getBackCameraHalVersion()) {
76             case 1:
77                 mEmulatedCameras[camera_id] =
78                         new EmulatedFakeCamera(camera_id, false, &HAL_MODULE_INFO_SYM.common);
79                 break;
80             case 2:
81                 mEmulatedCameras[camera_id] =
82                         new EmulatedFakeCamera2(camera_id, false, &HAL_MODULE_INFO_SYM.common);
83                 break;
84             default:
85                 ALOGE("%s: Unknown back camera hal version requested: %d", __FUNCTION__,
86                         getBackCameraHalVersion());
87         }
88         if (mEmulatedCameras[camera_id] != NULL) {
89             ALOGV("%s: Back camera device version is %d", __FUNCTION__,
90                     getBackCameraHalVersion());
91             if (mEmulatedCameras[camera_id]->Initialize() != NO_ERROR) {
92                 delete mEmulatedCameras[camera_id];
93                 mEmulatedCameras--;
94             }
95         } else {
96             mEmulatedCameras--;
97             ALOGE("%s: Unable to instantiate fake camera class", __FUNCTION__);
98         }
99     }
100 
101     if (isFrontFakeCameraEmulationOn()) {
102         /* Camera ID. */
103         const int camera_id = mEmulatedCameraNum;
104         /* Use fake camera to emulate front-facing camera. */
105         mEmulatedCameraNum++;
106 
107         /* Make sure that array is allocated (in case there were no 'qemu'
108          * cameras created. */
109         if (mEmulatedCameras == NULL) {
110             mEmulatedCameras = new EmulatedBaseCamera*[mEmulatedCameraNum];
111             if (mEmulatedCameras == NULL) {
112                 ALOGE("%s: Unable to allocate emulated camera array for %d entries",
113                      __FUNCTION__, mEmulatedCameraNum);
114                 return;
115             }
116             memset(mEmulatedCameras, 0,
117                     mEmulatedCameraNum * sizeof(EmulatedBaseCamera*));
118         }
119 
120         /* Create, and initialize the fake camera */
121         switch (getFrontCameraHalVersion()) {
122             case 1:
123                 mEmulatedCameras[camera_id] =
124                         new EmulatedFakeCamera(camera_id, false, &HAL_MODULE_INFO_SYM.common);
125                 break;
126             case 2:
127                 mEmulatedCameras[camera_id] =
128                         new EmulatedFakeCamera2(camera_id, false, &HAL_MODULE_INFO_SYM.common);
129                 break;
130             default:
131                 ALOGE("%s: Unknown front camera hal version requested: %d", __FUNCTION__,
132                         getFrontCameraHalVersion());
133         }
134         if (mEmulatedCameras[camera_id] != NULL) {
135             ALOGV("%s: Front camera device version is %d", __FUNCTION__,
136                     getFrontCameraHalVersion());
137             if (mEmulatedCameras[camera_id]->Initialize() != NO_ERROR) {
138                 delete mEmulatedCameras[camera_id];
139                 mEmulatedCameras--;
140             }
141         } else {
142             mEmulatedCameras--;
143             ALOGE("%s: Unable to instantiate fake camera class", __FUNCTION__);
144         }
145     }
146 
147     ALOGV("%d cameras are being emulated. %d of them are fake cameras.",
148           mEmulatedCameraNum, mFakeCameraNum);
149 
150     mConstructedOK = true;
151 }
152 
~EmulatedCameraFactory()153 EmulatedCameraFactory::~EmulatedCameraFactory()
154 {
155     if (mEmulatedCameras != NULL) {
156         for (int n = 0; n < mEmulatedCameraNum; n++) {
157             if (mEmulatedCameras[n] != NULL) {
158                 delete mEmulatedCameras[n];
159             }
160         }
161         delete[] mEmulatedCameras;
162     }
163 }
164 
165 /****************************************************************************
166  * Camera HAL API handlers.
167  *
168  * Each handler simply verifies existence of an appropriate EmulatedBaseCamera
169  * instance, and dispatches the call to that instance.
170  *
171  ***************************************************************************/
172 
cameraDeviceOpen(int camera_id,hw_device_t ** device)173 int EmulatedCameraFactory::cameraDeviceOpen(int camera_id, hw_device_t** device)
174 {
175     ALOGV("%s: id = %d", __FUNCTION__, camera_id);
176 
177     *device = NULL;
178 
179     if (!isConstructedOK()) {
180         ALOGE("%s: EmulatedCameraFactory has failed to initialize", __FUNCTION__);
181         return -EINVAL;
182     }
183 
184     if (camera_id < 0 || camera_id >= getEmulatedCameraNum()) {
185         ALOGE("%s: Camera id %d is out of bounds (%d)",
186              __FUNCTION__, camera_id, getEmulatedCameraNum());
187         return -EINVAL;
188     }
189 
190     return mEmulatedCameras[camera_id]->connectCamera(device);
191 }
192 
getCameraInfo(int camera_id,struct camera_info * info)193 int EmulatedCameraFactory::getCameraInfo(int camera_id, struct camera_info* info)
194 {
195     ALOGV("%s: id = %d", __FUNCTION__, camera_id);
196 
197     if (!isConstructedOK()) {
198         ALOGE("%s: EmulatedCameraFactory has failed to initialize", __FUNCTION__);
199         return -EINVAL;
200     }
201 
202     if (camera_id < 0 || camera_id >= getEmulatedCameraNum()) {
203         ALOGE("%s: Camera id %d is out of bounds (%d)",
204              __FUNCTION__, camera_id, getEmulatedCameraNum());
205         return -EINVAL;
206     }
207 
208     return mEmulatedCameras[camera_id]->getCameraInfo(info);
209 }
210 
211 /****************************************************************************
212  * Camera HAL API callbacks.
213  ***************************************************************************/
214 
device_open(const hw_module_t * module,const char * name,hw_device_t ** device)215 int EmulatedCameraFactory::device_open(const hw_module_t* module,
216                                        const char* name,
217                                        hw_device_t** device)
218 {
219     /*
220      * Simply verify the parameters, and dispatch the call inside the
221      * EmulatedCameraFactory instance.
222      */
223 
224     if (module != &HAL_MODULE_INFO_SYM.common) {
225         ALOGE("%s: Invalid module %p expected %p",
226              __FUNCTION__, module, &HAL_MODULE_INFO_SYM.common);
227         return -EINVAL;
228     }
229     if (name == NULL) {
230         ALOGE("%s: NULL name is not expected here", __FUNCTION__);
231         return -EINVAL;
232     }
233 
234     return gEmulatedCameraFactory.cameraDeviceOpen(atoi(name), device);
235 }
236 
get_number_of_cameras(void)237 int EmulatedCameraFactory::get_number_of_cameras(void)
238 {
239     return gEmulatedCameraFactory.getEmulatedCameraNum();
240 }
241 
get_camera_info(int camera_id,struct camera_info * info)242 int EmulatedCameraFactory::get_camera_info(int camera_id,
243                                            struct camera_info* info)
244 {
245     return gEmulatedCameraFactory.getCameraInfo(camera_id, info);
246 }
247 
248 /********************************************************************************
249  * Internal API
250  *******************************************************************************/
251 
252 /*
253  * Camera information tokens passed in response to the "list" factory query.
254  */
255 
256 /* Device name token. */
257 static const char lListNameToken[]    = "name=";
258 /* Frame dimensions token. */
259 static const char lListDimsToken[]    = "framedims=";
260 /* Facing direction token. */
261 static const char lListDirToken[]     = "dir=";
262 
createQemuCameras()263 void EmulatedCameraFactory::createQemuCameras()
264 {
265     /* Obtain camera list. */
266     char* camera_list = NULL;
267     status_t res = mQemuClient.listCameras(&camera_list);
268     /* Empty list, or list containing just an EOL means that there were no
269      * connected cameras found. */
270     if (res != NO_ERROR || camera_list == NULL || *camera_list == '\0' ||
271         *camera_list == '\n') {
272         if (camera_list != NULL) {
273             free(camera_list);
274         }
275         return;
276     }
277 
278     /*
279      * Calculate number of connected cameras. Number of EOLs in the camera list
280      * is the number of the connected cameras.
281      */
282 
283     int num = 0;
284     const char* eol = strchr(camera_list, '\n');
285     while (eol != NULL) {
286         num++;
287         eol = strchr(eol + 1, '\n');
288     }
289 
290     /* Allocate the array for emulated camera instances. Note that we allocate
291      * two more entries for back and front fake camera emulation. */
292     mEmulatedCameras = new EmulatedBaseCamera*[num + 2];
293     if (mEmulatedCameras == NULL) {
294         ALOGE("%s: Unable to allocate emulated camera array for %d entries",
295              __FUNCTION__, num + 1);
296         free(camera_list);
297         return;
298     }
299     memset(mEmulatedCameras, 0, sizeof(EmulatedBaseCamera*) * (num + 1));
300 
301     /*
302      * Iterate the list, creating, and initializin emulated qemu cameras for each
303      * entry (line) in the list.
304      */
305 
306     int index = 0;
307     char* cur_entry = camera_list;
308     while (cur_entry != NULL && *cur_entry != '\0' && index < num) {
309         /* Find the end of the current camera entry, and terminate it with zero
310          * for simpler string manipulation. */
311         char* next_entry = strchr(cur_entry, '\n');
312         if (next_entry != NULL) {
313             *next_entry = '\0';
314             next_entry++;   // Start of the next entry.
315         }
316 
317         /* Find 'name', 'framedims', and 'dir' tokens that are required here. */
318         char* name_start = strstr(cur_entry, lListNameToken);
319         char* dim_start = strstr(cur_entry, lListDimsToken);
320         char* dir_start = strstr(cur_entry, lListDirToken);
321         if (name_start != NULL && dim_start != NULL && dir_start != NULL) {
322             /* Advance to the token values. */
323             name_start += strlen(lListNameToken);
324             dim_start += strlen(lListDimsToken);
325             dir_start += strlen(lListDirToken);
326 
327             /* Terminate token values with zero. */
328             char* s = strchr(name_start, ' ');
329             if (s != NULL) {
330                 *s = '\0';
331             }
332             s = strchr(dim_start, ' ');
333             if (s != NULL) {
334                 *s = '\0';
335             }
336             s = strchr(dir_start, ' ');
337             if (s != NULL) {
338                 *s = '\0';
339             }
340 
341             /* Create and initialize qemu camera. */
342             EmulatedQemuCamera* qemu_cam =
343                 new EmulatedQemuCamera(index, &HAL_MODULE_INFO_SYM.common);
344             if (NULL != qemu_cam) {
345                 res = qemu_cam->Initialize(name_start, dim_start, dir_start);
346                 if (res == NO_ERROR) {
347                     mEmulatedCameras[index] = qemu_cam;
348                     index++;
349                 } else {
350                     delete qemu_cam;
351                 }
352             } else {
353                 ALOGE("%s: Unable to instantiate EmulatedQemuCamera",
354                      __FUNCTION__);
355             }
356         } else {
357             ALOGW("%s: Bad camera information: %s", __FUNCTION__, cur_entry);
358         }
359 
360         cur_entry = next_entry;
361     }
362 
363     mEmulatedCameraNum = index;
364 }
365 
isBackFakeCameraEmulationOn()366 bool EmulatedCameraFactory::isBackFakeCameraEmulationOn()
367 {
368     /* Defined by 'qemu.sf.fake_camera' boot property: if property exist, and
369      * is set to 'both', or 'back', then fake camera is used to emulate back
370      * camera. */
371     char prop[PROPERTY_VALUE_MAX];
372     if ((property_get("qemu.sf.fake_camera", prop, NULL) > 0) &&
373         (!strcmp(prop, "both") || !strcmp(prop, "back"))) {
374         return true;
375     } else {
376         return false;
377     }
378 }
379 
getBackCameraHalVersion()380 int EmulatedCameraFactory::getBackCameraHalVersion()
381 {
382     /* Defined by 'qemu.sf.back_camera_hal_version' boot property: if the
383      * property doesn't exist, it is assumed to be 1. */
384     char prop[PROPERTY_VALUE_MAX];
385     if (property_get("qemu.sf.back_camera_hal", prop, NULL) > 0) {
386         char *prop_end = prop;
387         int val = strtol(prop, &prop_end, 10);
388         if (*prop_end == '\0') {
389             return val;
390         }
391         // Badly formatted property, should just be a number
392         ALOGE("qemu.sf.back_camera_hal is not a number: %s", prop);
393     }
394     return 1;
395 }
396 
isFrontFakeCameraEmulationOn()397 bool EmulatedCameraFactory::isFrontFakeCameraEmulationOn()
398 {
399     /* Defined by 'qemu.sf.fake_camera' boot property: if property exist, and
400      * is set to 'both', or 'front', then fake camera is used to emulate front
401      * camera. */
402     char prop[PROPERTY_VALUE_MAX];
403     if ((property_get("qemu.sf.fake_camera", prop, NULL) > 0) &&
404         (!strcmp(prop, "both") || !strcmp(prop, "front"))) {
405         return true;
406     } else {
407         return false;
408     }
409 }
410 
getFrontCameraHalVersion()411 int EmulatedCameraFactory::getFrontCameraHalVersion()
412 {
413     /* Defined by 'qemu.sf.front_camera_hal_version' boot property: if the
414      * property doesn't exist, it is assumed to be 1. */
415     char prop[PROPERTY_VALUE_MAX];
416     if (property_get("qemu.sf.front_camera_hal", prop, NULL) > 0) {
417         char *prop_end = prop;
418         int val = strtol(prop, &prop_end, 10);
419         if (*prop_end == '\0') {
420             return val;
421         }
422         // Badly formatted property, should just be a number
423         ALOGE("qemu.sf.front_camera_hal is not a number: %s", prop);
424     }
425     return 1;
426 }
427 
428 /********************************************************************************
429  * Initializer for the static member structure.
430  *******************************************************************************/
431 
432 /* Entry point for camera HAL API. */
433 struct hw_module_methods_t EmulatedCameraFactory::mCameraModuleMethods = {
434     open: EmulatedCameraFactory::device_open
435 };
436 
437 }; /* namespace android */
438