Home | History | Annotate | Download | only in impl
      1 /*
      2  * Copyright (C) 2018 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_NDEBUG 0
     18 #define LOG_TAG "ACameraManagerVendor"
     19 
     20 #include <memory>
     21 #include "ndk_vendor/impl/ACameraManager.h"
     22 #include "ACameraMetadata.h"
     23 #include "ndk_vendor/impl/ACameraDevice.h"
     24 #include "utils.h"
     25 #include <CameraMetadata.h>
     26 #include <camera_metadata_hidden.h>
     27 
     28 #include <utils/Vector.h>
     29 #include <cutils/properties.h>
     30 #include <stdlib.h>
     31 
     32 #include <VendorTagDescriptor.h>
     33 
     34 using namespace android::acam;
     35 
     36 namespace android {
     37 namespace acam {
     38 
     39 using frameworks::cameraservice::service::V2_0::CameraStatusAndId;
     40 using frameworks::cameraservice::common::V2_0::ProviderIdAndVendorTagSections;
     41 using android::hardware::camera::common::V1_0::helper::VendorTagDescriptor;
     42 using android::hardware::camera::common::V1_0::helper::VendorTagDescriptorCache;
     43 
     44 // Static member definitions
     45 const char* CameraManagerGlobal::kCameraIdKey   = "CameraId";
     46 const char* CameraManagerGlobal::kCallbackFpKey = "CallbackFp";
     47 const char* CameraManagerGlobal::kContextKey    = "CallbackContext";
     48 Mutex                CameraManagerGlobal::sLock;
     49 CameraManagerGlobal* CameraManagerGlobal::sInstance = nullptr;
     50 
     51 /**
     52  * The vendor tag descriptor class that takes HIDL vendor tag information as
     53  * input. Not part of vendor available VendorTagDescriptor class because that class is used by
     54  * default HAL implementation code as well.
     55  */
     56 class HidlVendorTagDescriptor : public VendorTagDescriptor {
     57 public:
     58     /**
     59      * Create a VendorTagDescriptor object from the HIDL VendorTagSection
     60      * vector.
     61      *
     62      * Returns OK on success, or a negative error code.
     63      */
     64     static status_t createDescriptorFromHidl(const hidl_vec<VendorTagSection>& vts,
     65                                              /*out*/ sp<VendorTagDescriptor> *descriptor);
     66 };
     67 
     68 status_t HidlVendorTagDescriptor::createDescriptorFromHidl(const hidl_vec<VendorTagSection> &vts,
     69                                                            sp<VendorTagDescriptor> *descriptor) {
     70     int tagCount = 0;
     71 
     72     for (size_t s = 0; s < vts.size(); s++) {
     73         tagCount += vts[s].tags.size();
     74     }
     75 
     76     if (tagCount < 0 || tagCount > INT32_MAX) {
     77         ALOGE("%s: tag count %d from vendor tag sections is invalid.", __FUNCTION__, tagCount);
     78         return BAD_VALUE;
     79     }
     80 
     81     Vector<uint32_t> tagArray;
     82     LOG_ALWAYS_FATAL_IF(tagArray.resize(tagCount) != tagCount,
     83             "%s: too many (%u) vendor tags defined.", __FUNCTION__, tagCount);
     84 
     85     sp<HidlVendorTagDescriptor> desc = new HidlVendorTagDescriptor();
     86     desc->mTagCount = tagCount;
     87 
     88     KeyedVector<uint32_t, String8> tagToSectionMap;
     89 
     90     int idx = 0;
     91     for (size_t s = 0; s < vts.size(); s++) {
     92         const VendorTagSection& section = vts[s];
     93         const char *sectionName = section.sectionName.c_str();
     94         if (sectionName == NULL) {
     95             ALOGE("%s: no section name defined for vendor tag section %zu.", __FUNCTION__, s);
     96             return BAD_VALUE;
     97         }
     98         String8 sectionString(sectionName);
     99         desc->mSections.add(sectionString);
    100 
    101         for (size_t j = 0; j < section.tags.size(); j++) {
    102             uint32_t tag = section.tags[j].tagId;
    103             if (tag < CAMERA_METADATA_VENDOR_TAG_BOUNDARY) {
    104                 ALOGE("%s: vendor tag %d not in vendor tag section.", __FUNCTION__, tag);
    105                 return BAD_VALUE;
    106             }
    107 
    108             tagArray.editItemAt(idx++) = section.tags[j].tagId;
    109 
    110             const char *tagName = section.tags[j].tagName.c_str();
    111             if (tagName == NULL) {
    112                 ALOGE("%s: no tag name defined for vendor tag %d.", __FUNCTION__, tag);
    113                 return BAD_VALUE;
    114             }
    115             desc->mTagToNameMap.add(tag, String8(tagName));
    116             tagToSectionMap.add(tag, sectionString);
    117 
    118             int tagType = (int) section.tags[j].tagType;
    119             if (tagType < 0 || tagType >= NUM_TYPES) {
    120                 ALOGE("%s: tag type %d from vendor ops does not exist.", __FUNCTION__, tagType);
    121                 return BAD_VALUE;
    122             }
    123             desc->mTagToTypeMap.emplace(tag, tagType);
    124         }
    125     }
    126 
    127     for (size_t i = 0; i < tagArray.size(); ++i) {
    128         uint32_t tag = tagArray[i];
    129         String8 sectionString = tagToSectionMap.valueFor(tag);
    130 
    131         // Set up tag to section index map
    132         ssize_t index = desc->mSections.indexOf(sectionString);
    133         LOG_ALWAYS_FATAL_IF(index < 0, "index %zd must be non-negative", index);
    134         desc->mTagToSectionMap.add(tag, static_cast<uint32_t>(index));
    135 
    136         // Set up reverse mapping
    137         ssize_t reverseIndex = -1;
    138         if ((reverseIndex = desc->mReverseMapping.indexOfKey(sectionString)) < 0) {
    139             KeyedVector<String8, uint32_t>* nameMapper = new KeyedVector<String8, uint32_t>();
    140             reverseIndex = desc->mReverseMapping.add(sectionString, nameMapper);
    141         }
    142         desc->mReverseMapping[reverseIndex]->add(desc->mTagToNameMap.valueFor(tag), tag);
    143     }
    144 
    145     *descriptor = std::move(desc);
    146     return OK;
    147 }
    148 
    149 CameraManagerGlobal&
    150 CameraManagerGlobal::getInstance() {
    151     Mutex::Autolock _l(sLock);
    152     CameraManagerGlobal* instance = sInstance;
    153     if (instance == nullptr) {
    154         instance = new CameraManagerGlobal();
    155         sInstance = instance;
    156     }
    157     return *instance;
    158 }
    159 
    160 CameraManagerGlobal::~CameraManagerGlobal() {
    161     // clear sInstance so next getInstance call knows to create a new one
    162     Mutex::Autolock _sl(sLock);
    163     sInstance = nullptr;
    164     Mutex::Autolock _l(mLock);
    165     if (mCameraService != nullptr) {
    166         mCameraService->unlinkToDeath(mDeathNotifier);
    167         mCameraService->removeListener(mCameraServiceListener);
    168     }
    169     mDeathNotifier.clear();
    170     if (mCbLooper != nullptr) {
    171         mCbLooper->unregisterHandler(mHandler->id());
    172         mCbLooper->stop();
    173     }
    174     mCbLooper.clear();
    175     mHandler.clear();
    176     mCameraServiceListener.clear();
    177     mCameraService.clear();
    178 }
    179 
    180 static bool isCameraServiceDisabled() {
    181     char value[PROPERTY_VALUE_MAX];
    182     property_get("config.disable_cameraservice", value, "0");
    183     return (strncmp(value, "0", 2) != 0 && strncasecmp(value, "false", 6) != 0);
    184 }
    185 
    186 bool CameraManagerGlobal::setupVendorTags() {
    187     sp<VendorTagDescriptorCache> tagCache = new VendorTagDescriptorCache();
    188     Status status = Status::NO_ERROR;
    189     std::vector<ProviderIdAndVendorTagSections> providerIdsAndVts;
    190     auto remoteRet = mCameraService->getCameraVendorTagSections([&status, &providerIdsAndVts]
    191                                                                  (Status s,
    192                                                                   auto &IdsAndVts) {
    193                                                          status = s;
    194                                                          providerIdsAndVts = IdsAndVts; });
    195 
    196     if (!remoteRet.isOk() || status != Status::NO_ERROR) {
    197         ALOGE("Failed to retrieve VendorTagSections %s", remoteRet.description().c_str());
    198         return false;
    199     }
    200     // Convert each providers VendorTagSections into a VendorTagDescriptor and
    201     // add it to the cache
    202     for (auto &providerIdAndVts : providerIdsAndVts) {
    203         sp<VendorTagDescriptor> vendorTagDescriptor;
    204         if (HidlVendorTagDescriptor::createDescriptorFromHidl(providerIdAndVts.vendorTagSections,
    205                                                               &vendorTagDescriptor) != OK) {
    206             ALOGE("Failed to convert from Hidl: VendorTagDescriptor");
    207             return false;
    208         }
    209         tagCache->addVendorDescriptor(providerIdAndVts.providerId, vendorTagDescriptor);
    210     }
    211     VendorTagDescriptorCache::setAsGlobalVendorTagCache(tagCache);
    212     return true;
    213 }
    214 
    215 sp<ICameraService> CameraManagerGlobal::getCameraService() {
    216     Mutex::Autolock _l(mLock);
    217     if (mCameraService.get() == nullptr) {
    218         if (isCameraServiceDisabled()) {
    219             return mCameraService;
    220         }
    221 
    222         sp<ICameraService> cameraServiceBinder;
    223         do {
    224             cameraServiceBinder = ICameraService::getService();
    225             if (cameraServiceBinder != nullptr) {
    226                 break;
    227             }
    228             ALOGW("CameraService not published, waiting...");
    229             usleep(kCameraServicePollDelay);
    230         } while(true);
    231         if (mDeathNotifier == nullptr) {
    232             mDeathNotifier = new DeathNotifier(this);
    233         }
    234         cameraServiceBinder->linkToDeath(mDeathNotifier, 0);
    235         mCameraService = cameraServiceBinder;
    236 
    237         // Setup looper thread to perfrom availiability callbacks
    238         if (mCbLooper == nullptr) {
    239             mCbLooper = new ALooper;
    240             mCbLooper->setName("C2N-mgr-looper");
    241             status_t err = mCbLooper->start(
    242                     /*runOnCallingThread*/false,
    243                     /*canCallJava*/       true,
    244                     PRIORITY_DEFAULT);
    245             if (err != OK) {
    246                 ALOGE("%s: Unable to start camera service listener looper: %s (%d)",
    247                         __FUNCTION__, strerror(-err), err);
    248                 mCbLooper.clear();
    249                 return nullptr;
    250             }
    251             if (mHandler == nullptr) {
    252                 mHandler = new CallbackHandler();
    253             }
    254             mCbLooper->registerHandler(mHandler);
    255         }
    256 
    257         // register ICameraServiceListener
    258         if (mCameraServiceListener == nullptr) {
    259             mCameraServiceListener = new CameraServiceListener(this);
    260         }
    261         hidl_vec<CameraStatusAndId> cameraStatuses{};
    262         Status status = Status::NO_ERROR;
    263         auto remoteRet = mCameraService->addListener(mCameraServiceListener,
    264                                                      [&status, &cameraStatuses](Status s,
    265                                                                                 auto &retStatuses) {
    266                                                          status = s;
    267                                                          cameraStatuses = retStatuses;
    268                                                      });
    269         if (!remoteRet.isOk() || status != Status::NO_ERROR) {
    270             ALOGE("Failed to add listener to camera service %s", remoteRet.description().c_str());
    271         }
    272 
    273         // Setup vendor tags
    274         if (!setupVendorTags()) {
    275             ALOGE("Unable to set up vendor tags");
    276             return nullptr;
    277         }
    278 
    279         for (auto& c : cameraStatuses) {
    280             onStatusChangedLocked(c);
    281         }
    282     }
    283     return mCameraService;
    284 }
    285 
    286 void CameraManagerGlobal::DeathNotifier::serviceDied(uint64_t cookie, const wp<IBase> &who) {
    287     (void) cookie;
    288     (void) who;
    289     ALOGE("Camera service binderDied!");
    290     sp<CameraManagerGlobal> cm = mCameraManager.promote();
    291     if (cm != nullptr) {
    292         AutoMutex lock(cm->mLock);
    293         for (auto& pair : cm->mDeviceStatusMap) {
    294             CameraStatusAndId cameraStatusAndId;
    295             cameraStatusAndId.cameraId = pair.first;
    296             cameraStatusAndId.deviceStatus = pair.second;
    297             cm->onStatusChangedLocked(cameraStatusAndId);
    298         }
    299         cm->mCameraService.clear();
    300         // TODO: consider adding re-connect call here?
    301     }
    302 }
    303 
    304 void CameraManagerGlobal::registerAvailabilityCallback(
    305         const ACameraManager_AvailabilityCallbacks *callback) {
    306     Mutex::Autolock _l(mLock);
    307     Callback cb(callback);
    308     auto pair = mCallbacks.insert(cb);
    309     // Send initial callbacks if callback is newly registered
    310     if (pair.second) {
    311         for (auto& pair : mDeviceStatusMap) {
    312             const hidl_string& cameraId = pair.first;
    313             CameraDeviceStatus status = pair.second;
    314 
    315             sp<AMessage> msg = new AMessage(kWhatSendSingleCallback, mHandler);
    316             ACameraManager_AvailabilityCallback cb = isStatusAvailable(status) ?
    317                     callback->onCameraAvailable : callback->onCameraUnavailable;
    318             msg->setPointer(kCallbackFpKey, (void *) cb);
    319             msg->setPointer(kContextKey, callback->context);
    320             msg->setString(kCameraIdKey, AString(cameraId.c_str()));
    321             msg->post();
    322         }
    323     }
    324 }
    325 
    326 void CameraManagerGlobal::unregisterAvailabilityCallback(
    327         const ACameraManager_AvailabilityCallbacks *callback) {
    328     Mutex::Autolock _l(mLock);
    329     Callback cb(callback);
    330     mCallbacks.erase(cb);
    331 }
    332 
    333 void CameraManagerGlobal::getCameraIdList(std::vector<hidl_string>* cameraIds) {
    334     // Ensure that we have initialized/refreshed the list of available devices
    335     auto cs = getCameraService();
    336     Mutex::Autolock _l(mLock);
    337 
    338     for(auto& deviceStatus : mDeviceStatusMap) {
    339         if (deviceStatus.second == CameraDeviceStatus::STATUS_NOT_PRESENT ||
    340                 deviceStatus.second == CameraDeviceStatus::STATUS_ENUMERATING) {
    341             continue;
    342         }
    343         cameraIds->push_back(deviceStatus.first);
    344     }
    345 }
    346 
    347 bool CameraManagerGlobal::validStatus(CameraDeviceStatus status) {
    348     switch (status) {
    349         case CameraDeviceStatus::STATUS_NOT_PRESENT:
    350         case CameraDeviceStatus::STATUS_PRESENT:
    351         case CameraDeviceStatus::STATUS_ENUMERATING:
    352         case CameraDeviceStatus::STATUS_NOT_AVAILABLE:
    353             return true;
    354         default:
    355             return false;
    356     }
    357 }
    358 
    359 bool CameraManagerGlobal::isStatusAvailable(CameraDeviceStatus status) {
    360     switch (status) {
    361         case CameraDeviceStatus::STATUS_PRESENT:
    362             return true;
    363         default:
    364             return false;
    365     }
    366 }
    367 
    368 void CameraManagerGlobal::CallbackHandler::onMessageReceived(
    369         const sp<AMessage> &msg) {
    370     switch (msg->what()) {
    371         case kWhatSendSingleCallback:
    372         {
    373             ACameraManager_AvailabilityCallback cb;
    374             void* context;
    375             AString cameraId;
    376             bool found = msg->findPointer(kCallbackFpKey, (void**) &cb);
    377             if (!found) {
    378                 ALOGE("%s: Cannot find camera callback fp!", __FUNCTION__);
    379                 return;
    380             }
    381             found = msg->findPointer(kContextKey, &context);
    382             if (!found) {
    383                 ALOGE("%s: Cannot find callback context!", __FUNCTION__);
    384                 return;
    385             }
    386             found = msg->findString(kCameraIdKey, &cameraId);
    387             if (!found) {
    388                 ALOGE("%s: Cannot find camera ID!", __FUNCTION__);
    389                 return;
    390             }
    391             (*cb)(context, cameraId.c_str());
    392             break;
    393         }
    394         default:
    395             ALOGE("%s: unknown message type %d", __FUNCTION__, msg->what());
    396             break;
    397     }
    398 }
    399 
    400 hardware::Return<void> CameraManagerGlobal::CameraServiceListener::onStatusChanged(
    401         const CameraStatusAndId &statusAndId) {
    402     sp<CameraManagerGlobal> cm = mCameraManager.promote();
    403     if (cm != nullptr) {
    404         cm->onStatusChanged(statusAndId);
    405     } else {
    406         ALOGE("Cannot deliver status change. Global camera manager died");
    407     }
    408     return Void();
    409 }
    410 
    411 void CameraManagerGlobal::onStatusChanged(
    412         const CameraStatusAndId &statusAndId) {
    413     Mutex::Autolock _l(mLock);
    414     onStatusChangedLocked(statusAndId);
    415 }
    416 
    417 void CameraManagerGlobal::onStatusChangedLocked(
    418         const CameraStatusAndId &statusAndId) {
    419     hidl_string cameraId = statusAndId.cameraId;
    420     CameraDeviceStatus status = statusAndId.deviceStatus;
    421     if (!validStatus(status)) {
    422         ALOGE("%s: Invalid status %d", __FUNCTION__, status);
    423         return;
    424     }
    425 
    426     bool firstStatus = (mDeviceStatusMap.count(cameraId) == 0);
    427     CameraDeviceStatus oldStatus = firstStatus ?
    428             status : // first status
    429             mDeviceStatusMap[cameraId];
    430 
    431     if (!firstStatus &&
    432             isStatusAvailable(status) == isStatusAvailable(oldStatus)) {
    433         // No status update. No need to send callback
    434         return;
    435     }
    436 
    437     // Iterate through all registered callbacks
    438     mDeviceStatusMap[cameraId] = status;
    439     for (auto cb : mCallbacks) {
    440         sp<AMessage> msg = new AMessage(kWhatSendSingleCallback, mHandler);
    441         ACameraManager_AvailabilityCallback cbFp = isStatusAvailable(status) ?
    442                 cb.mAvailable : cb.mUnavailable;
    443         msg->setPointer(kCallbackFpKey, (void *) cbFp);
    444         msg->setPointer(kContextKey, cb.mContext);
    445         msg->setString(kCameraIdKey, AString(cameraId.c_str()));
    446         msg->post();
    447     }
    448     if (status == CameraDeviceStatus::STATUS_NOT_PRESENT) {
    449         mDeviceStatusMap.erase(cameraId);
    450     }
    451 }
    452 
    453 } // namespace acam
    454 } // namespace android
    455 
    456 /**
    457  * ACameraManger Implementation
    458  */
    459 camera_status_t
    460 ACameraManager::getCameraIdList(ACameraIdList** cameraIdList) {
    461     Mutex::Autolock _l(mLock);
    462 
    463     std::vector<hidl_string> idList;
    464     CameraManagerGlobal::getInstance().getCameraIdList(&idList);
    465 
    466     int numCameras = idList.size();
    467     ACameraIdList *out = new ACameraIdList;
    468     if (!out) {
    469         ALOGE("Allocate memory for ACameraIdList failed!");
    470         return ACAMERA_ERROR_NOT_ENOUGH_MEMORY;
    471     }
    472     out->numCameras = numCameras;
    473     out->cameraIds = new const char*[numCameras];
    474     if (!out->cameraIds) {
    475         ALOGE("Allocate memory for ACameraIdList failed!");
    476         deleteCameraIdList(out);
    477         return ACAMERA_ERROR_NOT_ENOUGH_MEMORY;
    478     }
    479     for (int i = 0; i < numCameras; i++) {
    480         const char* src = idList[i].c_str();
    481         size_t dstSize = strlen(src) + 1;
    482         char* dst = new char[dstSize];
    483         if (!dst) {
    484             ALOGE("Allocate memory for ACameraIdList failed!");
    485             deleteCameraIdList(out);
    486             return ACAMERA_ERROR_NOT_ENOUGH_MEMORY;
    487         }
    488         strlcpy(dst, src, dstSize);
    489         out->cameraIds[i] = dst;
    490     }
    491     *cameraIdList = out;
    492     return ACAMERA_OK;
    493 }
    494 
    495 void
    496 ACameraManager::deleteCameraIdList(ACameraIdList* cameraIdList) {
    497     if (cameraIdList != nullptr) {
    498         if (cameraIdList->cameraIds != nullptr) {
    499             for (int i = 0; i < cameraIdList->numCameras; i ++) {
    500                 if (cameraIdList->cameraIds[i] != nullptr) {
    501                     delete[] cameraIdList->cameraIds[i];
    502                 }
    503             }
    504             delete[] cameraIdList->cameraIds;
    505         }
    506         delete cameraIdList;
    507     }
    508 }
    509 
    510 camera_status_t ACameraManager::getCameraCharacteristics(
    511         const char *cameraIdStr, sp<ACameraMetadata> *characteristics) {
    512     Mutex::Autolock _l(mLock);
    513 
    514     sp<ICameraService> cs = CameraManagerGlobal::getInstance().getCameraService();
    515     if (cs == nullptr) {
    516         ALOGE("%s: Cannot reach camera service!", __FUNCTION__);
    517         return ACAMERA_ERROR_CAMERA_DISCONNECTED;
    518     }
    519     CameraMetadata rawMetadata;
    520     Status status = Status::NO_ERROR;
    521     auto serviceRet =
    522         cs->getCameraCharacteristics(cameraIdStr,
    523                                      [&status, &rawMetadata] (auto s ,
    524                                                               const hidl_vec<uint8_t> &metadata) {
    525                                           status = s;
    526                                           if (status == Status::NO_ERROR) {
    527                                               utils::convertFromHidlCloned(metadata, &rawMetadata);
    528                                           }
    529                                      });
    530     if (!serviceRet.isOk() || status != Status::NO_ERROR) {
    531         ALOGE("Get camera characteristics from camera service failed");
    532         return ACAMERA_ERROR_UNKNOWN; // should not reach here
    533     }
    534 
    535     *characteristics = new ACameraMetadata(
    536             rawMetadata.release(), ACameraMetadata::ACM_CHARACTERISTICS);
    537     return ACAMERA_OK;
    538 }
    539 
    540 camera_status_t
    541 ACameraManager::openCamera(
    542         const char* cameraId,
    543         ACameraDevice_StateCallbacks* callback,
    544         /*out*/ACameraDevice** outDevice) {
    545     sp<ACameraMetadata> rawChars;
    546     camera_status_t ret = getCameraCharacteristics(cameraId, &rawChars);
    547     Mutex::Autolock _l(mLock);
    548     if (ret != ACAMERA_OK) {
    549         ALOGE("%s: cannot get camera characteristics for camera %s. err %d",
    550                 __FUNCTION__, cameraId, ret);
    551         return ACAMERA_ERROR_INVALID_PARAMETER;
    552     }
    553 
    554     ACameraDevice* device = new ACameraDevice(cameraId, callback, std::move(rawChars));
    555 
    556     sp<ICameraService> cs = CameraManagerGlobal::getInstance().getCameraService();
    557     if (cs == nullptr) {
    558         ALOGE("%s: Cannot reach camera service!", __FUNCTION__);
    559         delete device;
    560         return ACAMERA_ERROR_CAMERA_DISCONNECTED;
    561     }
    562 
    563     sp<ICameraDeviceCallback> callbacks = device->getServiceCallback();
    564     sp<ICameraDeviceUser> deviceRemote;
    565 
    566     // No way to get package name from native.
    567     // Send a zero length package name and let camera service figure it out from UID
    568     Status status = Status::NO_ERROR;
    569     auto serviceRet = cs->connectDevice(
    570             callbacks, cameraId, [&status, &deviceRemote](auto s, auto &device) {
    571                                      status = s;
    572                                      deviceRemote = device;
    573                                  });
    574 
    575     if (!serviceRet.isOk() || status != Status::NO_ERROR) {
    576         ALOGE("%s: connect camera device failed", __FUNCTION__);
    577         // TODO: Convert serviceRet to camera_status_t
    578         delete device;
    579         return ACAMERA_ERROR_UNKNOWN;
    580     }
    581     if (deviceRemote == nullptr) {
    582         ALOGE("%s: connect camera device failed! remote device is null", __FUNCTION__);
    583         delete device;
    584         return ACAMERA_ERROR_CAMERA_DISCONNECTED;
    585     }
    586     device->setRemoteDevice(deviceRemote);
    587     device->setDeviceMetadataQueues();
    588     *outDevice = device;
    589     return ACAMERA_OK;
    590 }
    591 
    592 camera_status_t
    593 ACameraManager::getTagFromName(const char *cameraId, const char *name, uint32_t *tag) {
    594     sp<ACameraMetadata> rawChars;
    595     camera_status_t ret = getCameraCharacteristics(cameraId, &rawChars);
    596     if (ret != ACAMERA_OK) {
    597         ALOGE("%s, Cannot retrieve camera characteristics for camera id %s", __FUNCTION__,
    598                 cameraId);
    599         return ACAMERA_ERROR_METADATA_NOT_FOUND;
    600     }
    601     const CameraMetadata& metadata = rawChars->getInternalData();
    602     const camera_metadata_t *rawMetadata = metadata.getAndLock();
    603     metadata_vendor_id_t vendorTagId = get_camera_metadata_vendor_id(rawMetadata);
    604     metadata.unlock(rawMetadata);
    605     sp<VendorTagDescriptorCache> vtCache = VendorTagDescriptorCache::getGlobalVendorTagCache();
    606     sp<VendorTagDescriptor> vTags = nullptr;
    607     vtCache->getVendorTagDescriptor(vendorTagId, &vTags);
    608     status_t status= metadata.getTagFromName(name, vTags.get(), tag);
    609     return status == OK ? ACAMERA_OK : ACAMERA_ERROR_METADATA_NOT_FOUND;
    610 }
    611 
    612 ACameraManager::~ACameraManager() {
    613 
    614 }
    615