• 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 
25 #include "EmulatedCameraFactory.h"
26 #include "EmulatedCameraHotplugThread.h"
27 #include "EmulatedFakeCamera.h"
28 #include "EmulatedFakeCamera2.h"
29 #include "EmulatedFakeCamera3.h"
30 #include "EmulatedFakeRotatingCamera3.h"
31 #include "EmulatedQemuCamera.h"
32 #include "EmulatedQemuCamera3.h"
33 
34 #include <log/log.h>
35 #include <cutils/properties.h>
36 
37 extern camera_module_t HAL_MODULE_INFO_SYM;
38 
39 /*
40  * A global instance of EmulatedCameraFactory is statically instantiated and
41  * initialized when camera emulation HAL is loaded.
42  */
43 android::EmulatedCameraFactory gEmulatedCameraFactory;
44 
45 namespace android {
46 
EmulatedCameraFactory()47 EmulatedCameraFactory::EmulatedCameraFactory() :
48         mQemuClient(),
49         mConstructedOK(false),
50         mGBM(&GraphicBufferMapper::get()),
51         mCallbacks(nullptr) {
52 
53     /*
54      * Figure out how many cameras need to be created, so we can allocate the
55      * array of emulated cameras before populating it.
56      */
57 
58     // QEMU Cameras
59     std::vector<QemuCameraInfo> qemuCameras;
60     if (mQemuClient.connectClient(nullptr) == NO_ERROR) {
61         findQemuCameras(&qemuCameras);
62     }
63 
64     int fakeCameraNum = 0;
65     waitForQemuSfFakeCameraPropertyAvailable();
66     // Fake Cameras
67     if (isFakeCameraEmulationOn(/* backCamera */ true)) {
68         fakeCameraNum++;
69     }
70     if (isFakeCameraEmulationOn(/* backCamera */ false)) {
71         fakeCameraNum++;
72     }
73 
74     /*
75      * We have the number of cameras we need to create, now allocate space for
76      * them.
77      */
78     mEmulatedCameras.reserve(qemuCameras.size() + fakeCameraNum);
79 
80     createQemuCameras(qemuCameras);
81 
82     // Create fake cameras, if enabled.
83     if (isFakeCameraEmulationOn(/* backCamera */ true)) {
84         createFakeCamera(/* backCamera */ true);
85     }
86     if (isFakeCameraEmulationOn(/* backCamera */ false)) {
87         createFakeCamera(/* backCamera */ false);
88     }
89 
90     ALOGE("%zu cameras are being emulated. %d of them are fake cameras.",
91             mEmulatedCameras.size(), fakeCameraNum);
92 
93     // Create hotplug thread.
94     {
95         std::vector<int> cameraIdVector;
96         for (const auto &camera: mEmulatedCameras) {
97             cameraIdVector.push_back(camera->getCameraId());
98         }
99         mHotplugThread = new EmulatedCameraHotplugThread(std::move(cameraIdVector));
100         mHotplugThread->run("EmulatedCameraHotplugThread");
101     }
102 
103     mConstructedOK = true;
104 }
105 
~EmulatedCameraFactory()106 EmulatedCameraFactory::~EmulatedCameraFactory() {
107     mEmulatedCameras.clear();
108 
109     if (mHotplugThread != nullptr) {
110         mHotplugThread->requestExit();
111         mHotplugThread->join();
112     }
113 }
114 
115 /******************************************************************************
116  * Camera HAL API handlers.
117  *
118  * Each handler simply verifies existence of an appropriate EmulatedBaseCamera
119  * instance, and dispatches the call to that instance.
120  *
121  *****************************************************************************/
122 
cameraDeviceOpen(int cameraId,hw_device_t ** device)123 int EmulatedCameraFactory::cameraDeviceOpen(int cameraId,
124                                             hw_device_t **device) {
125     ALOGV("%s: id = %d", __FUNCTION__, cameraId);
126 
127     *device = nullptr;
128 
129     if (!isConstructedOK()) {
130         ALOGE("%s: EmulatedCameraFactory has failed to initialize",
131                 __FUNCTION__);
132         return -EINVAL;
133     }
134 
135     if (cameraId < 0 || cameraId >= getEmulatedCameraNum()) {
136         ALOGE("%s: Camera id %d is out of bounds (%d)",
137                 __FUNCTION__, cameraId, getEmulatedCameraNum());
138         return -ENODEV;
139     }
140 
141     return mEmulatedCameras[cameraId]->connectCamera(device);
142 }
143 
getCameraInfo(int cameraId,struct camera_info * info)144 int EmulatedCameraFactory::getCameraInfo(int cameraId,
145                                          struct camera_info *info) {
146     ALOGV("%s: id = %d", __FUNCTION__, cameraId);
147 
148     if (!isConstructedOK()) {
149         ALOGE("%s: EmulatedCameraFactory has failed to initialize",
150                 __FUNCTION__);
151         return -EINVAL;
152     }
153 
154     if (cameraId < 0 || cameraId >= getEmulatedCameraNum()) {
155         ALOGE("%s: Camera id %d is out of bounds (%d)",
156                 __FUNCTION__, cameraId, getEmulatedCameraNum());
157         return -ENODEV;
158     }
159 
160     return mEmulatedCameras[cameraId]->getCameraInfo(info);
161 }
162 
setCallbacks(const camera_module_callbacks_t * callbacks)163 int EmulatedCameraFactory::setCallbacks(
164         const camera_module_callbacks_t *callbacks) {
165     ALOGV("%s: callbacks = %p", __FUNCTION__, callbacks);
166 
167     mCallbacks = callbacks;
168 
169     return OK;
170 }
171 
getVendorTagOps(vendor_tag_ops_t * ops)172 void EmulatedCameraFactory::getVendorTagOps(vendor_tag_ops_t* ops) {
173     ALOGV("%s: ops = %p", __FUNCTION__, ops);
174     // No vendor tags defined for emulator yet, so not touching ops.
175 }
176 
177 /****************************************************************************
178  * Camera HAL API callbacks.
179  ***************************************************************************/
180 
device_open(const hw_module_t * module,const char * name,hw_device_t ** device)181 int EmulatedCameraFactory::device_open(const hw_module_t *module, const char
182         *name, hw_device_t **device) {
183     /*
184      * Simply verify the parameters, and dispatch the call inside the
185      * EmulatedCameraFactory instance.
186      */
187 
188     if (module != &HAL_MODULE_INFO_SYM.common) {
189         ALOGE("%s: Invalid module %p expected %p",
190                 __FUNCTION__, module, &HAL_MODULE_INFO_SYM.common);
191         return -EINVAL;
192     }
193     if (name == nullptr) {
194         ALOGE("%s: NULL name is not expected here", __FUNCTION__);
195         return -EINVAL;
196     }
197 
198     return gEmulatedCameraFactory.cameraDeviceOpen(atoi(name), device);
199 }
200 
get_number_of_cameras()201 int EmulatedCameraFactory::get_number_of_cameras() {
202     return gEmulatedCameraFactory.getEmulatedCameraNum();
203 }
204 
get_camera_info(int camera_id,struct camera_info * info)205 int EmulatedCameraFactory::get_camera_info(int camera_id,
206                         struct camera_info *info) {
207     return gEmulatedCameraFactory.getCameraInfo(camera_id, info);
208 }
209 
set_callbacks(const camera_module_callbacks_t * callbacks)210 int EmulatedCameraFactory::set_callbacks(
211         const camera_module_callbacks_t *callbacks) {
212     return gEmulatedCameraFactory.setCallbacks(callbacks);
213 }
214 
get_vendor_tag_ops(vendor_tag_ops_t * ops)215 void EmulatedCameraFactory::get_vendor_tag_ops(vendor_tag_ops_t *ops) {
216     gEmulatedCameraFactory.getVendorTagOps(ops);
217 }
218 
open_legacy(const struct hw_module_t * module,const char * id,uint32_t halVersion,struct hw_device_t ** device)219 int EmulatedCameraFactory::open_legacy(const struct hw_module_t *module,
220         const char *id, uint32_t halVersion, struct hw_device_t **device) {
221     // Not supporting legacy open.
222     return -ENOSYS;
223 }
224 
225 /********************************************************************************
226  * Internal API
227  *******************************************************************************/
228 
229 /*
230  * Camera information tokens passed in response to the "list" factory query.
231  */
232 
233 // Device name token.
234 static const char *kListNameToken = "name=";
235 // Frame dimensions token.
236 static const char *kListDimsToken = "framedims=";
237 // Facing direction token.
238 static const char *kListDirToken = "dir=";
239 
240 
getTokenValue(const char * token,const std::string & s,char ** value)241 bool EmulatedCameraFactory::getTokenValue(const char *token,
242         const std::string &s, char **value) {
243     // Find the start of the token.
244     size_t tokenStart = s.find(token);
245     if (tokenStart == std::string::npos) {
246         return false;
247     }
248 
249     // Advance to the beginning of the token value.
250     size_t valueStart = tokenStart + strlen(token);
251 
252     // Find the length of the token value.
253     size_t valueLength = s.find(' ', valueStart) - valueStart;
254 
255     // Extract the value substring.
256     std::string valueStr = s.substr(valueStart, valueLength);
257 
258     // Convert to char*.
259     *value = new char[valueStr.length() + 1];
260     if (*value == nullptr) {
261         return false;
262     }
263     strcpy(*value, valueStr.c_str());
264 
265     ALOGV("%s: Parsed value is \"%s\"", __FUNCTION__, *value);
266 
267     return true;
268 }
269 
findQemuCameras(std::vector<QemuCameraInfo> * qemuCameras)270 void EmulatedCameraFactory::findQemuCameras(
271         std::vector<QemuCameraInfo> *qemuCameras) {
272     // Obtain camera list.
273     char *cameraList = nullptr;
274     status_t res = mQemuClient.listCameras(&cameraList);
275 
276     /*
277      * Empty list, or list containing just an EOL means that there were no
278      * connected cameras found.
279      */
280     if (res != NO_ERROR || cameraList == nullptr || *cameraList == '\0' ||
281         *cameraList == '\n') {
282         if (cameraList != nullptr) {
283             free(cameraList);
284         }
285         return;
286     }
287 
288     /*
289      * Calculate number of connected cameras. Number of EOLs in the camera list
290      * is the number of the connected cameras.
291      */
292 
293     std::string cameraListStr(cameraList);
294     free(cameraList);
295 
296     size_t lineBegin = 0;
297     size_t lineEnd = cameraListStr.find('\n');
298     while (lineEnd != std::string::npos) {
299         std::string cameraStr = cameraListStr.substr(lineBegin, lineEnd - lineBegin);
300         // Parse the 'name', 'framedims', and 'dir' tokens.
301         char *name, *frameDims, *dir;
302         if (getTokenValue(kListNameToken, cameraStr, &name) &&
303                 getTokenValue(kListDimsToken, cameraStr, &frameDims) &&
304                 getTokenValue(kListDirToken, cameraStr, &dir)) {
305             // Push the camera info if it was all successfully parsed.
306             qemuCameras->push_back(QemuCameraInfo{
307                 .name = name,
308                 .frameDims = frameDims,
309                 .dir = dir,
310             });
311         } else {
312             ALOGW("%s: Bad camera information: %s", __FUNCTION__,
313                     cameraStr.c_str());
314         }
315         // Skip over the newline for the beginning of the next line.
316         lineBegin = lineEnd + 1;
317         lineEnd = cameraListStr.find('\n', lineBegin);
318     }
319 }
320 
321 std::unique_ptr<EmulatedBaseCamera>
createQemuCameraImpl(int halVersion,const QemuCameraInfo & camInfo,int cameraId,struct hw_module_t * module)322 EmulatedCameraFactory::createQemuCameraImpl(int halVersion,
323                                             const QemuCameraInfo& camInfo,
324                                             int cameraId,
325                                             struct hw_module_t* module) {
326     status_t res;
327 
328     switch (halVersion) {
329     case 1: {
330             auto camera = std::make_unique<EmulatedQemuCamera>(cameraId, module, mGBM);
331             res = camera->Initialize(camInfo.name, camInfo.frameDims, camInfo.dir);
332             if (res == NO_ERROR) {
333                 return camera;
334             }
335         }
336         break;
337 
338     case 3: {
339             auto camera = std::make_unique<EmulatedQemuCamera3>(cameraId, module, mGBM);
340             res = camera->Initialize(camInfo.name, camInfo.frameDims, camInfo.dir);
341             if (res == NO_ERROR) {
342                 return camera;
343             }
344         }
345         break;
346 
347     default:
348         ALOGE("%s: QEMU support for camera hal version %d is not "
349               "implemented", __func__, halVersion);
350         break;
351     }
352 
353     return nullptr;
354 }
355 
createQemuCameras(const std::vector<QemuCameraInfo> & qemuCameras)356 void EmulatedCameraFactory::createQemuCameras(
357         const std::vector<QemuCameraInfo> &qemuCameras) {
358     /*
359      * Iterate the list, creating, and initializing emulated QEMU cameras for each
360      * entry in the list.
361      */
362 
363     /*
364      * We use this index only for determining which direction the webcam should
365      * face. Otherwise, mEmulatedCameraNum represents the camera ID and the
366      * index into mEmulatedCameras.
367      */
368     int qemuIndex = 0;
369     for (const auto &cameraInfo : qemuCameras) {
370         /*
371          * Here, we're assuming the first webcam is intended to be the back
372          * camera and any other webcams are front cameras.
373          */
374         const bool isBackcamera = (qemuIndex == 0);
375         const int halVersion = getCameraHalVersion(isBackcamera);
376 
377         std::unique_ptr<EmulatedBaseCamera> camera =
378             createQemuCameraImpl(halVersion,
379                                  cameraInfo,
380                                  mEmulatedCameras.size(),
381                                  &HAL_MODULE_INFO_SYM.common);
382         if (camera) {
383             mEmulatedCameras.push_back(std::move(camera));
384         }
385 
386         qemuIndex++;
387     }
388 }
389 
390 std::unique_ptr<EmulatedBaseCamera>
createFakeCameraImpl(bool backCamera,int halVersion,int cameraId,struct hw_module_t * module)391 EmulatedCameraFactory::createFakeCameraImpl(bool backCamera,
392                                             int halVersion,
393                                             int cameraId,
394                                             struct hw_module_t* module) {
395     switch (halVersion) {
396     case 1:
397         return std::make_unique<EmulatedFakeCamera>(cameraId, backCamera, module, mGBM);
398 
399     case 2:
400         return std::make_unique<EmulatedFakeCamera2>(cameraId, backCamera, module, mGBM);
401 
402     case 3: {
403             static const char key[] = "ro.boot.qemu.camera.fake.rotating";
404             char prop[PROPERTY_VALUE_MAX];
405 
406             if (property_get(key, prop, nullptr) > 0) {
407                 return std::make_unique<EmulatedFakeRotatingCamera3>(cameraId, backCamera, module, mGBM);
408             } else {
409                 return std::make_unique<EmulatedFakeCamera3>(cameraId, backCamera, module, mGBM);
410             }
411         }
412 
413     default:
414         ALOGE("%s: Unknown %s camera hal version requested: %d",
415               __func__, backCamera ? "back" : "front", halVersion);
416         return nullptr;
417     }
418 }
419 
createFakeCamera(bool backCamera)420 void EmulatedCameraFactory::createFakeCamera(bool backCamera) {
421     const int halVersion = getCameraHalVersion(backCamera);
422 
423     std::unique_ptr<EmulatedBaseCamera> camera = createFakeCameraImpl(
424         backCamera, halVersion, mEmulatedCameras.size(),
425         &HAL_MODULE_INFO_SYM.common);
426 
427     status_t res = camera->Initialize();
428     if (res == NO_ERROR) {
429         mEmulatedCameras.push_back(std::move(camera));
430     } else {
431         ALOGE("%s: Unable to initialize %s camera %zu: %s (%d)",
432               __func__, backCamera ? "back" : "front",
433               mEmulatedCameras.size(), strerror(-res), res);
434     }
435 }
436 
waitForQemuSfFakeCameraPropertyAvailable()437 void EmulatedCameraFactory::waitForQemuSfFakeCameraPropertyAvailable() {
438     /*
439      * Camera service may start running before qemu-props sets
440      * vendor.qemu.sf.fake_camera to any of the following four values:
441      * "none,front,back,both"; so we need to wait.
442      *
443      * android/camera/camera-service.c
444      * bug: 30768229
445      */
446     int numAttempts = 100;
447     char prop[PROPERTY_VALUE_MAX];
448     bool timeout = true;
449     for (int i = 0; i < numAttempts; ++i) {
450         if (property_get("vendor.qemu.sf.fake_camera", prop, nullptr) != 0 ) {
451             timeout = false;
452             break;
453         }
454         usleep(5000);
455     }
456     if (timeout) {
457         ALOGE("timeout (%dms) waiting for property vendor.qemu.sf.fake_camera to be set\n", 5 * numAttempts);
458     }
459 }
460 
isFakeCameraEmulationOn(bool backCamera)461 bool EmulatedCameraFactory::isFakeCameraEmulationOn(bool backCamera) {
462     // Always return false, because another HAL (Google Camera HAL)
463     // will create the fake cameras
464     if (!property_get_bool("ro.boot.qemu.legacy_fake_camera", false)) {
465         return false;
466     }
467     char prop[PROPERTY_VALUE_MAX];
468     if ((property_get("vendor.qemu.sf.fake_camera", prop, nullptr) > 0) &&
469         (!strcmp(prop, "both") ||
470          !strcmp(prop, backCamera ? "back" : "front"))) {
471         return true;
472     } else {
473         return false;
474     }
475 }
476 
getCameraHalVersion(bool backCamera)477 int EmulatedCameraFactory::getCameraHalVersion(bool backCamera) {
478     /*
479      * Defined by 'qemu.sf.front_camera_hal_version' and
480      * 'qemu.sf.back_camera_hal_version' boot properties. If the property
481      * doesn't exist, it is assumed we are working with HAL v1.
482      */
483     char prop[PROPERTY_VALUE_MAX];
484     const char *propQuery = backCamera ?
485             "qemu.sf.back_camera_hal" :
486             "qemu.sf.front_camera_hal";
487     if (property_get(propQuery, prop, nullptr) > 0) {
488         char *propEnd = prop;
489         int val = strtol(prop, &propEnd, 10);
490         if (*propEnd == '\0') {
491             return val;
492         }
493         // Badly formatted property. It should just be a number.
494         ALOGE("qemu.sf.back_camera_hal is not a number: %s", prop);
495     }
496     return 3;
497 }
498 
onStatusChanged(int cameraId,int newStatus)499 void EmulatedCameraFactory::onStatusChanged(int cameraId, int newStatus) {
500 
501     EmulatedBaseCamera *cam = mEmulatedCameras[cameraId].get();
502     if (!cam) {
503         ALOGE("%s: Invalid camera ID %d", __FUNCTION__, cameraId);
504         return;
505     }
506 
507     /*
508      * (Order is important)
509      * Send the callback first to framework, THEN close the camera.
510      */
511 
512     if (newStatus == cam->getHotplugStatus()) {
513         ALOGW("%s: Ignoring transition to the same status", __FUNCTION__);
514         return;
515     }
516 
517     const camera_module_callbacks_t* cb = mCallbacks;
518     if (cb != nullptr && cb->camera_device_status_change != nullptr) {
519         cb->camera_device_status_change(cb, cameraId, newStatus);
520     }
521 
522     if (newStatus == CAMERA_DEVICE_STATUS_NOT_PRESENT) {
523         cam->unplugCamera();
524     } else if (newStatus == CAMERA_DEVICE_STATUS_PRESENT) {
525         cam->plugCamera();
526     }
527 }
528 
529 /********************************************************************************
530  * Initializer for the static member structure.
531  *******************************************************************************/
532 
533 // Entry point for camera HAL API.
534 struct hw_module_methods_t EmulatedCameraFactory::mCameraModuleMethods = {
535     .open = EmulatedCameraFactory::device_open
536 };
537 
538 }; // end of namespace android
539