• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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