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