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