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