1 /*
2 * Copyright (C) 2022 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 #include "AidlProviderInfo.h"
17 #include "common/HalConversionsTemplated.h"
18 #include "common/CameraProviderInfoTemplated.h"
19
20 #include <cutils/properties.h>
21
22 #include <aidlcommonsupport/NativeHandle.h>
23 #include <android/binder_manager.h>
24 #include <android/hardware/ICameraService.h>
25 #include <camera_metadata_hidden.h>
26
27 #include "device3/ZoomRatioMapper.h"
28 #include <utils/SessionConfigurationUtils.h>
29 #include <utils/Trace.h>
30
31 namespace {
32 const bool kEnableLazyHal(property_get_bool("ro.camera.enableLazyHal", false));
33 } // anonymous namespace
34
35 namespace android {
36
37 namespace SessionConfigurationUtils = ::android::camera3::SessionConfigurationUtils;
38
39 using namespace aidl::android::hardware;
40 using namespace hardware::camera;
41 using hardware::camera2::utils::CameraIdAndSessionConfiguration;
42 using hardware::ICameraService;
43
44 using HalDeviceStatusType = aidl::android::hardware::camera::common::CameraDeviceStatus;
45 using ICameraProvider = aidl::android::hardware::camera::provider::ICameraProvider;
46 using StatusListener = CameraProviderManager::StatusListener;
47
mapExceptionCodeToStatusT(binder_exception_t binderException)48 static status_t mapExceptionCodeToStatusT(binder_exception_t binderException) {
49 switch (binderException) {
50 case EX_NONE:
51 return OK;
52 case EX_ILLEGAL_ARGUMENT:
53 case EX_NULL_POINTER:
54 case EX_BAD_PARCELABLE:
55 case EX_ILLEGAL_STATE:
56 return BAD_VALUE;
57 case EX_UNSUPPORTED_OPERATION:
58 return INVALID_OPERATION;
59 case EX_TRANSACTION_FAILED:
60 return DEAD_OBJECT;
61 default:
62 return UNKNOWN_ERROR;
63 }
64 }
65
mapToStatusT(const ndk::ScopedAStatus & s)66 status_t AidlProviderInfo::mapToStatusT(const ndk::ScopedAStatus& s) {
67 using Status = aidl::android::hardware::camera::common::Status;
68 auto exceptionCode = s.getExceptionCode();
69 if (exceptionCode != EX_SERVICE_SPECIFIC) {
70 return mapExceptionCodeToStatusT(exceptionCode);
71 }
72 Status st = static_cast<Status>(s.getServiceSpecificError());
73 switch (st) {
74 case Status::OK:
75 return OK;
76 case Status::ILLEGAL_ARGUMENT:
77 return BAD_VALUE;
78 case Status::CAMERA_IN_USE:
79 return -EBUSY;
80 case Status::MAX_CAMERAS_IN_USE:
81 return -EUSERS;
82 case Status::OPERATION_NOT_SUPPORTED:
83 return INVALID_OPERATION;
84 case Status::CAMERA_DISCONNECTED:
85 return DEAD_OBJECT;
86 case Status::INTERNAL_ERROR:
87 return INVALID_OPERATION;
88 }
89 ALOGW("Unexpected HAL status code %d", static_cast<int>(st));
90 return INVALID_OPERATION;
91 }
92
AidlProviderInfo(const std::string & providerName,const std::string & providerInstance,CameraProviderManager * manager)93 AidlProviderInfo::AidlProviderInfo(
94 const std::string &providerName,
95 const std::string &providerInstance,
96 CameraProviderManager *manager) :
97 CameraProviderManager::ProviderInfo(providerName, providerInstance, manager) {}
98
initializeAidlProvider(std::shared_ptr<ICameraProvider> & interface,int64_t currentDeviceState)99 status_t AidlProviderInfo::initializeAidlProvider(
100 std::shared_ptr<ICameraProvider>& interface, int64_t currentDeviceState) {
101
102 status_t res = parseProviderName(mProviderName, &mType, &mId);
103 if (res != OK) {
104 ALOGE("%s: Invalid provider name, ignoring", __FUNCTION__);
105 return BAD_VALUE;
106 }
107 ALOGI("Connecting to new camera provider: %s, isRemote? %d",
108 mProviderName.c_str(), interface->isRemote());
109
110 // cameraDeviceStatusChange callbacks may be called (and causing new devices added)
111 // before setCallback returns
112 mCallbacks =
113 ndk::SharedRefBase::make<AidlProviderCallbacks>(this);
114 ndk::ScopedAStatus status =
115 interface->setCallback(mCallbacks);
116 if (!status.isOk()) {
117 ALOGE("%s: Transaction error setting up callbacks with camera provider '%s': %s",
118 __FUNCTION__, mProviderName.c_str(), status.getMessage());
119 return mapToStatusT(status);
120 }
121
122 mDeathRecipient = ndk::ScopedAIBinder_DeathRecipient(AIBinder_DeathRecipient_new(binderDied));
123 auto link = AIBinder_linkToDeath(interface->asBinder().get(), mDeathRecipient.get(), this);
124 if (link != STATUS_OK) {
125 ALOGW("%s: Unable to link to provider '%s' death notifications",
126 __FUNCTION__, mProviderName.c_str());
127 return DEAD_OBJECT;
128 }
129
130 if (!kEnableLazyHal) {
131 // Save HAL reference indefinitely
132 mSavedInterface = interface;
133 } else {
134 mActiveInterface = interface;
135 }
136
137 ALOGV("%s: Setting device state for %s: 0x%" PRIx64,
138 __FUNCTION__, mProviderName.c_str(), mDeviceState);
139 notifyDeviceStateChange(currentDeviceState);
140
141 res = setUpVendorTags();
142 if (res != OK) {
143 ALOGE("%s: Unable to set up vendor tags from provider '%s'",
144 __FUNCTION__, mProviderName.c_str());
145 return res;
146 }
147
148 // Get initial list of camera devices, if any
149 std::vector<std::string> devices;
150 std::vector<std::string> retDevices;
151 status = interface->getCameraIdList(&retDevices);
152 if (!status.isOk()) {
153 ALOGE("%s: Transaction error in getting camera ID list from provider '%s': %s",
154 __FUNCTION__, mProviderName.c_str(), status.getMessage());
155 return mapToStatusT(status);
156 }
157
158 for (auto& name : retDevices) {
159 uint16_t major, minor;
160 std::string type, id;
161 status_t res = parseDeviceName(name, &major, &minor, &type, &id);
162 if (res != OK) {
163 ALOGE("%s: Error parsing deviceName: %s: %d", __FUNCTION__, name.c_str(), res);
164 return res;
165 } else {
166 devices.push_back(name);
167 mProviderPublicCameraIds.push_back(id);
168 }
169 }
170
171 // Get list of concurrent streaming camera device combinations
172 res = getConcurrentCameraIdsInternalLocked(interface);
173 if (res != OK) {
174 return res;
175 }
176
177 mSetTorchModeSupported = true;
178
179 mIsRemote = interface->isRemote();
180
181 initializeProviderInfoCommon(devices);
182 return OK;
183 }
184
binderDied(void * cookie)185 void AidlProviderInfo::binderDied(void *cookie) {
186 AidlProviderInfo *provider = reinterpret_cast<AidlProviderInfo *>(cookie);
187 ALOGI("Camera provider '%s' has died; removing it", provider->mProviderInstance.c_str());
188 provider->mManager->removeProvider(provider->mProviderInstance);
189 }
190
setUpVendorTags()191 status_t AidlProviderInfo::setUpVendorTags() {
192 if (mVendorTagDescriptor != nullptr)
193 return OK;
194
195 std::vector<camera::common::VendorTagSection> vts;
196 ::ndk::ScopedAStatus status;
197 const std::shared_ptr<ICameraProvider> interface = startProviderInterface();
198 if (interface == nullptr) {
199 return DEAD_OBJECT;
200 }
201 status = interface->getVendorTags(&vts);
202 if (!status.isOk()) {
203 ALOGE("%s: Transaction error getting vendor tags from provider '%s': %s",
204 __FUNCTION__, mProviderName.c_str(), status.getMessage());
205 return mapToStatusT(status);
206 }
207
208 // Read all vendor tag definitions into a descriptor
209 status_t res;
210 if ((res =
211 IdlVendorTagDescriptor::
212 createDescriptorFromIdl<std::vector<camera::common::VendorTagSection>,
213 camera::common::VendorTagSection>(vts, /*out*/mVendorTagDescriptor))
214 != OK) {
215 ALOGE("%s: Could not generate descriptor from vendor tag operations,"
216 "received error %s (%d). Camera clients will not be able to use"
217 "vendor tags", __FUNCTION__, strerror(res), res);
218 return res;
219 }
220
221 return OK;
222 }
223
notifyDeviceStateChange(int64_t newDeviceState)224 status_t AidlProviderInfo::notifyDeviceStateChange(int64_t newDeviceState) {
225
226 mDeviceState = newDeviceState;
227 // Check if the provider is currently active - not going to start it up for this notification
228 auto interface = mSavedInterface != nullptr ? mSavedInterface : mActiveInterface.lock();
229 if (interface != nullptr) {
230 // Send current device state
231 interface->notifyDeviceStateChange(mDeviceState);
232 }
233 return OK;
234 }
235
successfullyStartedProviderInterface()236 bool AidlProviderInfo::successfullyStartedProviderInterface() {
237 return startProviderInterface() != nullptr;
238 }
239
240 std::shared_ptr<camera::device::ICameraDevice>
startDeviceInterface(const std::string & name)241 AidlProviderInfo::startDeviceInterface(const std::string &name) {
242 ::ndk::ScopedAStatus status;
243 std::shared_ptr<camera::device::ICameraDevice> cameraInterface;
244 const std::shared_ptr<ICameraProvider> interface = startProviderInterface();
245 if (interface == nullptr) {
246 return nullptr;
247 }
248 status = interface->getCameraDeviceInterface(name, &cameraInterface);
249 if (!status.isOk()) {
250 ALOGE("%s: Transaction error trying to obtain interface for camera device %s: %s",
251 __FUNCTION__, name.c_str(), status.getMessage());
252 return nullptr;
253 }
254 return cameraInterface;
255 }
256
startProviderInterface()257 const std::shared_ptr<ICameraProvider> AidlProviderInfo::startProviderInterface() {
258 ATRACE_CALL();
259 ALOGV("Request to start camera provider: %s", mProviderName.c_str());
260 if (mSavedInterface != nullptr) {
261 return mSavedInterface;
262 }
263 if (!kEnableLazyHal) {
264 ALOGE("Bad provider state! Should not be here on a non-lazy HAL!");
265 return nullptr;
266 }
267
268 auto interface = mActiveInterface.lock();
269 if (interface == nullptr) {
270 // Try to get service without starting
271 interface =
272 ICameraProvider::fromBinder(
273 ndk::SpAIBinder(AServiceManager_checkService(mProviderName.c_str())));
274 if (interface == nullptr) {
275 ALOGV("Camera provider actually needs restart, calling getService(%s)",
276 mProviderName.c_str());
277 interface =
278 ICameraProvider::fromBinder(
279 ndk::SpAIBinder(
280 AServiceManager_getService(mProviderName.c_str())));
281
282 // Set all devices as ENUMERATING, provider should update status
283 // to PRESENT after initializing.
284 // This avoids failing getCameraDeviceInterface_V3_x before devices
285 // are ready.
286 for (auto& device : mDevices) {
287 device->mIsDeviceAvailable = false;
288 }
289
290 interface->setCallback(mCallbacks);
291 auto link = AIBinder_linkToDeath(interface->asBinder().get(), mDeathRecipient.get(),
292 this);
293 if (link != STATUS_OK) {
294 ALOGW("%s: Unable to link to provider '%s' death notifications",
295 __FUNCTION__, mProviderName.c_str());
296 mManager->removeProvider(mProviderName);
297 return nullptr;
298 }
299
300 // Send current device state
301 interface->notifyDeviceStateChange(mDeviceState);
302 }
303 mActiveInterface = interface;
304 } else {
305 ALOGV("Camera provider (%s) already in use. Re-using instance.",
306 mProviderName.c_str());
307 }
308
309 return interface;
310 }
311
cameraDeviceStatusChange(const std::string & cameraDeviceName,HalDeviceStatusType newStatus)312 ::ndk::ScopedAStatus AidlProviderInfo::AidlProviderCallbacks::cameraDeviceStatusChange(
313 const std::string& cameraDeviceName,
314 HalDeviceStatusType newStatus) {
315 sp<AidlProviderInfo> parent = mParent.promote();
316 if (parent == nullptr) {
317 ALOGE("%s: Parent provider not alive", __FUNCTION__);
318 return ::ndk::ScopedAStatus::ok();
319 }
320 return parent->cameraDeviceStatusChange(cameraDeviceName, newStatus);
321 }
322
torchModeStatusChange(const std::string & cameraDeviceName,aidl::android::hardware::camera::common::TorchModeStatus newStatus)323 ::ndk::ScopedAStatus AidlProviderInfo::AidlProviderCallbacks::torchModeStatusChange(
324 const std::string& cameraDeviceName,
325 aidl::android::hardware::camera::common::TorchModeStatus newStatus) {
326 sp<AidlProviderInfo> parent = mParent.promote();
327 if (parent == nullptr) {
328 ALOGE("%s: Parent provider not alive", __FUNCTION__);
329 return ::ndk::ScopedAStatus::ok();
330 }
331 return parent->torchModeStatusChange(cameraDeviceName, newStatus);
332
333 };
334
physicalCameraDeviceStatusChange(const std::string & cameraDeviceName,const std::string & physicalCameraDeviceName,HalDeviceStatusType newStatus)335 ::ndk::ScopedAStatus AidlProviderInfo::AidlProviderCallbacks::physicalCameraDeviceStatusChange(
336 const std::string& cameraDeviceName,
337 const std::string& physicalCameraDeviceName,
338 HalDeviceStatusType newStatus) {
339 sp<AidlProviderInfo> parent = mParent.promote();
340 if (parent == nullptr) {
341 ALOGE("%s: Parent provider not alive", __FUNCTION__);
342 return ::ndk::ScopedAStatus::ok();
343 }
344 return parent->physicalCameraDeviceStatusChange(cameraDeviceName, physicalCameraDeviceName,
345 newStatus);
346 };
347
cameraDeviceStatusChange(const std::string & cameraDeviceName,HalDeviceStatusType newStatus)348 ::ndk::ScopedAStatus AidlProviderInfo::cameraDeviceStatusChange(const std::string& cameraDeviceName,
349 HalDeviceStatusType newStatus) {
350 cameraDeviceStatusChangeInternal(cameraDeviceName, HalToFrameworkCameraDeviceStatus(newStatus));
351 return ::ndk::ScopedAStatus::ok();
352 }
353
torchModeStatusChange(const std::string & cameraDeviceName,aidl::android::hardware::camera::common::TorchModeStatus newStatus)354 ::ndk::ScopedAStatus AidlProviderInfo::torchModeStatusChange(const std::string& cameraDeviceName,
355 aidl::android::hardware::camera::common::TorchModeStatus newStatus) {
356 torchModeStatusChangeInternal(cameraDeviceName, HalToFrameworkTorchModeStatus(newStatus));
357 return ::ndk::ScopedAStatus::ok();
358 };
359
physicalCameraDeviceStatusChange(const std::string & cameraDeviceName,const std::string & physicalCameraDeviceName,HalDeviceStatusType newStatus)360 ::ndk::ScopedAStatus AidlProviderInfo::physicalCameraDeviceStatusChange(
361 const std::string& cameraDeviceName,
362 const std::string& physicalCameraDeviceName,
363 HalDeviceStatusType newStatus) {
364 physicalCameraDeviceStatusChangeInternal(cameraDeviceName, physicalCameraDeviceName,
365 HalToFrameworkCameraDeviceStatus(newStatus));
366 return ::ndk::ScopedAStatus::ok();
367 };
368
369 std::unique_ptr<CameraProviderManager::ProviderInfo::DeviceInfo>
initializeDeviceInfo(const std::string & name,const metadata_vendor_id_t tagId,const std::string & id,uint16_t minorVersion)370 AidlProviderInfo::initializeDeviceInfo(
371 const std::string &name, const metadata_vendor_id_t tagId,
372 const std::string &id, uint16_t minorVersion) {
373 ::ndk::ScopedAStatus status;
374
375 auto cameraInterface = startDeviceInterface(name);
376 if (cameraInterface == nullptr) return nullptr;
377
378 camera::common::CameraResourceCost resourceCost;
379 status = cameraInterface->getResourceCost(&resourceCost);
380 if (!status.isOk()) {
381 ALOGE("%s: Unable to obtain resource costs for camera device %s: %s", __FUNCTION__,
382 name.c_str(), status.getMessage());
383 return nullptr;
384 }
385
386 for (auto& conflictName : resourceCost.conflictingDevices) {
387 uint16_t major, minor;
388 std::string type, id;
389 status_t res = parseDeviceName(conflictName, &major, &minor, &type, &id);
390 if (res != OK) {
391 ALOGE("%s: Failed to parse conflicting device %s", __FUNCTION__, conflictName.c_str());
392 return nullptr;
393 }
394 conflictName = id;
395 }
396
397 return std::unique_ptr<DeviceInfo3>(
398 new AidlDeviceInfo3(name, tagId, id, minorVersion, HalToFrameworkResourceCost(resourceCost),
399 this, mProviderPublicCameraIds, cameraInterface));
400 }
401
reCacheConcurrentStreamingCameraIdsLocked()402 status_t AidlProviderInfo::reCacheConcurrentStreamingCameraIdsLocked() {
403
404 // Check if the provider is currently active - not going to start it up for this notification
405 auto interface = mSavedInterface != nullptr ? mSavedInterface : mActiveInterface.lock();
406 if (interface == nullptr) {
407 ALOGE("%s: camera provider interface for %s is not valid", __FUNCTION__,
408 mProviderName.c_str());
409 return INVALID_OPERATION;
410 }
411
412 return getConcurrentCameraIdsInternalLocked(interface);
413 }
414
getConcurrentCameraIdsInternalLocked(std::shared_ptr<ICameraProvider> & interface)415 status_t AidlProviderInfo::getConcurrentCameraIdsInternalLocked(
416 std::shared_ptr<ICameraProvider> &interface) {
417 if (interface == nullptr) {
418 ALOGE("%s: null interface provided", __FUNCTION__);
419 return BAD_VALUE;
420 }
421
422 std::vector<aidl::android::hardware::camera::provider::ConcurrentCameraIdCombination> combs;
423 ::ndk::ScopedAStatus status = interface->getConcurrentCameraIds(&combs);
424
425 if (!status.isOk()) {
426 ALOGE("%s: Transaction error in getting concurrent camera ID list from provider '%s'",
427 __FUNCTION__, mProviderName.c_str());
428 return mapToStatusT(status);
429 }
430 mConcurrentCameraIdCombinations.clear();
431 for (const auto& combination : combs) {
432 std::unordered_set<std::string> deviceIds;
433 for (const auto &cameraDeviceId : combination.combination) {
434 deviceIds.insert(cameraDeviceId.c_str());
435 }
436 mConcurrentCameraIdCombinations.push_back(std::move(deviceIds));
437 }
438
439 return OK;
440 }
441
AidlDeviceInfo3(const std::string & name,const metadata_vendor_id_t tagId,const std::string & id,uint16_t minorVersion,const CameraResourceCost & resourceCost,sp<CameraProviderManager::ProviderInfo> parentProvider,const std::vector<std::string> & publicCameraIds,std::shared_ptr<aidl::android::hardware::camera::device::ICameraDevice> interface)442 AidlProviderInfo::AidlDeviceInfo3::AidlDeviceInfo3(
443 const std::string& name,
444 const metadata_vendor_id_t tagId,
445 const std::string &id, uint16_t minorVersion,
446 const CameraResourceCost& resourceCost,
447 sp<CameraProviderManager::ProviderInfo> parentProvider,
448 const std::vector<std::string>& publicCameraIds,
449 std::shared_ptr<aidl::android::hardware::camera::device::ICameraDevice> interface) :
450 DeviceInfo3(name, tagId, id, minorVersion, resourceCost, parentProvider, publicCameraIds) {
451
452 // Get camera characteristics and initialize flash unit availability
453 aidl::android::hardware::camera::device::CameraMetadata chars;
454 ::ndk::ScopedAStatus status = interface->getCameraCharacteristics(&chars);
455 std::vector<uint8_t> &metadata = chars.metadata;
456 camera_metadata_t *buffer = reinterpret_cast<camera_metadata_t*>(metadata.data());
457 size_t expectedSize = metadata.size();
458 int resV = validate_camera_metadata_structure(buffer, &expectedSize);
459 if (resV == OK || resV == CAMERA_METADATA_VALIDATION_SHIFTED) {
460 set_camera_metadata_vendor_id(buffer, mProviderTagid);
461 mCameraCharacteristics = buffer;
462 } else {
463 ALOGE("%s: Malformed camera metadata received from HAL", __FUNCTION__);
464 return;
465 }
466
467 if (!status.isOk()) {
468 ALOGE("%s: Transaction error getting camera characteristics for device %s"
469 " to check for a flash unit: %s", __FUNCTION__, id.c_str(),
470 status.getMessage());
471 return;
472 }
473
474 if (mCameraCharacteristics.exists(ANDROID_INFO_DEVICE_STATE_ORIENTATIONS)) {
475 const auto &stateMap = mCameraCharacteristics.find(ANDROID_INFO_DEVICE_STATE_ORIENTATIONS);
476 if ((stateMap.count > 0) && ((stateMap.count % 2) == 0)) {
477 for (size_t i = 0; i < stateMap.count; i += 2) {
478 mDeviceStateOrientationMap.emplace(stateMap.data.i64[i], stateMap.data.i64[i+1]);
479 }
480 } else {
481 ALOGW("%s: Invalid ANDROID_INFO_DEVICE_STATE_ORIENTATIONS map size: %zu", __FUNCTION__,
482 stateMap.count);
483 }
484 }
485
486 mSystemCameraKind = getSystemCameraKind();
487
488 status_t res = fixupMonochromeTags();
489 if (OK != res) {
490 ALOGE("%s: Unable to fix up monochrome tags based for older HAL version: %s (%d)",
491 __FUNCTION__, strerror(-res), res);
492 return;
493 }
494 auto stat = addDynamicDepthTags();
495 if (OK != stat) {
496 ALOGE("%s: Failed appending dynamic depth tags: %s (%d)", __FUNCTION__, strerror(-stat),
497 stat);
498 }
499 res = deriveHeicTags();
500 if (OK != res) {
501 ALOGE("%s: Unable to derive HEIC tags based on camera and media capabilities: %s (%d)",
502 __FUNCTION__, strerror(-res), res);
503 }
504
505 if (camera3::SessionConfigurationUtils::isUltraHighResolutionSensor(mCameraCharacteristics)) {
506 status_t status = addDynamicDepthTags(/*maxResolution*/true);
507 if (OK != status) {
508 ALOGE("%s: Failed appending dynamic depth tags for maximum resolution mode: %s (%d)",
509 __FUNCTION__, strerror(-status), status);
510 }
511
512 status = deriveHeicTags(/*maxResolution*/true);
513 if (OK != status) {
514 ALOGE("%s: Unable to derive HEIC tags based on camera and media capabilities for"
515 "maximum resolution mode: %s (%d)", __FUNCTION__, strerror(-status), status);
516 }
517 }
518
519 res = addRotateCropTags();
520 if (OK != res) {
521 ALOGE("%s: Unable to add default SCALER_ROTATE_AND_CROP tags: %s (%d)", __FUNCTION__,
522 strerror(-res), res);
523 }
524 res = addPreCorrectionActiveArraySize();
525 if (OK != res) {
526 ALOGE("%s: Unable to add PRE_CORRECTION_ACTIVE_ARRAY_SIZE: %s (%d)", __FUNCTION__,
527 strerror(-res), res);
528 }
529 res = camera3::ZoomRatioMapper::overrideZoomRatioTags(
530 &mCameraCharacteristics, &mSupportNativeZoomRatio);
531 if (OK != res) {
532 ALOGE("%s: Unable to override zoomRatio related tags: %s (%d)",
533 __FUNCTION__, strerror(-res), res);
534 }
535 res = addReadoutTimestampTag();
536 if (OK != res) {
537 ALOGE("%s: Unable to add sensorReadoutTimestamp tag: %s (%d)",
538 __FUNCTION__, strerror(-res), res);
539 }
540
541 camera_metadata_entry flashAvailable =
542 mCameraCharacteristics.find(ANDROID_FLASH_INFO_AVAILABLE);
543 if (flashAvailable.count == 1 &&
544 flashAvailable.data.u8[0] == ANDROID_FLASH_INFO_AVAILABLE_TRUE) {
545 mHasFlashUnit = true;
546 // Fix up flash strength tags for devices without these keys.
547 res = fixupTorchStrengthTags();
548 if (OK != res) {
549 ALOGE("%s: Unable to add default ANDROID_FLASH_INFO_STRENGTH_DEFAULT_LEVEL and"
550 "ANDROID_FLASH_INFO_STRENGTH_MAXIMUM_LEVEL tags: %s (%d)", __FUNCTION__,
551 strerror(-res), res);
552 }
553 } else {
554 mHasFlashUnit = false;
555 }
556
557 camera_metadata_entry entry =
558 mCameraCharacteristics.find(ANDROID_FLASH_INFO_STRENGTH_DEFAULT_LEVEL);
559 if (entry.count == 1) {
560 mTorchDefaultStrengthLevel = entry.data.i32[0];
561 } else {
562 mTorchDefaultStrengthLevel = 0;
563 }
564 entry = mCameraCharacteristics.find(ANDROID_FLASH_INFO_STRENGTH_MAXIMUM_LEVEL);
565 if (entry.count == 1) {
566 mTorchMaximumStrengthLevel = entry.data.i32[0];
567 } else {
568 mTorchMaximumStrengthLevel = 0;
569 }
570
571 mTorchStrengthLevel = 0;
572
573 queryPhysicalCameraIds();
574
575 // Get physical camera characteristics if applicable
576 if (mIsLogicalCamera) {
577 for (auto& id : mPhysicalIds) {
578 if (std::find(mPublicCameraIds.begin(), mPublicCameraIds.end(), id) !=
579 mPublicCameraIds.end()) {
580 continue;
581 }
582
583 aidl::android::hardware::camera::device::CameraMetadata pChars;
584 status = interface->getPhysicalCameraCharacteristics(id, &pChars);
585 if (!status.isOk()) {
586 ALOGE("%s: Transaction error getting physical camera %s characteristics for %s: %s",
587 __FUNCTION__, id.c_str(), id.c_str(), status.getMessage());
588 return;
589 }
590 std::vector<uint8_t> &pMetadata = pChars.metadata;
591 camera_metadata_t *pBuffer =
592 reinterpret_cast<camera_metadata_t*>(pMetadata.data());
593 size_t expectedSize = pMetadata.size();
594 int res = validate_camera_metadata_structure(pBuffer, &expectedSize);
595 if (res == OK || res == CAMERA_METADATA_VALIDATION_SHIFTED) {
596 set_camera_metadata_vendor_id(pBuffer, mProviderTagid);
597 mPhysicalCameraCharacteristics[id] = pBuffer;
598 } else {
599 ALOGE("%s: Malformed camera metadata received from HAL", __FUNCTION__);
600 return;
601 }
602
603 res = camera3::ZoomRatioMapper::overrideZoomRatioTags(
604 &mPhysicalCameraCharacteristics[id], &mSupportNativeZoomRatio);
605 if (OK != res) {
606 ALOGE("%s: Unable to override zoomRatio related tags: %s (%d)",
607 __FUNCTION__, strerror(-res), res);
608 }
609 }
610 }
611
612 if (!kEnableLazyHal) {
613 // Save HAL reference indefinitely
614 mSavedInterface = interface;
615 }
616 }
617
setTorchMode(bool enabled)618 status_t AidlProviderInfo::AidlDeviceInfo3::setTorchMode(bool enabled) {
619 const std::shared_ptr<camera::device::ICameraDevice> interface = startDeviceInterface();
620 ::ndk::ScopedAStatus s = interface->setTorchMode(enabled);
621 if (!s.isOk()) {
622 ALOGE("%s Unable to set torch mode: %s", __FUNCTION__, s.getMessage());
623 return mapToStatusT(s);
624 }
625 return OK;
626 }
627
turnOnTorchWithStrengthLevel(int32_t torchStrength)628 status_t AidlProviderInfo::AidlDeviceInfo3::turnOnTorchWithStrengthLevel(
629 int32_t torchStrength) {
630 const std::shared_ptr<camera::device::ICameraDevice> interface = startDeviceInterface();
631 if (interface == nullptr) {
632 return DEAD_OBJECT;
633 }
634
635 ::ndk::ScopedAStatus s = interface->turnOnTorchWithStrengthLevel(torchStrength);
636 if (!s.isOk()) {
637 ALOGE("%s Unable to set torch mode strength %d : %s", __FUNCTION__, torchStrength,
638 s.getMessage());
639 return mapToStatusT(s);
640 }
641 mTorchStrengthLevel = torchStrength;
642 return OK;
643 }
644
getTorchStrengthLevel(int32_t * torchStrength)645 status_t AidlProviderInfo::AidlDeviceInfo3::getTorchStrengthLevel(int32_t *torchStrength) {
646 if (torchStrength == nullptr) {
647 return BAD_VALUE;
648 }
649 const std::shared_ptr<camera::device::ICameraDevice> interface = startDeviceInterface();
650 if (interface == nullptr) {
651 return DEAD_OBJECT;
652 }
653
654 ::ndk::ScopedAStatus status = interface->getTorchStrengthLevel(torchStrength);
655 if (!status.isOk()) {
656 ALOGE("%s: Couldn't get torch strength level: %s", __FUNCTION__, status.getMessage());
657 return mapToStatusT(status);
658 }
659 return OK;
660 }
661
662 std::shared_ptr<aidl::android::hardware::camera::device::ICameraDevice>
startDeviceInterface()663 AidlProviderInfo::AidlDeviceInfo3::startDeviceInterface() {
664 Mutex::Autolock l(mDeviceAvailableLock);
665 std::shared_ptr<camera::device::ICameraDevice> device;
666 ATRACE_CALL();
667 if (mSavedInterface == nullptr) {
668 sp<AidlProviderInfo> parentProvider =
669 static_cast<AidlProviderInfo *>(mParentProvider.promote().get());
670 if (parentProvider != nullptr) {
671 // Wait for lazy HALs to confirm device availability
672 if (parentProvider->isExternalLazyHAL() && !mIsDeviceAvailable) {
673 ALOGV("%s: Wait for external device to become available %s",
674 __FUNCTION__,
675 mId.c_str());
676
677 auto res = mDeviceAvailableSignal.waitRelative(mDeviceAvailableLock,
678 kDeviceAvailableTimeout);
679 if (res != OK) {
680 ALOGE("%s: Failed waiting for device to become available",
681 __FUNCTION__);
682 return nullptr;
683 }
684 }
685
686 device = parentProvider->startDeviceInterface(mName);
687 }
688 } else {
689 device = mSavedInterface;
690 }
691 return device;
692 }
693
dumpState(int fd)694 status_t AidlProviderInfo::AidlDeviceInfo3::dumpState(int fd) {
695 const std::shared_ptr<camera::device::ICameraDevice> interface = startDeviceInterface();
696 if (interface == nullptr) {
697 return DEAD_OBJECT;
698 }
699 const char *args = nullptr;
700 auto ret = interface->dump(fd, &args, /*numArgs*/0);
701 if (ret != OK) {
702 return ret;
703 }
704 return OK;
705 }
706
isSessionConfigurationSupported(const SessionConfiguration & configuration,bool overrideForPerfClass,camera3::metadataGetter getMetadata,bool * status)707 status_t AidlProviderInfo::AidlDeviceInfo3::isSessionConfigurationSupported(
708 const SessionConfiguration &configuration, bool overrideForPerfClass,
709 camera3::metadataGetter getMetadata, bool *status) {
710
711 camera::device::StreamConfiguration streamConfiguration;
712 bool earlyExit = false;
713 auto bRes = SessionConfigurationUtils::convertToHALStreamCombination(configuration,
714 String8(mId.c_str()), mCameraCharacteristics, getMetadata, mPhysicalIds,
715 streamConfiguration, overrideForPerfClass, &earlyExit);
716
717 if (!bRes.isOk()) {
718 return UNKNOWN_ERROR;
719 }
720
721 if (earlyExit) {
722 *status = false;
723 return OK;
724 }
725
726 const std::shared_ptr<camera::device::ICameraDevice> interface =
727 startDeviceInterface();
728
729 if (interface == nullptr) {
730 return DEAD_OBJECT;
731 }
732
733 ::ndk::ScopedAStatus ret =
734 interface->isStreamCombinationSupported(streamConfiguration, status);
735 if (!ret.isOk()) {
736 *status = false;
737 ALOGE("%s: Unexpected binder error: %s", __FUNCTION__, ret.getMessage());
738 return mapToStatusT(ret);
739 }
740 return OK;
741
742 }
743
convertToAidlHALStreamCombinationAndCameraIdsLocked(const std::vector<CameraIdAndSessionConfiguration> & cameraIdsAndSessionConfigs,const std::set<std::string> & perfClassPrimaryCameraIds,int targetSdkVersion,std::vector<camera::provider::CameraIdAndStreamCombination> * halCameraIdsAndStreamCombinations,bool * earlyExit)744 status_t AidlProviderInfo::convertToAidlHALStreamCombinationAndCameraIdsLocked(
745 const std::vector<CameraIdAndSessionConfiguration> &cameraIdsAndSessionConfigs,
746 const std::set<std::string>& perfClassPrimaryCameraIds,
747 int targetSdkVersion,
748 std::vector<camera::provider::CameraIdAndStreamCombination>
749 *halCameraIdsAndStreamCombinations,
750 bool *earlyExit) {
751 binder::Status bStatus = binder::Status::ok();
752 std::vector<camera::provider::CameraIdAndStreamCombination> halCameraIdsAndStreamsV;
753 bool shouldExit = false;
754 status_t res = OK;
755 for (auto &cameraIdAndSessionConfig : cameraIdsAndSessionConfigs) {
756 const std::string& cameraId = cameraIdAndSessionConfig.mCameraId;
757 camera::device::StreamConfiguration streamConfiguration;
758 CameraMetadata deviceInfo;
759 bool overrideForPerfClass =
760 SessionConfigurationUtils::targetPerfClassPrimaryCamera(
761 perfClassPrimaryCameraIds, cameraId, targetSdkVersion);
762 res = mManager->getCameraCharacteristicsLocked(cameraId, overrideForPerfClass, &deviceInfo,
763 /*overrideToPortrait*/false);
764 if (res != OK) {
765 return res;
766 }
767 camera3::metadataGetter getMetadata =
768 [this](const String8 &id, bool overrideForPerfClass) {
769 CameraMetadata physicalDeviceInfo;
770 mManager->getCameraCharacteristicsLocked(id.string(), overrideForPerfClass,
771 &physicalDeviceInfo,
772 /*overrideToPortrait*/false);
773 return physicalDeviceInfo;
774 };
775 std::vector<std::string> physicalCameraIds;
776 mManager->isLogicalCameraLocked(cameraId, &physicalCameraIds);
777 bStatus =
778 SessionConfigurationUtils::convertToHALStreamCombination(
779 cameraIdAndSessionConfig.mSessionConfiguration,
780 String8(cameraId.c_str()), deviceInfo, getMetadata,
781 physicalCameraIds, streamConfiguration,
782 overrideForPerfClass, &shouldExit);
783 if (!bStatus.isOk()) {
784 ALOGE("%s: convertToHALStreamCombination failed", __FUNCTION__);
785 return INVALID_OPERATION;
786 }
787 if (shouldExit) {
788 *earlyExit = true;
789 return OK;
790 }
791 camera::provider::CameraIdAndStreamCombination halCameraIdAndStream;
792 halCameraIdAndStream.cameraId = cameraId;
793 halCameraIdAndStream.streamConfiguration = streamConfiguration;
794 halCameraIdsAndStreamsV.push_back(halCameraIdAndStream);
795 }
796 *halCameraIdsAndStreamCombinations = halCameraIdsAndStreamsV;
797 return OK;
798 }
799
isConcurrentSessionConfigurationSupported(const std::vector<CameraIdAndSessionConfiguration> & cameraIdsAndSessionConfigs,const std::set<std::string> & perfClassPrimaryCameraIds,int targetSdkVersion,bool * isSupported)800 status_t AidlProviderInfo::isConcurrentSessionConfigurationSupported(
801 const std::vector<CameraIdAndSessionConfiguration> &cameraIdsAndSessionConfigs,
802 const std::set<std::string>& perfClassPrimaryCameraIds,
803 int targetSdkVersion, bool *isSupported) {
804
805 std::vector<camera::provider::CameraIdAndStreamCombination> halCameraIdsAndStreamCombinations;
806 bool knowUnsupported = false;
807 status_t res = convertToAidlHALStreamCombinationAndCameraIdsLocked(
808 cameraIdsAndSessionConfigs, perfClassPrimaryCameraIds,
809 targetSdkVersion, &halCameraIdsAndStreamCombinations, &knowUnsupported);
810 if (res != OK) {
811 ALOGE("%s unable to convert session configurations provided to HAL stream"
812 "combinations", __FUNCTION__);
813 return res;
814 }
815 if (knowUnsupported) {
816 // We got to know the streams aren't valid before doing the HAL
817 // call itself.
818 *isSupported = false;
819 return OK;
820 }
821
822 // Check if the provider is currently active - not going to start it up for this notification
823 auto interface = mSavedInterface != nullptr ? mSavedInterface : mActiveInterface.lock();
824 if (interface == nullptr) {
825 // TODO: This might be some other problem
826 return INVALID_OPERATION;
827 }
828 ::ndk::ScopedAStatus status = interface->isConcurrentStreamCombinationSupported(
829 halCameraIdsAndStreamCombinations, isSupported);
830 if (!status.isOk()) {
831 *isSupported = false;
832 ALOGE("%s: hal interface session configuration query failed", __FUNCTION__);
833 return mapToStatusT(status);
834 }
835
836 return OK;
837 }
838
839 } //namespace android
840