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