Home | History | Annotate | Download | only in default
      1 /*
      2  * Copyright (C) 2016 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 #define LOG_TAG "CamPrvdr (at) 2.4-legacy"
     18 //#define LOG_NDEBUG 0
     19 #include <android/log.h>
     20 
     21 #include "LegacyCameraProviderImpl_2_4.h"
     22 #include "CameraDevice_1_0.h"
     23 #include "CameraDevice_3_3.h"
     24 #include "CameraDevice_3_4.h"
     25 #include "CameraDevice_3_5.h"
     26 #include "CameraProvider_2_4.h"
     27 #include <cutils/properties.h>
     28 #include <regex>
     29 #include <string.h>
     30 #include <utils/Trace.h>
     31 
     32 namespace android {
     33 namespace hardware {
     34 namespace camera {
     35 namespace provider {
     36 namespace V2_4 {
     37 namespace implementation {
     38 
     39 template struct CameraProvider<LegacyCameraProviderImpl_2_4>;
     40 
     41 namespace {
     42 // "device@<version>/legacy/<id>"
     43 const std::regex kDeviceNameRE("device@([0-9]+\\.[0-9]+)/legacy/(.+)");
     44 const char *kHAL3_4 = "3.4";
     45 const char *kHAL3_5 = "3.5";
     46 const int kMaxCameraDeviceNameLen = 128;
     47 const int kMaxCameraIdLen = 16;
     48 
     49 bool matchDeviceName(const hidl_string& deviceName, std::string* deviceVersion,
     50                      std::string* cameraId) {
     51     std::string deviceNameStd(deviceName.c_str());
     52     std::smatch sm;
     53     if (std::regex_match(deviceNameStd, sm, kDeviceNameRE)) {
     54         if (deviceVersion != nullptr) {
     55             *deviceVersion = sm[1];
     56         }
     57         if (cameraId != nullptr) {
     58             *cameraId = sm[2];
     59         }
     60         return true;
     61     }
     62     return false;
     63 }
     64 
     65 } // anonymous namespace
     66 
     67 using ::android::hardware::camera::common::V1_0::CameraMetadataType;
     68 using ::android::hardware::camera::common::V1_0::Status;
     69 
     70 void LegacyCameraProviderImpl_2_4::addDeviceNames(int camera_id, CameraDeviceStatus status, bool cam_new)
     71 {
     72     char cameraId[kMaxCameraIdLen];
     73     snprintf(cameraId, sizeof(cameraId), "%d", camera_id);
     74     std::string cameraIdStr(cameraId);
     75 
     76     mCameraIds.add(cameraIdStr);
     77 
     78     // initialize mCameraDeviceNames and mOpenLegacySupported
     79     mOpenLegacySupported[cameraIdStr] = false;
     80     int deviceVersion = mModule->getDeviceVersion(camera_id);
     81     auto deviceNamePair = std::make_pair(cameraIdStr,
     82                                          getHidlDeviceName(cameraIdStr, deviceVersion));
     83     mCameraDeviceNames.add(deviceNamePair);
     84     if (cam_new) {
     85         mCallbacks->cameraDeviceStatusChange(deviceNamePair.second, status);
     86     }
     87     if (deviceVersion >= CAMERA_DEVICE_API_VERSION_3_2 &&
     88             mModule->isOpenLegacyDefined()) {
     89         // try open_legacy to see if it actually works
     90         struct hw_device_t* halDev = nullptr;
     91         int ret = mModule->openLegacy(cameraId, CAMERA_DEVICE_API_VERSION_1_0, &halDev);
     92         if (ret == 0) {
     93             mOpenLegacySupported[cameraIdStr] = true;
     94             halDev->close(halDev);
     95             deviceNamePair = std::make_pair(cameraIdStr,
     96                             getHidlDeviceName(cameraIdStr, CAMERA_DEVICE_API_VERSION_1_0));
     97             mCameraDeviceNames.add(deviceNamePair);
     98             if (cam_new) {
     99                 mCallbacks->cameraDeviceStatusChange(deviceNamePair.second, status);
    100             }
    101         } else if (ret == -EBUSY || ret == -EUSERS) {
    102             // Looks like this provider instance is not initialized during
    103             // system startup and there are other camera users already.
    104             // Not a good sign but not fatal.
    105             ALOGW("%s: open_legacy try failed!", __FUNCTION__);
    106         }
    107     }
    108 }
    109 
    110 void LegacyCameraProviderImpl_2_4::removeDeviceNames(int camera_id)
    111 {
    112     std::string cameraIdStr = std::to_string(camera_id);
    113 
    114     mCameraIds.remove(cameraIdStr);
    115 
    116     int deviceVersion = mModule->getDeviceVersion(camera_id);
    117     auto deviceNamePair = std::make_pair(cameraIdStr,
    118                                          getHidlDeviceName(cameraIdStr, deviceVersion));
    119     mCameraDeviceNames.remove(deviceNamePair);
    120     mCallbacks->cameraDeviceStatusChange(deviceNamePair.second, CameraDeviceStatus::NOT_PRESENT);
    121     if (deviceVersion >= CAMERA_DEVICE_API_VERSION_3_2 &&
    122         mModule->isOpenLegacyDefined() && mOpenLegacySupported[cameraIdStr]) {
    123 
    124         deviceNamePair = std::make_pair(cameraIdStr,
    125                             getHidlDeviceName(cameraIdStr, CAMERA_DEVICE_API_VERSION_1_0));
    126         mCameraDeviceNames.remove(deviceNamePair);
    127         mCallbacks->cameraDeviceStatusChange(deviceNamePair.second,
    128                                              CameraDeviceStatus::NOT_PRESENT);
    129     }
    130 
    131     mModule->removeCamera(camera_id);
    132 }
    133 
    134 /**
    135  * static callback forwarding methods from HAL to instance
    136  */
    137 void LegacyCameraProviderImpl_2_4::sCameraDeviceStatusChange(
    138         const struct camera_module_callbacks* callbacks,
    139         int camera_id,
    140         int new_status) {
    141     LegacyCameraProviderImpl_2_4* cp = const_cast<LegacyCameraProviderImpl_2_4*>(
    142             static_cast<const LegacyCameraProviderImpl_2_4*>(callbacks));
    143     if (cp == nullptr) {
    144         ALOGE("%s: callback ops is null", __FUNCTION__);
    145         return;
    146     }
    147 
    148     Mutex::Autolock _l(cp->mCbLock);
    149     char cameraId[kMaxCameraIdLen];
    150     snprintf(cameraId, sizeof(cameraId), "%d", camera_id);
    151     std::string cameraIdStr(cameraId);
    152     cp->mCameraStatusMap[cameraIdStr] = (camera_device_status_t) new_status;
    153 
    154     if (cp->mCallbacks == nullptr) {
    155         // For camera connected before mCallbacks is set, the corresponding
    156         // addDeviceNames() would be called later in setCallbacks().
    157         return;
    158     }
    159 
    160     bool found = false;
    161     CameraDeviceStatus status = (CameraDeviceStatus)new_status;
    162     for (auto const& deviceNamePair : cp->mCameraDeviceNames) {
    163         if (cameraIdStr.compare(deviceNamePair.first) == 0) {
    164             cp->mCallbacks->cameraDeviceStatusChange(deviceNamePair.second, status);
    165             found = true;
    166         }
    167     }
    168 
    169     switch (status) {
    170         case CameraDeviceStatus::PRESENT:
    171         case CameraDeviceStatus::ENUMERATING:
    172             if (!found) {
    173                 cp->addDeviceNames(camera_id, status, true);
    174             }
    175             break;
    176         case CameraDeviceStatus::NOT_PRESENT:
    177             if (found) {
    178                 cp->removeDeviceNames(camera_id);
    179             }
    180     }
    181 }
    182 
    183 void LegacyCameraProviderImpl_2_4::sTorchModeStatusChange(
    184         const struct camera_module_callbacks* callbacks,
    185         const char* camera_id,
    186         int new_status) {
    187     LegacyCameraProviderImpl_2_4* cp = const_cast<LegacyCameraProviderImpl_2_4*>(
    188             static_cast<const LegacyCameraProviderImpl_2_4*>(callbacks));
    189 
    190     if (cp == nullptr) {
    191         ALOGE("%s: callback ops is null", __FUNCTION__);
    192         return;
    193     }
    194 
    195     Mutex::Autolock _l(cp->mCbLock);
    196     if (cp->mCallbacks != nullptr) {
    197         std::string cameraIdStr(camera_id);
    198         TorchModeStatus status = (TorchModeStatus) new_status;
    199         for (auto const& deviceNamePair : cp->mCameraDeviceNames) {
    200             if (cameraIdStr.compare(deviceNamePair.first) == 0) {
    201                 cp->mCallbacks->torchModeStatusChange(
    202                         deviceNamePair.second, status);
    203             }
    204         }
    205     }
    206 }
    207 
    208 Status LegacyCameraProviderImpl_2_4::getHidlStatus(int status) {
    209     switch (status) {
    210         case 0: return Status::OK;
    211         case -ENODEV: return Status::INTERNAL_ERROR;
    212         case -EINVAL: return Status::ILLEGAL_ARGUMENT;
    213         default:
    214             ALOGE("%s: unknown HAL status code %d", __FUNCTION__, status);
    215             return Status::INTERNAL_ERROR;
    216     }
    217 }
    218 
    219 std::string LegacyCameraProviderImpl_2_4::getLegacyCameraId(const hidl_string& deviceName) {
    220     std::string cameraId;
    221     matchDeviceName(deviceName, nullptr, &cameraId);
    222     return cameraId;
    223 }
    224 
    225 std::string LegacyCameraProviderImpl_2_4::getHidlDeviceName(
    226         std::string cameraId, int deviceVersion) {
    227     // Maybe consider create a version check method and SortedVec to speed up?
    228     if (deviceVersion != CAMERA_DEVICE_API_VERSION_1_0 &&
    229             deviceVersion != CAMERA_DEVICE_API_VERSION_3_2 &&
    230             deviceVersion != CAMERA_DEVICE_API_VERSION_3_3 &&
    231             deviceVersion != CAMERA_DEVICE_API_VERSION_3_4 &&
    232             deviceVersion != CAMERA_DEVICE_API_VERSION_3_5 &&
    233             deviceVersion != CAMERA_DEVICE_API_VERSION_3_6) {
    234         return hidl_string("");
    235     }
    236 
    237     // Supported combinations:
    238     // CAMERA_DEVICE_API_VERSION_1_0 -> ICameraDevice (at) 1.0
    239     // CAMERA_DEVICE_API_VERSION_3_[2-4] -> ICameraDevice@[3.2|3.3]
    240     // CAMERA_DEVICE_API_VERSION_3_5 + CAMERA_MODULE_API_VERSION_2_4 -> ICameraDevice (at) 3.4
    241     // CAMERA_DEVICE_API_VERSION_3_[5-6] + CAMERA_MODULE_API_VERSION_2_5 -> ICameraDevice (at) 3.5
    242     bool isV1 = deviceVersion == CAMERA_DEVICE_API_VERSION_1_0;
    243     int versionMajor = isV1 ? 1 : 3;
    244     int versionMinor = isV1 ? 0 : mPreferredHal3MinorVersion;
    245     if (deviceVersion == CAMERA_DEVICE_API_VERSION_3_5) {
    246         if (mModule->getModuleApiVersion() == CAMERA_MODULE_API_VERSION_2_5) {
    247             versionMinor = 5;
    248         } else {
    249             versionMinor = 4;
    250         }
    251     } else if (deviceVersion == CAMERA_DEVICE_API_VERSION_3_6) {
    252         versionMinor = 5;
    253     }
    254     char deviceName[kMaxCameraDeviceNameLen];
    255     snprintf(deviceName, sizeof(deviceName), "device@%d.%d/legacy/%s",
    256             versionMajor, versionMinor, cameraId.c_str());
    257     return deviceName;
    258 }
    259 
    260 LegacyCameraProviderImpl_2_4::LegacyCameraProviderImpl_2_4() :
    261         camera_module_callbacks_t({sCameraDeviceStatusChange,
    262                                    sTorchModeStatusChange}) {
    263     mInitFailed = initialize();
    264 }
    265 
    266 LegacyCameraProviderImpl_2_4::~LegacyCameraProviderImpl_2_4() {}
    267 
    268 bool LegacyCameraProviderImpl_2_4::initialize() {
    269     camera_module_t *rawModule;
    270     int err = hw_get_module(CAMERA_HARDWARE_MODULE_ID,
    271             (const hw_module_t **)&rawModule);
    272     if (err < 0) {
    273         ALOGE("Could not load camera HAL module: %d (%s)", err, strerror(-err));
    274         return true;
    275     }
    276 
    277     mModule = new CameraModule(rawModule);
    278     err = mModule->init();
    279     if (err != OK) {
    280         ALOGE("Could not initialize camera HAL module: %d (%s)", err, strerror(-err));
    281         mModule.clear();
    282         return true;
    283     }
    284     ALOGI("Loaded \"%s\" camera module", mModule->getModuleName());
    285 
    286     // Setup vendor tags here so HAL can setup vendor keys in camera characteristics
    287     VendorTagDescriptor::clearGlobalVendorTagDescriptor();
    288     if (!setUpVendorTags()) {
    289         ALOGE("%s: Vendor tag setup failed, will not be available.", __FUNCTION__);
    290     }
    291 
    292     // Setup callback now because we are going to try openLegacy next
    293     err = mModule->setCallbacks(this);
    294     if (err != OK) {
    295         ALOGE("Could not set camera module callback: %d (%s)", err, strerror(-err));
    296         mModule.clear();
    297         return true;
    298     }
    299 
    300     mPreferredHal3MinorVersion =
    301         property_get_int32("ro.vendor.camera.wrapper.hal3TrebleMinorVersion", 3);
    302     ALOGV("Preferred HAL 3 minor version is %d", mPreferredHal3MinorVersion);
    303     switch(mPreferredHal3MinorVersion) {
    304         case 2:
    305         case 3:
    306             // OK
    307             break;
    308         default:
    309             ALOGW("Unknown minor camera device HAL version %d in property "
    310                     "'camera.wrapper.hal3TrebleMinorVersion', defaulting to 3",
    311                     mPreferredHal3MinorVersion);
    312             mPreferredHal3MinorVersion = 3;
    313     }
    314 
    315     mNumberOfLegacyCameras = mModule->getNumberOfCameras();
    316     for (int i = 0; i < mNumberOfLegacyCameras; i++) {
    317         struct camera_info info;
    318         auto rc = mModule->getCameraInfo(i, &info);
    319         if (rc != NO_ERROR) {
    320             ALOGE("%s: Camera info query failed!", __func__);
    321             mModule.clear();
    322             return true;
    323         }
    324 
    325         if (checkCameraVersion(i, info) != OK) {
    326             ALOGE("%s: Camera version check failed!", __func__);
    327             mModule.clear();
    328             return true;
    329         }
    330 
    331         char cameraId[kMaxCameraIdLen];
    332         snprintf(cameraId, sizeof(cameraId), "%d", i);
    333         std::string cameraIdStr(cameraId);
    334         mCameraStatusMap[cameraIdStr] = CAMERA_DEVICE_STATUS_PRESENT;
    335 
    336         addDeviceNames(i);
    337     }
    338 
    339     return false; // mInitFailed
    340 }
    341 
    342 /**
    343  * Check that the device HAL version is still in supported.
    344  */
    345 int LegacyCameraProviderImpl_2_4::checkCameraVersion(int id, camera_info info) {
    346     if (mModule == nullptr) {
    347         return NO_INIT;
    348     }
    349 
    350     // device_version undefined in CAMERA_MODULE_API_VERSION_1_0,
    351     // All CAMERA_MODULE_API_VERSION_1_0 devices are backward-compatible
    352     uint16_t moduleVersion = mModule->getModuleApiVersion();
    353     if (moduleVersion >= CAMERA_MODULE_API_VERSION_2_0) {
    354         // Verify the device version is in the supported range
    355         switch (info.device_version) {
    356             case CAMERA_DEVICE_API_VERSION_1_0:
    357             case CAMERA_DEVICE_API_VERSION_3_2:
    358             case CAMERA_DEVICE_API_VERSION_3_3:
    359             case CAMERA_DEVICE_API_VERSION_3_4:
    360             case CAMERA_DEVICE_API_VERSION_3_5:
    361                 // in support
    362                 break;
    363             case CAMERA_DEVICE_API_VERSION_3_6:
    364                 /**
    365                  * ICameraDevice (at) 3.5 contains APIs from both
    366                  * CAMERA_DEVICE_API_VERSION_3_6 and CAMERA_MODULE_API_VERSION_2_5
    367                  * so we require HALs to uprev both for simplified supported combinations.
    368                  * HAL can still opt in individual new APIs indepedently.
    369                  */
    370                 if (moduleVersion < CAMERA_MODULE_API_VERSION_2_5) {
    371                     ALOGE("%s: Device %d has unsupported version combination:"
    372                             "HAL version %x and module version %x",
    373                             __FUNCTION__, id, info.device_version, moduleVersion);
    374                     return NO_INIT;
    375                 }
    376                 break;
    377             case CAMERA_DEVICE_API_VERSION_2_0:
    378             case CAMERA_DEVICE_API_VERSION_2_1:
    379             case CAMERA_DEVICE_API_VERSION_3_0:
    380             case CAMERA_DEVICE_API_VERSION_3_1:
    381                 // no longer supported
    382             default:
    383                 ALOGE("%s: Device %d has HAL version %x, which is not supported",
    384                         __FUNCTION__, id, info.device_version);
    385                 return NO_INIT;
    386         }
    387     }
    388 
    389     return OK;
    390 }
    391 
    392 bool LegacyCameraProviderImpl_2_4::setUpVendorTags() {
    393     ATRACE_CALL();
    394     vendor_tag_ops_t vOps = vendor_tag_ops_t();
    395 
    396     // Check if vendor operations have been implemented
    397     if (!mModule->isVendorTagDefined()) {
    398         ALOGI("%s: No vendor tags defined for this device.", __FUNCTION__);
    399         return true;
    400     }
    401 
    402     mModule->getVendorTagOps(&vOps);
    403 
    404     // Ensure all vendor operations are present
    405     if (vOps.get_tag_count == nullptr || vOps.get_all_tags == nullptr ||
    406             vOps.get_section_name == nullptr || vOps.get_tag_name == nullptr ||
    407             vOps.get_tag_type == nullptr) {
    408         ALOGE("%s: Vendor tag operations not fully defined. Ignoring definitions."
    409                , __FUNCTION__);
    410         return false;
    411     }
    412 
    413     // Read all vendor tag definitions into a descriptor
    414     sp<VendorTagDescriptor> desc;
    415     status_t res;
    416     if ((res = VendorTagDescriptor::createDescriptorFromOps(&vOps, /*out*/desc))
    417             != OK) {
    418         ALOGE("%s: Could not generate descriptor from vendor tag operations,"
    419               "received error %s (%d). Camera clients will not be able to use"
    420               "vendor tags", __FUNCTION__, strerror(res), res);
    421         return false;
    422     }
    423 
    424     // Set the global descriptor to use with camera metadata
    425     VendorTagDescriptor::setAsGlobalVendorTagDescriptor(desc);
    426     const SortedVector<String8>* sectionNames = desc->getAllSectionNames();
    427     size_t numSections = sectionNames->size();
    428     std::vector<std::vector<VendorTag>> tagsBySection(numSections);
    429     int tagCount = desc->getTagCount();
    430     std::vector<uint32_t> tags(tagCount);
    431     desc->getTagArray(tags.data());
    432     for (int i = 0; i < tagCount; i++) {
    433         VendorTag vt;
    434         vt.tagId = tags[i];
    435         vt.tagName = desc->getTagName(tags[i]);
    436         vt.tagType = (CameraMetadataType) desc->getTagType(tags[i]);
    437         ssize_t sectionIdx = desc->getSectionIndex(tags[i]);
    438         tagsBySection[sectionIdx].push_back(vt);
    439     }
    440     mVendorTagSections.resize(numSections);
    441     for (size_t s = 0; s < numSections; s++) {
    442         mVendorTagSections[s].sectionName = (*sectionNames)[s].string();
    443         mVendorTagSections[s].tags = tagsBySection[s];
    444     }
    445     return true;
    446 }
    447 
    448 // Methods from ::android::hardware::camera::provider::V2_4::ICameraProvider follow.
    449 Return<Status> LegacyCameraProviderImpl_2_4::setCallback(
    450         const sp<ICameraProviderCallback>& callback) {
    451     Mutex::Autolock _l(mCbLock);
    452     mCallbacks = callback;
    453 
    454     // Add and report all presenting external cameras.
    455     for (auto const& statusPair : mCameraStatusMap) {
    456         int id = std::stoi(statusPair.first);
    457         auto status = static_cast<CameraDeviceStatus>(statusPair.second);
    458         if (id >= mNumberOfLegacyCameras && status != CameraDeviceStatus::NOT_PRESENT) {
    459             addDeviceNames(id, status, true);
    460         }
    461     }
    462 
    463     return Status::OK;
    464 }
    465 
    466 Return<void> LegacyCameraProviderImpl_2_4::getVendorTags(
    467         ICameraProvider::getVendorTags_cb _hidl_cb) {
    468     _hidl_cb(Status::OK, mVendorTagSections);
    469     return Void();
    470 }
    471 
    472 Return<void> LegacyCameraProviderImpl_2_4::getCameraIdList(
    473         ICameraProvider::getCameraIdList_cb _hidl_cb) {
    474     std::vector<hidl_string> deviceNameList;
    475     for (auto const& deviceNamePair : mCameraDeviceNames) {
    476         if (std::stoi(deviceNamePair.first) >= mNumberOfLegacyCameras) {
    477             // External camera devices must be reported through the device status change callback,
    478             // not in this list.
    479             continue;
    480         }
    481         if (mCameraStatusMap[deviceNamePair.first] == CAMERA_DEVICE_STATUS_PRESENT) {
    482             deviceNameList.push_back(deviceNamePair.second);
    483         }
    484     }
    485     hidl_vec<hidl_string> hidlDeviceNameList(deviceNameList);
    486     _hidl_cb(Status::OK, hidlDeviceNameList);
    487     return Void();
    488 }
    489 
    490 Return<void> LegacyCameraProviderImpl_2_4::isSetTorchModeSupported(
    491         ICameraProvider::isSetTorchModeSupported_cb _hidl_cb) {
    492     bool support = mModule->isSetTorchModeSupported();
    493     _hidl_cb (Status::OK, support);
    494     return Void();
    495 }
    496 
    497 Return<void> LegacyCameraProviderImpl_2_4::getCameraDeviceInterface_V1_x(
    498         const hidl_string& cameraDeviceName,
    499         ICameraProvider::getCameraDeviceInterface_V1_x_cb _hidl_cb)  {
    500     std::string cameraId, deviceVersion;
    501     bool match = matchDeviceName(cameraDeviceName, &deviceVersion, &cameraId);
    502     if (!match) {
    503         _hidl_cb(Status::ILLEGAL_ARGUMENT, nullptr);
    504         return Void();
    505     }
    506 
    507     std::string deviceName(cameraDeviceName.c_str());
    508     ssize_t index = mCameraDeviceNames.indexOf(std::make_pair(cameraId, deviceName));
    509     if (index == NAME_NOT_FOUND) { // Either an illegal name or a device version mismatch
    510         Status status = Status::OK;
    511         ssize_t idx = mCameraIds.indexOf(cameraId);
    512         if (idx == NAME_NOT_FOUND) {
    513             ALOGE("%s: cannot find camera %s!", __FUNCTION__, cameraId.c_str());
    514             status = Status::ILLEGAL_ARGUMENT;
    515         } else { // invalid version
    516             ALOGE("%s: camera device %s does not support version %s!",
    517                     __FUNCTION__, cameraId.c_str(), deviceVersion.c_str());
    518             status = Status::OPERATION_NOT_SUPPORTED;
    519         }
    520         _hidl_cb(status, nullptr);
    521         return Void();
    522     }
    523 
    524     if (mCameraStatusMap.count(cameraId) == 0 ||
    525             mCameraStatusMap[cameraId] != CAMERA_DEVICE_STATUS_PRESENT) {
    526         _hidl_cb(Status::ILLEGAL_ARGUMENT, nullptr);
    527         return Void();
    528     }
    529 
    530     sp<android::hardware::camera::device::V1_0::implementation::CameraDevice> device =
    531             new android::hardware::camera::device::V1_0::implementation::CameraDevice(
    532                     mModule, cameraId, mCameraDeviceNames);
    533 
    534     if (device == nullptr) {
    535         ALOGE("%s: cannot allocate camera device for id %s", __FUNCTION__, cameraId.c_str());
    536         _hidl_cb(Status::INTERNAL_ERROR, nullptr);
    537         return Void();
    538     }
    539 
    540     if (device->isInitFailed()) {
    541         ALOGE("%s: camera device %s init failed!", __FUNCTION__, cameraId.c_str());
    542         device = nullptr;
    543         _hidl_cb(Status::INTERNAL_ERROR, nullptr);
    544         return Void();
    545     }
    546 
    547     _hidl_cb (Status::OK, device);
    548     return Void();
    549 }
    550 
    551 Return<void> LegacyCameraProviderImpl_2_4::getCameraDeviceInterface_V3_x(
    552         const hidl_string& cameraDeviceName,
    553         ICameraProvider::getCameraDeviceInterface_V3_x_cb _hidl_cb)  {
    554     std::string cameraId, deviceVersion;
    555     bool match = matchDeviceName(cameraDeviceName, &deviceVersion, &cameraId);
    556     if (!match) {
    557         _hidl_cb(Status::ILLEGAL_ARGUMENT, nullptr);
    558         return Void();
    559     }
    560 
    561     std::string deviceName(cameraDeviceName.c_str());
    562     ssize_t index = mCameraDeviceNames.indexOf(std::make_pair(cameraId, deviceName));
    563     if (index == NAME_NOT_FOUND) { // Either an illegal name or a device version mismatch
    564         Status status = Status::OK;
    565         ssize_t idx = mCameraIds.indexOf(cameraId);
    566         if (idx == NAME_NOT_FOUND) {
    567             ALOGE("%s: cannot find camera %s!", __FUNCTION__, cameraId.c_str());
    568             status = Status::ILLEGAL_ARGUMENT;
    569         } else { // invalid version
    570             ALOGE("%s: camera device %s does not support version %s!",
    571                     __FUNCTION__, cameraId.c_str(), deviceVersion.c_str());
    572             status = Status::OPERATION_NOT_SUPPORTED;
    573         }
    574         _hidl_cb(status, nullptr);
    575         return Void();
    576     }
    577 
    578     if (mCameraStatusMap.count(cameraId) == 0 ||
    579             mCameraStatusMap[cameraId] != CAMERA_DEVICE_STATUS_PRESENT) {
    580         _hidl_cb(Status::ILLEGAL_ARGUMENT, nullptr);
    581         return Void();
    582     }
    583 
    584     sp<android::hardware::camera::device::V3_2::implementation::CameraDevice> deviceImpl;
    585 
    586     // ICameraDevice 3.4 or upper
    587     if (deviceVersion >= kHAL3_4) {
    588         ALOGV("Constructing v3.4+ camera device");
    589         if (deviceVersion == kHAL3_4) {
    590             deviceImpl = new android::hardware::camera::device::V3_4::implementation::CameraDevice(
    591                     mModule, cameraId, mCameraDeviceNames);
    592         } else if (deviceVersion == kHAL3_5) {
    593             deviceImpl = new android::hardware::camera::device::V3_5::implementation::CameraDevice(
    594                     mModule, cameraId, mCameraDeviceNames);
    595         }
    596         if (deviceImpl == nullptr || deviceImpl->isInitFailed()) {
    597             ALOGE("%s: camera device %s init failed!", __FUNCTION__, cameraId.c_str());
    598             _hidl_cb(Status::INTERNAL_ERROR, nullptr);
    599             return Void();
    600         }
    601         IF_ALOGV() {
    602             deviceImpl->getInterface()->interfaceChain([](
    603                 ::android::hardware::hidl_vec<::android::hardware::hidl_string> interfaceChain) {
    604                     ALOGV("Device interface chain:");
    605                     for (auto iface : interfaceChain) {
    606                         ALOGV("  %s", iface.c_str());
    607                     }
    608                 });
    609         }
    610         _hidl_cb (Status::OK, deviceImpl->getInterface());
    611         return Void();
    612     }
    613 
    614     // ICameraDevice 3.2 and 3.3
    615     // Since some Treble HAL revisions can map to the same legacy HAL version(s), we default
    616     // to the newest possible Treble HAL revision, but allow for override if needed via
    617     // system property.
    618     switch (mPreferredHal3MinorVersion) {
    619         case 2: { // Map legacy camera device v3 HAL to Treble camera device HAL v3.2
    620             ALOGV("Constructing v3.2 camera device");
    621             deviceImpl = new android::hardware::camera::device::V3_2::implementation::CameraDevice(
    622                     mModule, cameraId, mCameraDeviceNames);
    623             if (deviceImpl == nullptr || deviceImpl->isInitFailed()) {
    624                 ALOGE("%s: camera device %s init failed!", __FUNCTION__, cameraId.c_str());
    625                 _hidl_cb(Status::INTERNAL_ERROR, nullptr);
    626                 return Void();
    627             }
    628             break;
    629         }
    630         case 3: { // Map legacy camera device v3 HAL to Treble camera device HAL v3.3
    631             ALOGV("Constructing v3.3 camera device");
    632             deviceImpl = new android::hardware::camera::device::V3_3::implementation::CameraDevice(
    633                     mModule, cameraId, mCameraDeviceNames);
    634             if (deviceImpl == nullptr || deviceImpl->isInitFailed()) {
    635                 ALOGE("%s: camera device %s init failed!", __FUNCTION__, cameraId.c_str());
    636                 _hidl_cb(Status::INTERNAL_ERROR, nullptr);
    637                 return Void();
    638             }
    639             break;
    640         }
    641         default:
    642             ALOGE("%s: Unknown HAL minor version %d!", __FUNCTION__, mPreferredHal3MinorVersion);
    643             _hidl_cb(Status::INTERNAL_ERROR, nullptr);
    644             return Void();
    645     }
    646 
    647     _hidl_cb (Status::OK, deviceImpl->getInterface());
    648     return Void();
    649 }
    650 
    651 } // namespace implementation
    652 }  // namespace V2_4
    653 }  // namespace provider
    654 }  // namespace camera
    655 }  // namespace hardware
    656 }  // namespace android
    657