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