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 <aidl/AidlUtils.h>
21
22 #include <com_android_internal_camera_flags.h>
23 #include <cutils/properties.h>
24
25 #include <aidlcommonsupport/NativeHandle.h>
26 #include <android_companion_virtualdevice_flags.h>
27 #include <android/binder_manager.h>
28 #include <android/hardware/ICameraService.h>
29 #include <camera_metadata_hidden.h>
30
31 #include "device3/DistortionMapper.h"
32 #include "device3/ZoomRatioMapper.h"
33 #include <utils/SessionConfigurationUtils.h>
34 #include <utils/Trace.h>
35
36 namespace {
37 const bool kEnableLazyHal(property_get_bool("ro.camera.enableLazyHal", false));
38 } // anonymous namespace
39
40 namespace android {
41
42 namespace SessionConfigurationUtils = ::android::camera3::SessionConfigurationUtils;
43 namespace flags = com::android::internal::camera::flags;
44 namespace vd_flags = android::companion::virtualdevice::flags;
45
46 using namespace aidl::android::hardware;
47 using namespace hardware::camera;
48 using android::hardware::cameraservice::utils::conversion::aidl::copySessionCharacteristics;
49 using hardware::camera2::utils::CameraIdAndSessionConfiguration;
50 using hardware::ICameraService;
51 using SessionConfigurationUtils::overrideDefaultRequestKeys;
52
53 using HalDeviceStatusType = aidl::android::hardware::camera::common::CameraDeviceStatus;
54 using ICameraProvider = aidl::android::hardware::camera::provider::ICameraProvider;
55 using StatusListener = CameraProviderManager::StatusListener;
56
mapExceptionCodeToStatusT(binder_exception_t binderException)57 static status_t mapExceptionCodeToStatusT(binder_exception_t binderException) {
58 switch (binderException) {
59 case EX_NONE:
60 return OK;
61 case EX_ILLEGAL_ARGUMENT:
62 case EX_NULL_POINTER:
63 case EX_BAD_PARCELABLE:
64 case EX_ILLEGAL_STATE:
65 return BAD_VALUE;
66 case EX_UNSUPPORTED_OPERATION:
67 return INVALID_OPERATION;
68 case EX_TRANSACTION_FAILED:
69 return DEAD_OBJECT;
70 default:
71 return UNKNOWN_ERROR;
72 }
73 }
74
mapToStatusT(const ndk::ScopedAStatus & s)75 status_t AidlProviderInfo::mapToStatusT(const ndk::ScopedAStatus& s) {
76 using Status = aidl::android::hardware::camera::common::Status;
77 auto exceptionCode = s.getExceptionCode();
78 if (exceptionCode != EX_SERVICE_SPECIFIC) {
79 return mapExceptionCodeToStatusT(exceptionCode);
80 }
81 Status st = static_cast<Status>(s.getServiceSpecificError());
82 switch (st) {
83 case Status::OK:
84 return OK;
85 case Status::ILLEGAL_ARGUMENT:
86 return BAD_VALUE;
87 case Status::CAMERA_IN_USE:
88 return -EBUSY;
89 case Status::MAX_CAMERAS_IN_USE:
90 return -EUSERS;
91 case Status::OPERATION_NOT_SUPPORTED:
92 return INVALID_OPERATION;
93 case Status::CAMERA_DISCONNECTED:
94 return DEAD_OBJECT;
95 case Status::INTERNAL_ERROR:
96 return INVALID_OPERATION;
97 }
98 ALOGW("Unexpected HAL status code %d", static_cast<int>(st));
99 return INVALID_OPERATION;
100 }
101
AidlProviderInfo(const std::string & providerName,const std::string & providerInstance,CameraProviderManager * manager)102 AidlProviderInfo::AidlProviderInfo(
103 const std::string &providerName,
104 const std::string &providerInstance,
105 CameraProviderManager *manager) :
106 CameraProviderManager::ProviderInfo(providerName, providerInstance, manager) {}
107
initializeAidlProvider(std::shared_ptr<ICameraProvider> & interface,int64_t currentDeviceState)108 status_t AidlProviderInfo::initializeAidlProvider(
109 std::shared_ptr<ICameraProvider>& interface, int64_t currentDeviceState) {
110
111 using aidl::android::hardware::camera::provider::ICameraProvider;
112 std::string parsedProviderName = mProviderName;
113 if (flags::lazy_aidl_wait_for_service()) {
114 parsedProviderName =
115 mProviderName.substr(std::string(ICameraProvider::descriptor).size() + 1);
116 }
117
118 status_t res = parseProviderName(parsedProviderName, &mType, &mId);
119 if (res != OK) {
120 ALOGE("%s: Invalid provider name, ignoring", __FUNCTION__);
121 return BAD_VALUE;
122 }
123 ALOGI("Connecting to new camera provider: %s, isRemote? %d",
124 mProviderName.c_str(), interface->isRemote());
125
126 // cameraDeviceStatusChange callbacks may be called (and causing new devices added)
127 // before setCallback returns
128 mCallbacks =
129 ndk::SharedRefBase::make<AidlProviderCallbacks>(this);
130 ndk::ScopedAStatus status =
131 interface->setCallback(mCallbacks);
132 if (!status.isOk()) {
133 ALOGE("%s: Transaction error setting up callbacks with camera provider '%s': %s",
134 __FUNCTION__, mProviderName.c_str(), status.getMessage());
135 return mapToStatusT(status);
136 }
137
138 mDeathRecipient = ndk::ScopedAIBinder_DeathRecipient(AIBinder_DeathRecipient_new(binderDied));
139
140 if (!vd_flags::virtual_camera_service_discovery() || interface->isRemote()) {
141 binder_status_t link =
142 AIBinder_linkToDeath(interface->asBinder().get(), mDeathRecipient.get(), this);
143 if (link != STATUS_OK) {
144 ALOGW("%s: Unable to link to provider '%s' death notifications (%d)", __FUNCTION__,
145 mProviderName.c_str(), link);
146 return DEAD_OBJECT;
147 }
148 }
149
150 if (!kEnableLazyHal) {
151 // Save HAL reference indefinitely
152 mSavedInterface = interface;
153 } else {
154 mActiveInterface = interface;
155 }
156
157 ALOGV("%s: Setting device state for %s: 0x%" PRIx64,
158 __FUNCTION__, mProviderName.c_str(), mDeviceState);
159 notifyDeviceStateChange(currentDeviceState);
160
161 res = setUpVendorTags();
162 if (res != OK) {
163 ALOGE("%s: Unable to set up vendor tags from provider '%s'",
164 __FUNCTION__, mProviderName.c_str());
165 return res;
166 }
167
168 // Get initial list of camera devices, if any
169 std::vector<std::string> devices;
170 std::vector<std::string> retDevices;
171 status = interface->getCameraIdList(&retDevices);
172 if (!status.isOk()) {
173 ALOGE("%s: Transaction error in getting camera ID list from provider '%s': %s",
174 __FUNCTION__, mProviderName.c_str(), status.getMessage());
175 return mapToStatusT(status);
176 }
177
178 for (auto& name : retDevices) {
179 uint16_t major, minor;
180 std::string type, id;
181 status_t res = parseDeviceName(name, &major, &minor, &type, &id);
182 if (res != OK) {
183 ALOGE("%s: Error parsing deviceName: %s: %d", __FUNCTION__, name.c_str(), res);
184 return res;
185 } else {
186 devices.push_back(name);
187 mProviderPublicCameraIds.push_back(id);
188 }
189 }
190
191 // Get list of concurrent streaming camera device combinations
192 res = getConcurrentCameraIdsInternalLocked(interface);
193 if (res != OK) {
194 return res;
195 }
196
197 mSetTorchModeSupported = true;
198
199 mIsRemote = interface->isRemote();
200
201 initializeProviderInfoCommon(devices);
202 return OK;
203 }
204
binderDied(void * cookie)205 void AidlProviderInfo::binderDied(void *cookie) {
206 AidlProviderInfo *provider = reinterpret_cast<AidlProviderInfo *>(cookie);
207 ALOGI("Camera provider '%s' has died; removing it", provider->mProviderInstance.c_str());
208 provider->mManager->removeProvider(provider->mProviderInstance);
209 }
210
setUpVendorTags()211 status_t AidlProviderInfo::setUpVendorTags() {
212 if (mVendorTagDescriptor != nullptr)
213 return OK;
214
215 std::vector<camera::common::VendorTagSection> vts;
216 ::ndk::ScopedAStatus status;
217 const std::shared_ptr<ICameraProvider> interface = startProviderInterface();
218 if (interface == nullptr) {
219 return DEAD_OBJECT;
220 }
221 status = interface->getVendorTags(&vts);
222 if (!status.isOk()) {
223 ALOGE("%s: Transaction error getting vendor tags from provider '%s': %s",
224 __FUNCTION__, mProviderName.c_str(), status.getMessage());
225 return mapToStatusT(status);
226 }
227
228 // Read all vendor tag definitions into a descriptor
229 status_t res;
230 if ((res =
231 IdlVendorTagDescriptor::
232 createDescriptorFromIdl<std::vector<camera::common::VendorTagSection>,
233 camera::common::VendorTagSection>(vts, /*out*/mVendorTagDescriptor))
234 != OK) {
235 ALOGE("%s: Could not generate descriptor from vendor tag operations,"
236 "received error %s (%d). Camera clients will not be able to use"
237 "vendor tags", __FUNCTION__, strerror(res), res);
238 return res;
239 }
240
241 return OK;
242 }
243
notifyDeviceStateChange(int64_t newDeviceState)244 status_t AidlProviderInfo::notifyDeviceStateChange(int64_t newDeviceState) {
245
246 mDeviceState = newDeviceState;
247 // Check if the provider is currently active - not going to start it up for this notification
248 auto interface = mSavedInterface != nullptr ? mSavedInterface : mActiveInterface.lock();
249 if (interface != nullptr) {
250 // Send current device state
251 interface->notifyDeviceStateChange(mDeviceState);
252 }
253 return OK;
254 }
255
successfullyStartedProviderInterface()256 bool AidlProviderInfo::successfullyStartedProviderInterface() {
257 return startProviderInterface() != nullptr;
258 }
259
260 std::shared_ptr<camera::device::ICameraDevice>
startDeviceInterface(const std::string & name)261 AidlProviderInfo::startDeviceInterface(const std::string &name) {
262 ::ndk::ScopedAStatus status;
263 std::shared_ptr<camera::device::ICameraDevice> cameraInterface;
264 const std::shared_ptr<ICameraProvider> interface = startProviderInterface();
265 if (interface == nullptr) {
266 return nullptr;
267 }
268 status = interface->getCameraDeviceInterface(name, &cameraInterface);
269 if (!status.isOk()) {
270 ALOGE("%s: Transaction error trying to obtain interface for camera device %s: %s",
271 __FUNCTION__, name.c_str(), status.getMessage());
272 return nullptr;
273 }
274 return cameraInterface;
275 }
276
startProviderInterface()277 const std::shared_ptr<ICameraProvider> AidlProviderInfo::startProviderInterface() {
278 ATRACE_CALL();
279 ALOGV("Request to start camera provider: %s", mProviderName.c_str());
280 if (mSavedInterface != nullptr) {
281 return mSavedInterface;
282 }
283
284 if (!kEnableLazyHal) {
285 ALOGE("Bad provider state! Should not be here on a non-lazy HAL!");
286 return nullptr;
287 }
288
289 auto interface = mActiveInterface.lock();
290 if (interface != nullptr) {
291 ALOGV("Camera provider (%s) already in use. Re-using instance.", mProviderName.c_str());
292 return interface;
293 }
294
295 // Try to get service without starting
296 interface = ICameraProvider::fromBinder(
297 ndk::SpAIBinder(AServiceManager_checkService(mProviderName.c_str())));
298 if (interface != nullptr) {
299 // Service is already running. Cache and return.
300 mActiveInterface = interface;
301 return interface;
302 }
303
304 ALOGV("Camera provider actually needs restart, calling getService(%s)", mProviderName.c_str());
305 interface = mManager->mAidlServiceProxy->getService(mProviderName);
306
307 if (interface == nullptr) {
308 ALOGE("%s: %s service not started", __FUNCTION__, mProviderName.c_str());
309 return nullptr;
310 }
311
312 // Set all devices as ENUMERATING, provider should update status
313 // to PRESENT after initializing.
314 // This avoids failing getCameraDeviceInterface_V3_x before devices
315 // are ready.
316 for (auto& device : mDevices) {
317 device->mIsDeviceAvailable = false;
318 }
319
320 interface->setCallback(mCallbacks);
321 auto link = AIBinder_linkToDeath(interface->asBinder().get(), mDeathRecipient.get(),
322 this);
323 if (link != STATUS_OK) {
324 ALOGW("%s: Unable to link to provider '%s' death notifications",
325 __FUNCTION__, mProviderName.c_str());
326 mManager->removeProvider(mProviderInstance);
327 return nullptr;
328 }
329
330 // Send current device state
331 interface->notifyDeviceStateChange(mDeviceState);
332 // Cache interface to return early for future calls.
333 mActiveInterface = interface;
334
335 return interface;
336 }
337
cameraDeviceStatusChange(const std::string & cameraDeviceName,HalDeviceStatusType newStatus)338 ::ndk::ScopedAStatus AidlProviderInfo::AidlProviderCallbacks::cameraDeviceStatusChange(
339 const std::string& cameraDeviceName,
340 HalDeviceStatusType newStatus) {
341 sp<AidlProviderInfo> parent = mParent.promote();
342 if (parent == nullptr) {
343 ALOGE("%s: Parent provider not alive", __FUNCTION__);
344 return ::ndk::ScopedAStatus::ok();
345 }
346 return parent->cameraDeviceStatusChange(cameraDeviceName, newStatus);
347 }
348
torchModeStatusChange(const std::string & cameraDeviceName,aidl::android::hardware::camera::common::TorchModeStatus newStatus)349 ::ndk::ScopedAStatus AidlProviderInfo::AidlProviderCallbacks::torchModeStatusChange(
350 const std::string& cameraDeviceName,
351 aidl::android::hardware::camera::common::TorchModeStatus newStatus) {
352 sp<AidlProviderInfo> parent = mParent.promote();
353 if (parent == nullptr) {
354 ALOGE("%s: Parent provider not alive", __FUNCTION__);
355 return ::ndk::ScopedAStatus::ok();
356 }
357 return parent->torchModeStatusChange(cameraDeviceName, newStatus);
358
359 };
360
physicalCameraDeviceStatusChange(const std::string & cameraDeviceName,const std::string & physicalCameraDeviceName,HalDeviceStatusType newStatus)361 ::ndk::ScopedAStatus AidlProviderInfo::AidlProviderCallbacks::physicalCameraDeviceStatusChange(
362 const std::string& cameraDeviceName,
363 const std::string& physicalCameraDeviceName,
364 HalDeviceStatusType newStatus) {
365 sp<AidlProviderInfo> parent = mParent.promote();
366 if (parent == nullptr) {
367 ALOGE("%s: Parent provider not alive", __FUNCTION__);
368 return ::ndk::ScopedAStatus::ok();
369 }
370 return parent->physicalCameraDeviceStatusChange(cameraDeviceName, physicalCameraDeviceName,
371 newStatus);
372 };
373
cameraDeviceStatusChange(const std::string & cameraDeviceName,HalDeviceStatusType newStatus)374 ::ndk::ScopedAStatus AidlProviderInfo::cameraDeviceStatusChange(const std::string& cameraDeviceName,
375 HalDeviceStatusType newStatus) {
376 cameraDeviceStatusChangeInternal(cameraDeviceName, HalToFrameworkCameraDeviceStatus(newStatus));
377 return ::ndk::ScopedAStatus::ok();
378 }
379
torchModeStatusChange(const std::string & cameraDeviceName,aidl::android::hardware::camera::common::TorchModeStatus newStatus)380 ::ndk::ScopedAStatus AidlProviderInfo::torchModeStatusChange(const std::string& cameraDeviceName,
381 aidl::android::hardware::camera::common::TorchModeStatus newStatus) {
382 torchModeStatusChangeInternal(cameraDeviceName, HalToFrameworkTorchModeStatus(newStatus));
383 return ::ndk::ScopedAStatus::ok();
384 };
385
physicalCameraDeviceStatusChange(const std::string & cameraDeviceName,const std::string & physicalCameraDeviceName,HalDeviceStatusType newStatus)386 ::ndk::ScopedAStatus AidlProviderInfo::physicalCameraDeviceStatusChange(
387 const std::string& cameraDeviceName,
388 const std::string& physicalCameraDeviceName,
389 HalDeviceStatusType newStatus) {
390 physicalCameraDeviceStatusChangeInternal(cameraDeviceName, physicalCameraDeviceName,
391 HalToFrameworkCameraDeviceStatus(newStatus));
392 return ::ndk::ScopedAStatus::ok();
393 };
394
395 std::unique_ptr<CameraProviderManager::ProviderInfo::DeviceInfo>
initializeDeviceInfo(const std::string & name,const metadata_vendor_id_t tagId,const std::string & id,uint16_t)396 AidlProviderInfo::initializeDeviceInfo(
397 const std::string &name, const metadata_vendor_id_t tagId,
398 const std::string &id, uint16_t /*minorVersion*/) {
399 ::ndk::ScopedAStatus status;
400
401 auto cameraInterface = startDeviceInterface(name);
402 if (cameraInterface == nullptr) return nullptr;
403
404 camera::common::CameraResourceCost resourceCost;
405 status = cameraInterface->getResourceCost(&resourceCost);
406 if (!status.isOk()) {
407 ALOGE("%s: Unable to obtain resource costs for camera device %s: %s", __FUNCTION__,
408 name.c_str(), status.getMessage());
409 return nullptr;
410 }
411
412 for (auto& conflictName : resourceCost.conflictingDevices) {
413 uint16_t major, minor;
414 std::string type, id;
415 status_t res = parseDeviceName(conflictName, &major, &minor, &type, &id);
416 if (res != OK) {
417 ALOGE("%s: Failed to parse conflicting device %s", __FUNCTION__, conflictName.c_str());
418 return nullptr;
419 }
420 conflictName = id;
421 }
422
423 int32_t interfaceVersion = 0;
424 status = cameraInterface->getInterfaceVersion(&interfaceVersion);
425 if (!status.isOk()) {
426 ALOGE("%s: Unable to obtain interface version for camera device %s: %s", __FUNCTION__,
427 id.c_str(), status.getMessage());
428 return nullptr;
429 }
430
431 return std::unique_ptr<DeviceInfo3>(
432 new AidlDeviceInfo3(name, tagId, id, static_cast<uint16_t>(interfaceVersion),
433 HalToFrameworkResourceCost(resourceCost), this,
434 mProviderPublicCameraIds, cameraInterface));
435 }
436
reCacheConcurrentStreamingCameraIdsLocked()437 status_t AidlProviderInfo::reCacheConcurrentStreamingCameraIdsLocked() {
438
439 // Check if the provider is currently active - not going to start it up for this notification
440 auto interface = mSavedInterface != nullptr ? mSavedInterface : mActiveInterface.lock();
441 if (interface == nullptr) {
442 ALOGE("%s: camera provider interface for %s is not valid", __FUNCTION__,
443 mProviderName.c_str());
444 return INVALID_OPERATION;
445 }
446
447 return getConcurrentCameraIdsInternalLocked(interface);
448 }
449
getConcurrentCameraIdsInternalLocked(std::shared_ptr<ICameraProvider> & interface)450 status_t AidlProviderInfo::getConcurrentCameraIdsInternalLocked(
451 std::shared_ptr<ICameraProvider> &interface) {
452 if (interface == nullptr) {
453 ALOGE("%s: null interface provided", __FUNCTION__);
454 return BAD_VALUE;
455 }
456
457 std::vector<aidl::android::hardware::camera::provider::ConcurrentCameraIdCombination> combs;
458 ::ndk::ScopedAStatus status = interface->getConcurrentCameraIds(&combs);
459
460 if (!status.isOk()) {
461 ALOGE("%s: Transaction error in getting concurrent camera ID list from provider '%s'",
462 __FUNCTION__, mProviderName.c_str());
463 return mapToStatusT(status);
464 }
465 mConcurrentCameraIdCombinations.clear();
466 for (const auto& combination : combs) {
467 std::unordered_set<std::string> deviceIds;
468 for (const auto &cameraDeviceId : combination.combination) {
469 deviceIds.insert(cameraDeviceId);
470 }
471 mConcurrentCameraIdCombinations.push_back(std::move(deviceIds));
472 }
473
474 return OK;
475 }
476
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)477 AidlProviderInfo::AidlDeviceInfo3::AidlDeviceInfo3(
478 const std::string& name,
479 const metadata_vendor_id_t tagId,
480 const std::string &id, uint16_t minorVersion,
481 const CameraResourceCost& resourceCost,
482 sp<CameraProviderManager::ProviderInfo> parentProvider,
483 const std::vector<std::string>& publicCameraIds,
484 std::shared_ptr<aidl::android::hardware::camera::device::ICameraDevice> interface) :
485 DeviceInfo3(name, tagId, id, minorVersion, resourceCost, parentProvider, publicCameraIds) {
486
487 // Get camera characteristics and initialize flash unit availability
488 aidl::android::hardware::camera::device::CameraMetadata chars;
489 ::ndk::ScopedAStatus status = interface->getCameraCharacteristics(&chars);
490 std::vector<uint8_t> &metadata = chars.metadata;
491 camera_metadata_t *buffer = reinterpret_cast<camera_metadata_t*>(metadata.data());
492 size_t expectedSize = metadata.size();
493 int resV = validate_camera_metadata_structure(buffer, &expectedSize);
494 if (resV == OK || resV == CAMERA_METADATA_VALIDATION_SHIFTED) {
495 set_camera_metadata_vendor_id(buffer, mProviderTagid);
496 mCameraCharacteristics = buffer;
497 } else {
498 ALOGE("%s: Malformed camera metadata received from HAL", __FUNCTION__);
499 return;
500 }
501
502 if (!status.isOk()) {
503 ALOGE("%s: Transaction error getting camera characteristics for device %s"
504 " to check for a flash unit: %s", __FUNCTION__, id.c_str(),
505 status.getMessage());
506 return;
507 }
508
509 if (mCameraCharacteristics.exists(ANDROID_INFO_DEVICE_STATE_ORIENTATIONS)) {
510 const auto &stateMap = mCameraCharacteristics.find(ANDROID_INFO_DEVICE_STATE_ORIENTATIONS);
511 if ((stateMap.count > 0) && ((stateMap.count % 2) == 0)) {
512 for (size_t i = 0; i < stateMap.count; i += 2) {
513 mDeviceStateOrientationMap.emplace(stateMap.data.i64[i], stateMap.data.i64[i+1]);
514 }
515 } else {
516 ALOGW("%s: Invalid ANDROID_INFO_DEVICE_STATE_ORIENTATIONS map size: %zu", __FUNCTION__,
517 stateMap.count);
518 }
519 }
520
521 mCompositeJpegRDisabled = mCameraCharacteristics.exists(
522 ANDROID_JPEGR_AVAILABLE_JPEG_R_STREAM_CONFIGURATIONS);
523
524 mSystemCameraKind = getSystemCameraKind();
525
526 status_t res = fixupMonochromeTags();
527 if (OK != res) {
528 ALOGE("%s: Unable to fix up monochrome tags based for older HAL version: %s (%d)",
529 __FUNCTION__, strerror(-res), res);
530 return;
531 }
532 if (flags::camera_manual_flash_strength_control()) {
533 res = fixupManualFlashStrengthControlTags(mCameraCharacteristics);
534 if (OK != res) {
535 ALOGE("%s: Unable to fix up manual flash strength control tags: %s (%d)",
536 __FUNCTION__, strerror(-res), res);
537 return;
538 }
539 }
540
541 auto stat = addDynamicDepthTags();
542 if (OK != stat) {
543 ALOGE("%s: Failed appending dynamic depth tags: %s (%d)", __FUNCTION__, strerror(-stat),
544 stat);
545 }
546 res = deriveHeicTags();
547 if (OK != res) {
548 ALOGE("%s: Unable to derive HEIC tags based on camera and media capabilities: %s (%d)",
549 __FUNCTION__, strerror(-res), res);
550 }
551 res = deriveJpegRTags();
552 if (OK != res) {
553 ALOGE("%s: Unable to derive Jpeg/R tags based on camera and media capabilities: %s (%d)",
554 __FUNCTION__, strerror(-res), res);
555 }
556 using camera3::SessionConfigurationUtils::supportsUltraHighResolutionCapture;
557 if (supportsUltraHighResolutionCapture(mCameraCharacteristics)) {
558 status_t status = addDynamicDepthTags(/*maxResolution*/true);
559 if (OK != status) {
560 ALOGE("%s: Failed appending dynamic depth tags for maximum resolution mode: %s (%d)",
561 __FUNCTION__, strerror(-status), status);
562 }
563
564 status = deriveHeicTags(/*maxResolution*/true);
565 if (OK != status) {
566 ALOGE("%s: Unable to derive HEIC tags based on camera and media capabilities for"
567 "maximum resolution mode: %s (%d)", __FUNCTION__, strerror(-status), status);
568 }
569
570 status = deriveJpegRTags(/*maxResolution*/true);
571 if (OK != status) {
572 ALOGE("%s: Unable to derive Jpeg/R tags based on camera and media capabilities for"
573 "maximum resolution mode: %s (%d)", __FUNCTION__, strerror(-status), status);
574 }
575 }
576
577 res = addRotateCropTags();
578 if (OK != res) {
579 ALOGE("%s: Unable to add default SCALER_ROTATE_AND_CROP tags: %s (%d)", __FUNCTION__,
580 strerror(-res), res);
581 }
582 res = addAutoframingTags();
583 if (OK != res) {
584 ALOGE("%s: Unable to add default AUTOFRAMING tags: %s (%d)", __FUNCTION__,
585 strerror(-res), res);
586 }
587 res = addPreCorrectionActiveArraySize();
588 if (OK != res) {
589 ALOGE("%s: Unable to add PRE_CORRECTION_ACTIVE_ARRAY_SIZE: %s (%d)", __FUNCTION__,
590 strerror(-res), res);
591 }
592 res = camera3::ZoomRatioMapper::overrideZoomRatioTags(
593 &mCameraCharacteristics, &mSupportNativeZoomRatio);
594 if (OK != res) {
595 ALOGE("%s: Unable to override zoomRatio related tags: %s (%d)",
596 __FUNCTION__, strerror(-res), res);
597 }
598 res = addReadoutTimestampTag();
599 if (OK != res) {
600 ALOGE("%s: Unable to add sensorReadoutTimestamp tag: %s (%d)",
601 __FUNCTION__, strerror(-res), res);
602 }
603
604 camera_metadata_entry flashAvailable =
605 mCameraCharacteristics.find(ANDROID_FLASH_INFO_AVAILABLE);
606 if (flashAvailable.count == 1 &&
607 flashAvailable.data.u8[0] == ANDROID_FLASH_INFO_AVAILABLE_TRUE) {
608 mHasFlashUnit = true;
609 // Fix up flash strength tags for devices without these keys.
610 res = fixupTorchStrengthTags();
611 if (OK != res) {
612 ALOGE("%s: Unable to add default ANDROID_FLASH_INFO_STRENGTH_DEFAULT_LEVEL and"
613 "ANDROID_FLASH_INFO_STRENGTH_MAXIMUM_LEVEL tags: %s (%d)", __FUNCTION__,
614 strerror(-res), res);
615 }
616
617 // b/247038031: In case of system_server crash, camera_server is
618 // restarted as well. If flashlight is turned on before the crash, it
619 // may be stuck to be on. As a workaround, set torch mode to be OFF.
620 interface->setTorchMode(false);
621 } else {
622 mHasFlashUnit = false;
623 }
624
625 if (flags::feature_combination_query()) {
626 res = addSessionConfigQueryVersionTag();
627 if (OK != res) {
628 ALOGE("%s: Unable to add sessionConfigurationQueryVersion tag: %s (%d)",
629 __FUNCTION__, strerror(-res), res);
630 }
631 }
632
633 camera_metadata_entry entry =
634 mCameraCharacteristics.find(ANDROID_FLASH_INFO_STRENGTH_DEFAULT_LEVEL);
635 if (entry.count == 1) {
636 mTorchDefaultStrengthLevel = entry.data.i32[0];
637 } else {
638 mTorchDefaultStrengthLevel = 0;
639 }
640 entry = mCameraCharacteristics.find(ANDROID_FLASH_INFO_STRENGTH_MAXIMUM_LEVEL);
641 if (entry.count == 1) {
642 mTorchMaximumStrengthLevel = entry.data.i32[0];
643 } else {
644 mTorchMaximumStrengthLevel = 0;
645 }
646
647 mTorchStrengthLevel = 0;
648
649 queryPhysicalCameraIds();
650
651 // Get physical camera characteristics if applicable
652 if (mIsLogicalCamera) {
653 for (auto& id : mPhysicalIds) {
654 if (std::find(mPublicCameraIds.begin(), mPublicCameraIds.end(), id) !=
655 mPublicCameraIds.end()) {
656 continue;
657 }
658
659 aidl::android::hardware::camera::device::CameraMetadata pChars;
660 status = interface->getPhysicalCameraCharacteristics(id, &pChars);
661 if (!status.isOk()) {
662 ALOGE("%s: Transaction error getting physical camera %s characteristics for "
663 "logical id %s: %s", __FUNCTION__, id.c_str(), mId.c_str(),
664 status.getMessage());
665 return;
666 }
667 std::vector<uint8_t> &pMetadata = pChars.metadata;
668 camera_metadata_t *pBuffer =
669 reinterpret_cast<camera_metadata_t*>(pMetadata.data());
670 size_t expectedSize = pMetadata.size();
671 int res = validate_camera_metadata_structure(pBuffer, &expectedSize);
672 if (res == OK || res == CAMERA_METADATA_VALIDATION_SHIFTED) {
673 set_camera_metadata_vendor_id(pBuffer, mProviderTagid);
674 mPhysicalCameraCharacteristics[id] = pBuffer;
675 } else {
676 ALOGE("%s: Malformed camera metadata received from HAL", __FUNCTION__);
677 return;
678 }
679
680 res = camera3::ZoomRatioMapper::overrideZoomRatioTags(
681 &mPhysicalCameraCharacteristics[id], &mSupportNativeZoomRatio);
682 if (OK != res) {
683 ALOGE("%s: Unable to override zoomRatio related tags: %s (%d)",
684 __FUNCTION__, strerror(-res), res);
685 }
686
687 if (flags::camera_manual_flash_strength_control()) {
688 res = fixupManualFlashStrengthControlTags(mPhysicalCameraCharacteristics[id]);
689 if (OK != res) {
690 ALOGE("%s: Unable to fix up manual flash strength control tags: %s (%d)",
691 __FUNCTION__, strerror(-res), res);
692 return;
693 }
694 }
695 }
696 }
697
698 int deviceVersion = HARDWARE_DEVICE_API_VERSION(mVersion.get_major(), mVersion.get_minor());
699 if (deviceVersion >= CAMERA_DEVICE_API_VERSION_1_3) {
700 // This additional set of request keys must match the ones specified
701 // in ICameraDevice.isSessionConfigurationWithSettingsSupported.
702 mAdditionalKeysForFeatureQuery.insert(mAdditionalKeysForFeatureQuery.end(),
703 {ANDROID_CONTROL_VIDEO_STABILIZATION_MODE, ANDROID_CONTROL_AE_TARGET_FPS_RANGE});
704 }
705
706 if (!kEnableLazyHal) {
707 // Save HAL reference indefinitely
708 mSavedInterface = interface;
709 }
710 }
711
setTorchMode(bool enabled)712 status_t AidlProviderInfo::AidlDeviceInfo3::setTorchMode(bool enabled) {
713 const std::shared_ptr<camera::device::ICameraDevice> interface = startDeviceInterface();
714 ::ndk::ScopedAStatus s = interface->setTorchMode(enabled);
715 if (!s.isOk()) {
716 ALOGE("%s Unable to set torch mode: %s", __FUNCTION__, s.getMessage());
717 return mapToStatusT(s);
718 }
719 return OK;
720 }
721
turnOnTorchWithStrengthLevel(int32_t torchStrength)722 status_t AidlProviderInfo::AidlDeviceInfo3::turnOnTorchWithStrengthLevel(
723 int32_t torchStrength) {
724 const std::shared_ptr<camera::device::ICameraDevice> interface = startDeviceInterface();
725 if (interface == nullptr) {
726 return DEAD_OBJECT;
727 }
728
729 ::ndk::ScopedAStatus s = interface->turnOnTorchWithStrengthLevel(torchStrength);
730 if (!s.isOk()) {
731 ALOGE("%s Unable to set torch mode strength %d : %s", __FUNCTION__, torchStrength,
732 s.getMessage());
733 return mapToStatusT(s);
734 }
735 mTorchStrengthLevel = torchStrength;
736 return OK;
737 }
738
getTorchStrengthLevel(int32_t * torchStrength)739 status_t AidlProviderInfo::AidlDeviceInfo3::getTorchStrengthLevel(int32_t *torchStrength) {
740 if (torchStrength == nullptr) {
741 return BAD_VALUE;
742 }
743 const std::shared_ptr<camera::device::ICameraDevice> interface = startDeviceInterface();
744 if (interface == nullptr) {
745 return DEAD_OBJECT;
746 }
747
748 ::ndk::ScopedAStatus status = interface->getTorchStrengthLevel(torchStrength);
749 if (!status.isOk()) {
750 ALOGE("%s: Couldn't get torch strength level: %s", __FUNCTION__, status.getMessage());
751 return mapToStatusT(status);
752 }
753 return OK;
754 }
755
756 std::shared_ptr<aidl::android::hardware::camera::device::ICameraDevice>
startDeviceInterface()757 AidlProviderInfo::AidlDeviceInfo3::startDeviceInterface() {
758 Mutex::Autolock l(mDeviceAvailableLock);
759 std::shared_ptr<camera::device::ICameraDevice> device;
760 ATRACE_CALL();
761 if (mSavedInterface == nullptr) {
762 sp<AidlProviderInfo> parentProvider =
763 static_cast<AidlProviderInfo *>(mParentProvider.promote().get());
764 if (parentProvider != nullptr) {
765 // Wait for lazy HALs to confirm device availability
766 if (parentProvider->isExternalLazyHAL() && !mIsDeviceAvailable) {
767 ALOGV("%s: Wait for external device to become available %s",
768 __FUNCTION__,
769 mId.c_str());
770
771 auto res = mDeviceAvailableSignal.waitRelative(mDeviceAvailableLock,
772 kDeviceAvailableTimeout);
773 if (res != OK) {
774 ALOGE("%s: Failed waiting for device to become available",
775 __FUNCTION__);
776 return nullptr;
777 }
778 }
779
780 device = parentProvider->startDeviceInterface(mName);
781 }
782 } else {
783 device = mSavedInterface;
784 }
785 return device;
786 }
787
dumpState(int fd)788 status_t AidlProviderInfo::AidlDeviceInfo3::dumpState(int fd) {
789 const std::shared_ptr<camera::device::ICameraDevice> interface = startDeviceInterface();
790 if (interface == nullptr) {
791 return DEAD_OBJECT;
792 }
793 const char *args = nullptr;
794 auto ret = interface->dump(fd, &args, /*numArgs*/0);
795 if (ret != OK) {
796 return ret;
797 }
798 return OK;
799 }
800
isSessionConfigurationSupported(const SessionConfiguration & configuration,bool overrideForPerfClass,camera3::metadataGetter getMetadata,bool checkSessionParams,bool * status)801 status_t AidlProviderInfo::AidlDeviceInfo3::isSessionConfigurationSupported(
802 const SessionConfiguration &configuration, bool overrideForPerfClass,
803 camera3::metadataGetter getMetadata, bool checkSessionParams, bool *status) {
804
805 auto operatingMode = configuration.getOperatingMode();
806
807 auto res = SessionConfigurationUtils::checkOperatingMode(operatingMode,
808 mCameraCharacteristics, mId);
809 if (!res.isOk()) {
810 return UNKNOWN_ERROR;
811 }
812
813 camera::device::StreamConfiguration streamConfiguration;
814 bool earlyExit = false;
815 auto bRes = SessionConfigurationUtils::convertToHALStreamCombination(configuration,
816 mId, mCameraCharacteristics, mCompositeJpegRDisabled, getMetadata,
817 mPhysicalIds, streamConfiguration, overrideForPerfClass, mProviderTagid,
818 checkSessionParams, mAdditionalKeysForFeatureQuery, &earlyExit);
819
820 if (!bRes.isOk()) {
821 return UNKNOWN_ERROR;
822 }
823
824 if (earlyExit) {
825 *status = false;
826 return OK;
827 }
828
829 const std::shared_ptr<camera::device::ICameraDevice> interface =
830 startDeviceInterface();
831
832 if (interface == nullptr) {
833 return DEAD_OBJECT;
834 }
835
836 ::ndk::ScopedAStatus ret;
837 if (checkSessionParams) {
838 // Only interface version 1_3 or greater supports
839 // isStreamCombinationWIthSettingsSupported.
840 int deviceVersion = HARDWARE_DEVICE_API_VERSION(mVersion.get_major(), mVersion.get_minor());
841 if (deviceVersion < CAMERA_DEVICE_API_VERSION_1_3) {
842 ALOGI("%s: Camera device version (major %d, minor %d) doesn't support querying of "
843 "session configuration!", __FUNCTION__, mVersion.get_major(),
844 mVersion.get_minor());
845 return INVALID_OPERATION;
846 }
847 if (flags::feature_combination_query()) {
848 ret = interface->isStreamCombinationWithSettingsSupported(streamConfiguration, status);
849 } else {
850 return INVALID_OPERATION;
851 }
852 } else {
853 ret = interface->isStreamCombinationSupported(streamConfiguration, status);
854 }
855 if (!ret.isOk()) {
856 *status = false;
857 ALOGE("%s: Unexpected binder error: %s", __FUNCTION__, ret.getMessage());
858 return mapToStatusT(ret);
859 }
860 return OK;
861
862 }
863
createDefaultRequest(camera3::camera_request_template_t templateId,CameraMetadata * metadata)864 status_t AidlProviderInfo::AidlDeviceInfo3::createDefaultRequest(
865 camera3::camera_request_template_t templateId, CameraMetadata* metadata) {
866 const std::shared_ptr<camera::device::ICameraDevice> interface =
867 startDeviceInterface();
868
869 if (interface == nullptr) {
870 return DEAD_OBJECT;
871 }
872
873 int deviceVersion = HARDWARE_DEVICE_API_VERSION(mVersion.get_major(), mVersion.get_minor());
874 if (deviceVersion < CAMERA_DEVICE_API_VERSION_1_3) {
875 ALOGI("%s: Camera device minor version 0x%x doesn't support creating "
876 " default request!", __FUNCTION__, mVersion.get_minor());
877 return INVALID_OPERATION;
878 }
879
880 aidl::android::hardware::camera::device::CameraMetadata request;
881
882 using aidl::android::hardware::camera::device::RequestTemplate;
883 RequestTemplate id;
884 status_t res = SessionConfigurationUtils::mapRequestTemplateToAidl(
885 templateId, &id);
886 if (res != OK) {
887 return res;
888 }
889
890 if (!flags::feature_combination_query()) {
891 return INVALID_OPERATION;
892 }
893
894 auto err = interface->constructDefaultRequestSettings(id, &request);
895 if (!err.isOk()) {
896 ALOGE("%s: Transaction error: %s", __FUNCTION__, err.getMessage());
897 return AidlProviderInfo::mapToStatusT(err);
898 }
899 const camera_metadata *r =
900 reinterpret_cast<const camera_metadata_t*>(request.metadata.data());
901 camera_metadata *rawRequest = nullptr;
902 size_t expectedSize = request.metadata.size();
903 int ret = validate_camera_metadata_structure(r, &expectedSize);
904 if (ret == OK || ret == CAMERA_METADATA_VALIDATION_SHIFTED) {
905 rawRequest = clone_camera_metadata(r);
906 if (rawRequest == nullptr) {
907 ALOGE("%s: Unable to clone camera metadata received from HAL",
908 __FUNCTION__);
909 res = UNKNOWN_ERROR;
910 }
911 } else {
912 ALOGE("%s: Malformed camera metadata received from HAL", __FUNCTION__);
913 res = UNKNOWN_ERROR;
914 }
915
916 set_camera_metadata_vendor_id(rawRequest, mProviderTagid);
917 metadata->acquire(rawRequest);
918
919 res = overrideDefaultRequestKeys(metadata);
920 if (res != OK) {
921 ALOGE("Unabled to override default request keys: %s (%d)",
922 strerror(-res), res);
923 return res;
924 }
925
926 return res;
927 }
928
getSessionCharacteristics(const SessionConfiguration & configuration,bool overrideForPerfClass,camera3::metadataGetter getMetadata,CameraMetadata * outChars)929 status_t AidlProviderInfo::AidlDeviceInfo3::getSessionCharacteristics(
930 const SessionConfiguration &configuration, bool overrideForPerfClass,
931 camera3::metadataGetter getMetadata, CameraMetadata* outChars) {
932 camera::device::StreamConfiguration streamConfiguration;
933 bool earlyExit = false;
934 auto res = SessionConfigurationUtils::convertToHALStreamCombination(configuration,
935 mId, mCameraCharacteristics, mCompositeJpegRDisabled, getMetadata,
936 mPhysicalIds, streamConfiguration, overrideForPerfClass, mProviderTagid,
937 /*checkSessionParams*/true, mAdditionalKeysForFeatureQuery, &earlyExit);
938
939 if (!res.isOk()) {
940 return UNKNOWN_ERROR;
941 }
942
943 if (earlyExit) {
944 return BAD_VALUE;
945 }
946
947 const std::shared_ptr<camera::device::ICameraDevice> interface =
948 startDeviceInterface();
949
950 if (interface == nullptr) {
951 return DEAD_OBJECT;
952 }
953
954 aidl::android::hardware::camera::device::CameraMetadata chars;
955 ::ndk::ScopedAStatus ret =
956 interface->getSessionCharacteristics(streamConfiguration, &chars);
957 if (!ret.isOk()) {
958 ALOGE("%s: Unexpected binder error while getting session characteristics (%d): %s",
959 __FUNCTION__, ret.getExceptionCode(), ret.getMessage());
960 return mapToStatusT(ret);
961 }
962
963 std::vector<uint8_t> &metadata = chars.metadata;
964 auto *buffer = reinterpret_cast<camera_metadata_t*>(metadata.data());
965 size_t expectedSize = metadata.size();
966 int resV = validate_camera_metadata_structure(buffer, &expectedSize);
967 if (resV == OK || resV == CAMERA_METADATA_VALIDATION_SHIFTED) {
968 set_camera_metadata_vendor_id(buffer, mProviderTagid);
969 } else {
970 ALOGE("%s: Malformed camera metadata received from HAL", __FUNCTION__);
971 return BAD_VALUE;
972 }
973
974 CameraMetadata rawSessionChars;
975 rawSessionChars = buffer; // clone buffer
976 rawSessionChars.sort(); // sort for faster lookups
977
978 *outChars = mCameraCharacteristics;
979 outChars->sort(); // sort for faster reads and (hopefully!) writes
980
981 return copySessionCharacteristics(/*from=*/rawSessionChars, /*to=*/outChars,
982 mSessionConfigQueryVersion);
983 }
984
convertToAidlHALStreamCombinationAndCameraIdsLocked(const std::vector<CameraIdAndSessionConfiguration> & cameraIdsAndSessionConfigs,const std::set<std::string> & perfClassPrimaryCameraIds,int targetSdkVersion,std::vector<camera::provider::CameraIdAndStreamCombination> * halCameraIdsAndStreamCombinations,bool * earlyExit)985 status_t AidlProviderInfo::convertToAidlHALStreamCombinationAndCameraIdsLocked(
986 const std::vector<CameraIdAndSessionConfiguration> &cameraIdsAndSessionConfigs,
987 const std::set<std::string>& perfClassPrimaryCameraIds,
988 int targetSdkVersion,
989 std::vector<camera::provider::CameraIdAndStreamCombination>
990 *halCameraIdsAndStreamCombinations,
991 bool *earlyExit) {
992 binder::Status bStatus = binder::Status::ok();
993 std::vector<camera::provider::CameraIdAndStreamCombination> halCameraIdsAndStreamsV;
994 bool shouldExit = false;
995 status_t res = OK;
996 for (auto &cameraIdAndSessionConfig : cameraIdsAndSessionConfigs) {
997 const std::string& cameraId = cameraIdAndSessionConfig.mCameraId;
998 camera::device::StreamConfiguration streamConfiguration;
999 CameraMetadata deviceInfo;
1000 bool overrideForPerfClass =
1001 SessionConfigurationUtils::targetPerfClassPrimaryCamera(
1002 perfClassPrimaryCameraIds, cameraId, targetSdkVersion);
1003 res = mManager->getCameraCharacteristicsLocked(cameraId, overrideForPerfClass, &deviceInfo,
1004 hardware::ICameraService::ROTATION_OVERRIDE_NONE);
1005 if (res != OK) {
1006 return res;
1007 }
1008 camera3::metadataGetter getMetadata =
1009 [this](const std::string &id, bool overrideForPerfClass) {
1010 CameraMetadata physicalDeviceInfo;
1011 mManager->getCameraCharacteristicsLocked(
1012 id, overrideForPerfClass, &physicalDeviceInfo,
1013 hardware::ICameraService::ROTATION_OVERRIDE_NONE);
1014 return physicalDeviceInfo;
1015 };
1016 std::vector<std::string> physicalCameraIds;
1017 mManager->isLogicalCameraLocked(cameraId, &physicalCameraIds);
1018 bStatus =
1019 SessionConfigurationUtils::convertToHALStreamCombination(
1020 cameraIdAndSessionConfig.mSessionConfiguration,
1021 cameraId, deviceInfo,
1022 mManager->isCompositeJpegRDisabledLocked(cameraId), getMetadata,
1023 physicalCameraIds, streamConfiguration,
1024 overrideForPerfClass, mProviderTagid,
1025 /*checkSessionParams*/false, /*additionalKeys*/{},
1026 &shouldExit);
1027 if (!bStatus.isOk()) {
1028 ALOGE("%s: convertToHALStreamCombination failed", __FUNCTION__);
1029 return INVALID_OPERATION;
1030 }
1031 if (shouldExit) {
1032 *earlyExit = true;
1033 return OK;
1034 }
1035 camera::provider::CameraIdAndStreamCombination halCameraIdAndStream;
1036 halCameraIdAndStream.cameraId = cameraId;
1037 halCameraIdAndStream.streamConfiguration = streamConfiguration;
1038 halCameraIdsAndStreamsV.push_back(halCameraIdAndStream);
1039 }
1040 *halCameraIdsAndStreamCombinations = halCameraIdsAndStreamsV;
1041 return OK;
1042 }
1043
isConcurrentSessionConfigurationSupported(const std::vector<CameraIdAndSessionConfiguration> & cameraIdsAndSessionConfigs,const std::set<std::string> & perfClassPrimaryCameraIds,int targetSdkVersion,bool * isSupported)1044 status_t AidlProviderInfo::isConcurrentSessionConfigurationSupported(
1045 const std::vector<CameraIdAndSessionConfiguration> &cameraIdsAndSessionConfigs,
1046 const std::set<std::string>& perfClassPrimaryCameraIds,
1047 int targetSdkVersion, bool *isSupported) {
1048
1049 std::vector<camera::provider::CameraIdAndStreamCombination> halCameraIdsAndStreamCombinations;
1050 bool knowUnsupported = false;
1051 status_t res = convertToAidlHALStreamCombinationAndCameraIdsLocked(
1052 cameraIdsAndSessionConfigs, perfClassPrimaryCameraIds,
1053 targetSdkVersion, &halCameraIdsAndStreamCombinations, &knowUnsupported);
1054 if (res != OK) {
1055 ALOGE("%s unable to convert session configurations provided to HAL stream"
1056 "combinations", __FUNCTION__);
1057 return res;
1058 }
1059 if (knowUnsupported) {
1060 // We got to know the streams aren't valid before doing the HAL
1061 // call itself.
1062 *isSupported = false;
1063 return OK;
1064 }
1065
1066 // Check if the provider is currently active - not going to start it up for this notification
1067 auto interface = mSavedInterface != nullptr ? mSavedInterface : mActiveInterface.lock();
1068 if (interface == nullptr) {
1069 // TODO: This might be some other problem
1070 return INVALID_OPERATION;
1071 }
1072 ::ndk::ScopedAStatus status = interface->isConcurrentStreamCombinationSupported(
1073 halCameraIdsAndStreamCombinations, isSupported);
1074 if (!status.isOk()) {
1075 *isSupported = false;
1076 ALOGE("%s: hal interface session configuration query failed", __FUNCTION__);
1077 return mapToStatusT(status);
1078 }
1079
1080 return OK;
1081 }
1082
1083 } //namespace android
1084