• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
createDescriptorFromHidl(const hidl_vec<VendorTagSection> & vts,sp<VendorTagDescriptor> * descriptor)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&
getInstance()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 
~CameraManagerGlobal()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 
isCameraServiceDisabled()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 
setupVendorTags()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 
getCameraService()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 
serviceDied(uint64_t cookie,const wp<IBase> & who)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 
registerAvailabilityCallback(const ACameraManager_AvailabilityCallbacks * callback)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 
unregisterAvailabilityCallback(const ACameraManager_AvailabilityCallbacks * callback)326 void CameraManagerGlobal::unregisterAvailabilityCallback(
327         const ACameraManager_AvailabilityCallbacks *callback) {
328     Mutex::Autolock _l(mLock);
329     Callback cb(callback);
330     mCallbacks.erase(cb);
331 }
332 
getCameraIdList(std::vector<hidl_string> * cameraIds)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 
validStatus(CameraDeviceStatus status)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 
isStatusAvailable(CameraDeviceStatus status)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 
onMessageReceived(const sp<AMessage> & msg)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 
onStatusChanged(const CameraStatusAndId & statusAndId)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 
onStatusChanged(const CameraStatusAndId & statusAndId)411 void CameraManagerGlobal::onStatusChanged(
412         const CameraStatusAndId &statusAndId) {
413     Mutex::Autolock _l(mLock);
414     onStatusChangedLocked(statusAndId);
415 }
416 
onStatusChangedLocked(const CameraStatusAndId & statusAndId)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
getCameraIdList(ACameraIdList ** cameraIdList)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
deleteCameraIdList(ACameraIdList * cameraIdList)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 
getCameraCharacteristics(const char * cameraIdStr,sp<ACameraMetadata> * characteristics)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
openCamera(const char * cameraId,ACameraDevice_StateCallbacks * callback,ACameraDevice ** outDevice)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
getTagFromName(const char * cameraId,const char * name,uint32_t * tag)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 
~ACameraManager()612 ACameraManager::~ACameraManager() {
613 
614 }
615