• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2016 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #define LOG_TAG "CamPrvdr@2.4-legacy"
18 //#define LOG_NDEBUG 0
19 #include <android/log.h>
20 
21 #include "LegacyCameraProviderImpl_2_4.h"
22 #include "CameraDevice_1_0.h"
23 #include "CameraDevice_3_3.h"
24 #include "CameraDevice_3_4.h"
25 #include "CameraDevice_3_5.h"
26 #include "CameraProvider_2_4.h"
27 #include <cutils/properties.h>
28 #include <regex>
29 #include <string.h>
30 #include <utils/Trace.h>
31 
32 namespace android {
33 namespace hardware {
34 namespace camera {
35 namespace provider {
36 namespace V2_4 {
37 namespace implementation {
38 
39 template struct CameraProvider<LegacyCameraProviderImpl_2_4>;
40 
41 namespace {
42 // "device@<version>/legacy/<id>"
43 const std::regex kDeviceNameRE("device@([0-9]+\\.[0-9]+)/legacy/(.+)");
44 const char *kHAL3_4 = "3.4";
45 const char *kHAL3_5 = "3.5";
46 const int kMaxCameraDeviceNameLen = 128;
47 const int kMaxCameraIdLen = 16;
48 
matchDeviceName(const hidl_string & deviceName,std::string * deviceVersion,std::string * cameraId)49 bool matchDeviceName(const hidl_string& deviceName, std::string* deviceVersion,
50                      std::string* cameraId) {
51     std::string deviceNameStd(deviceName.c_str());
52     std::smatch sm;
53     if (std::regex_match(deviceNameStd, sm, kDeviceNameRE)) {
54         if (deviceVersion != nullptr) {
55             *deviceVersion = sm[1];
56         }
57         if (cameraId != nullptr) {
58             *cameraId = sm[2];
59         }
60         return true;
61     }
62     return false;
63 }
64 
65 } // anonymous namespace
66 
67 using ::android::hardware::camera::common::V1_0::CameraMetadataType;
68 using ::android::hardware::camera::common::V1_0::Status;
69 
addDeviceNames(int camera_id,CameraDeviceStatus status,bool cam_new)70 void LegacyCameraProviderImpl_2_4::addDeviceNames(int camera_id, CameraDeviceStatus status, bool cam_new)
71 {
72     char cameraId[kMaxCameraIdLen];
73     snprintf(cameraId, sizeof(cameraId), "%d", camera_id);
74     std::string cameraIdStr(cameraId);
75 
76     mCameraIds.add(cameraIdStr);
77 
78     // initialize mCameraDeviceNames and mOpenLegacySupported
79     mOpenLegacySupported[cameraIdStr] = false;
80     int deviceVersion = mModule->getDeviceVersion(camera_id);
81     auto deviceNamePair = std::make_pair(cameraIdStr,
82                                          getHidlDeviceName(cameraIdStr, deviceVersion));
83     mCameraDeviceNames.add(deviceNamePair);
84     if (cam_new) {
85         mCallbacks->cameraDeviceStatusChange(deviceNamePair.second, status);
86     }
87     if (deviceVersion >= CAMERA_DEVICE_API_VERSION_3_2 &&
88             mModule->isOpenLegacyDefined()) {
89         // try open_legacy to see if it actually works
90         struct hw_device_t* halDev = nullptr;
91         int ret = mModule->openLegacy(cameraId, CAMERA_DEVICE_API_VERSION_1_0, &halDev);
92         if (ret == 0) {
93             mOpenLegacySupported[cameraIdStr] = true;
94             halDev->close(halDev);
95             deviceNamePair = std::make_pair(cameraIdStr,
96                             getHidlDeviceName(cameraIdStr, CAMERA_DEVICE_API_VERSION_1_0));
97             mCameraDeviceNames.add(deviceNamePair);
98             if (cam_new) {
99                 mCallbacks->cameraDeviceStatusChange(deviceNamePair.second, status);
100             }
101         } else if (ret == -EBUSY || ret == -EUSERS) {
102             // Looks like this provider instance is not initialized during
103             // system startup and there are other camera users already.
104             // Not a good sign but not fatal.
105             ALOGW("%s: open_legacy try failed!", __FUNCTION__);
106         }
107     }
108 }
109 
removeDeviceNames(int camera_id)110 void LegacyCameraProviderImpl_2_4::removeDeviceNames(int camera_id)
111 {
112     std::string cameraIdStr = std::to_string(camera_id);
113 
114     mCameraIds.remove(cameraIdStr);
115 
116     int deviceVersion = mModule->getDeviceVersion(camera_id);
117     auto deviceNamePair = std::make_pair(cameraIdStr,
118                                          getHidlDeviceName(cameraIdStr, deviceVersion));
119     mCameraDeviceNames.remove(deviceNamePair);
120     mCallbacks->cameraDeviceStatusChange(deviceNamePair.second, CameraDeviceStatus::NOT_PRESENT);
121     if (deviceVersion >= CAMERA_DEVICE_API_VERSION_3_2 &&
122         mModule->isOpenLegacyDefined() && mOpenLegacySupported[cameraIdStr]) {
123 
124         deviceNamePair = std::make_pair(cameraIdStr,
125                             getHidlDeviceName(cameraIdStr, CAMERA_DEVICE_API_VERSION_1_0));
126         mCameraDeviceNames.remove(deviceNamePair);
127         mCallbacks->cameraDeviceStatusChange(deviceNamePair.second,
128                                              CameraDeviceStatus::NOT_PRESENT);
129     }
130 
131     mModule->removeCamera(camera_id);
132 }
133 
134 /**
135  * static callback forwarding methods from HAL to instance
136  */
sCameraDeviceStatusChange(const struct camera_module_callbacks * callbacks,int camera_id,int new_status)137 void LegacyCameraProviderImpl_2_4::sCameraDeviceStatusChange(
138         const struct camera_module_callbacks* callbacks,
139         int camera_id,
140         int new_status) {
141     LegacyCameraProviderImpl_2_4* cp = const_cast<LegacyCameraProviderImpl_2_4*>(
142             static_cast<const LegacyCameraProviderImpl_2_4*>(callbacks));
143     if (cp == nullptr) {
144         ALOGE("%s: callback ops is null", __FUNCTION__);
145         return;
146     }
147 
148     Mutex::Autolock _l(cp->mCbLock);
149     char cameraId[kMaxCameraIdLen];
150     snprintf(cameraId, sizeof(cameraId), "%d", camera_id);
151     std::string cameraIdStr(cameraId);
152     cp->mCameraStatusMap[cameraIdStr] = (camera_device_status_t) new_status;
153 
154     if (cp->mCallbacks == nullptr) {
155         // For camera connected before mCallbacks is set, the corresponding
156         // addDeviceNames() would be called later in setCallbacks().
157         return;
158     }
159 
160     bool found = false;
161     CameraDeviceStatus status = (CameraDeviceStatus)new_status;
162     for (auto const& deviceNamePair : cp->mCameraDeviceNames) {
163         if (cameraIdStr.compare(deviceNamePair.first) == 0) {
164             cp->mCallbacks->cameraDeviceStatusChange(deviceNamePair.second, status);
165             found = true;
166         }
167     }
168 
169     switch (status) {
170         case CameraDeviceStatus::PRESENT:
171         case CameraDeviceStatus::ENUMERATING:
172             if (!found) {
173                 cp->addDeviceNames(camera_id, status, true);
174             }
175             break;
176         case CameraDeviceStatus::NOT_PRESENT:
177             if (found) {
178                 cp->removeDeviceNames(camera_id);
179             }
180     }
181 }
182 
sTorchModeStatusChange(const struct camera_module_callbacks * callbacks,const char * camera_id,int new_status)183 void LegacyCameraProviderImpl_2_4::sTorchModeStatusChange(
184         const struct camera_module_callbacks* callbacks,
185         const char* camera_id,
186         int new_status) {
187     LegacyCameraProviderImpl_2_4* cp = const_cast<LegacyCameraProviderImpl_2_4*>(
188             static_cast<const LegacyCameraProviderImpl_2_4*>(callbacks));
189 
190     if (cp == nullptr) {
191         ALOGE("%s: callback ops is null", __FUNCTION__);
192         return;
193     }
194 
195     Mutex::Autolock _l(cp->mCbLock);
196     if (cp->mCallbacks != nullptr) {
197         std::string cameraIdStr(camera_id);
198         TorchModeStatus status = (TorchModeStatus) new_status;
199         for (auto const& deviceNamePair : cp->mCameraDeviceNames) {
200             if (cameraIdStr.compare(deviceNamePair.first) == 0) {
201                 cp->mCallbacks->torchModeStatusChange(
202                         deviceNamePair.second, status);
203             }
204         }
205     }
206 }
207 
getHidlStatus(int status)208 Status LegacyCameraProviderImpl_2_4::getHidlStatus(int status) {
209     switch (status) {
210         case 0: return Status::OK;
211         case -ENODEV: return Status::INTERNAL_ERROR;
212         case -EINVAL: return Status::ILLEGAL_ARGUMENT;
213         default:
214             ALOGE("%s: unknown HAL status code %d", __FUNCTION__, status);
215             return Status::INTERNAL_ERROR;
216     }
217 }
218 
getLegacyCameraId(const hidl_string & deviceName)219 std::string LegacyCameraProviderImpl_2_4::getLegacyCameraId(const hidl_string& deviceName) {
220     std::string cameraId;
221     matchDeviceName(deviceName, nullptr, &cameraId);
222     return cameraId;
223 }
224 
getHidlDeviceName(std::string cameraId,int deviceVersion)225 std::string LegacyCameraProviderImpl_2_4::getHidlDeviceName(
226         std::string cameraId, int deviceVersion) {
227     // Maybe consider create a version check method and SortedVec to speed up?
228     if (deviceVersion != CAMERA_DEVICE_API_VERSION_1_0 &&
229             deviceVersion != CAMERA_DEVICE_API_VERSION_3_2 &&
230             deviceVersion != CAMERA_DEVICE_API_VERSION_3_3 &&
231             deviceVersion != CAMERA_DEVICE_API_VERSION_3_4 &&
232             deviceVersion != CAMERA_DEVICE_API_VERSION_3_5 &&
233             deviceVersion != CAMERA_DEVICE_API_VERSION_3_6) {
234         return hidl_string("");
235     }
236 
237     // Supported combinations:
238     // CAMERA_DEVICE_API_VERSION_1_0 -> ICameraDevice@1.0
239     // CAMERA_DEVICE_API_VERSION_3_[2-4] -> ICameraDevice@[3.2|3.3]
240     // CAMERA_DEVICE_API_VERSION_3_5 + CAMERA_MODULE_API_VERSION_2_4 -> ICameraDevice@3.4
241     // CAMERA_DEVICE_API_VERSION_3_[5-6] + CAMERA_MODULE_API_VERSION_2_5 -> ICameraDevice@3.5
242     bool isV1 = deviceVersion == CAMERA_DEVICE_API_VERSION_1_0;
243     int versionMajor = isV1 ? 1 : 3;
244     int versionMinor = isV1 ? 0 : mPreferredHal3MinorVersion;
245     if (deviceVersion == CAMERA_DEVICE_API_VERSION_3_5) {
246         if (mModule->getModuleApiVersion() == CAMERA_MODULE_API_VERSION_2_5) {
247             versionMinor = 5;
248         } else {
249             versionMinor = 4;
250         }
251     } else if (deviceVersion == CAMERA_DEVICE_API_VERSION_3_6) {
252         versionMinor = 5;
253     }
254     char deviceName[kMaxCameraDeviceNameLen];
255     snprintf(deviceName, sizeof(deviceName), "device@%d.%d/legacy/%s",
256             versionMajor, versionMinor, cameraId.c_str());
257     return deviceName;
258 }
259 
LegacyCameraProviderImpl_2_4()260 LegacyCameraProviderImpl_2_4::LegacyCameraProviderImpl_2_4() :
261         camera_module_callbacks_t({sCameraDeviceStatusChange,
262                                    sTorchModeStatusChange}) {
263     mInitFailed = initialize();
264 }
265 
~LegacyCameraProviderImpl_2_4()266 LegacyCameraProviderImpl_2_4::~LegacyCameraProviderImpl_2_4() {}
267 
initialize()268 bool LegacyCameraProviderImpl_2_4::initialize() {
269     camera_module_t *rawModule;
270     int err = hw_get_module(CAMERA_HARDWARE_MODULE_ID,
271             (const hw_module_t **)&rawModule);
272     if (err < 0) {
273         ALOGE("Could not load camera HAL module: %d (%s)", err, strerror(-err));
274         return true;
275     }
276 
277     mModule = new CameraModule(rawModule);
278     err = mModule->init();
279     if (err != OK) {
280         ALOGE("Could not initialize camera HAL module: %d (%s)", err, strerror(-err));
281         mModule.clear();
282         return true;
283     }
284     ALOGI("Loaded \"%s\" camera module", mModule->getModuleName());
285 
286     // Setup vendor tags here so HAL can setup vendor keys in camera characteristics
287     VendorTagDescriptor::clearGlobalVendorTagDescriptor();
288     if (!setUpVendorTags()) {
289         ALOGE("%s: Vendor tag setup failed, will not be available.", __FUNCTION__);
290     }
291 
292     // Setup callback now because we are going to try openLegacy next
293     err = mModule->setCallbacks(this);
294     if (err != OK) {
295         ALOGE("Could not set camera module callback: %d (%s)", err, strerror(-err));
296         mModule.clear();
297         return true;
298     }
299 
300     mPreferredHal3MinorVersion =
301         property_get_int32("ro.vendor.camera.wrapper.hal3TrebleMinorVersion", 3);
302     ALOGV("Preferred HAL 3 minor version is %d", mPreferredHal3MinorVersion);
303     switch(mPreferredHal3MinorVersion) {
304         case 2:
305         case 3:
306             // OK
307             break;
308         default:
309             ALOGW("Unknown minor camera device HAL version %d in property "
310                     "'camera.wrapper.hal3TrebleMinorVersion', defaulting to 3",
311                     mPreferredHal3MinorVersion);
312             mPreferredHal3MinorVersion = 3;
313     }
314 
315     mNumberOfLegacyCameras = mModule->getNumberOfCameras();
316     for (int i = 0; i < mNumberOfLegacyCameras; i++) {
317         struct camera_info info;
318         auto rc = mModule->getCameraInfo(i, &info);
319         if (rc != NO_ERROR) {
320             ALOGE("%s: Camera info query failed!", __func__);
321             mModule.clear();
322             return true;
323         }
324 
325         if (checkCameraVersion(i, info) != OK) {
326             ALOGE("%s: Camera version check failed!", __func__);
327             mModule.clear();
328             return true;
329         }
330 
331         char cameraId[kMaxCameraIdLen];
332         snprintf(cameraId, sizeof(cameraId), "%d", i);
333         std::string cameraIdStr(cameraId);
334         mCameraStatusMap[cameraIdStr] = CAMERA_DEVICE_STATUS_PRESENT;
335 
336         addDeviceNames(i);
337     }
338 
339     return false; // mInitFailed
340 }
341 
342 /**
343  * Check that the device HAL version is still in supported.
344  */
checkCameraVersion(int id,camera_info info)345 int LegacyCameraProviderImpl_2_4::checkCameraVersion(int id, camera_info info) {
346     if (mModule == nullptr) {
347         return NO_INIT;
348     }
349 
350     // device_version undefined in CAMERA_MODULE_API_VERSION_1_0,
351     // All CAMERA_MODULE_API_VERSION_1_0 devices are backward-compatible
352     uint16_t moduleVersion = mModule->getModuleApiVersion();
353     if (moduleVersion >= CAMERA_MODULE_API_VERSION_2_0) {
354         // Verify the device version is in the supported range
355         switch (info.device_version) {
356             case CAMERA_DEVICE_API_VERSION_1_0:
357             case CAMERA_DEVICE_API_VERSION_3_2:
358             case CAMERA_DEVICE_API_VERSION_3_3:
359             case CAMERA_DEVICE_API_VERSION_3_4:
360             case CAMERA_DEVICE_API_VERSION_3_5:
361                 // in support
362                 break;
363             case CAMERA_DEVICE_API_VERSION_3_6:
364                 /**
365                  * ICameraDevice@3.5 contains APIs from both
366                  * CAMERA_DEVICE_API_VERSION_3_6 and CAMERA_MODULE_API_VERSION_2_5
367                  * so we require HALs to uprev both for simplified supported combinations.
368                  * HAL can still opt in individual new APIs indepedently.
369                  */
370                 if (moduleVersion < CAMERA_MODULE_API_VERSION_2_5) {
371                     ALOGE("%s: Device %d has unsupported version combination:"
372                             "HAL version %x and module version %x",
373                             __FUNCTION__, id, info.device_version, moduleVersion);
374                     return NO_INIT;
375                 }
376                 break;
377             case CAMERA_DEVICE_API_VERSION_2_0:
378             case CAMERA_DEVICE_API_VERSION_2_1:
379             case CAMERA_DEVICE_API_VERSION_3_0:
380             case CAMERA_DEVICE_API_VERSION_3_1:
381                 // no longer supported
382             default:
383                 ALOGE("%s: Device %d has HAL version %x, which is not supported",
384                         __FUNCTION__, id, info.device_version);
385                 return NO_INIT;
386         }
387     }
388 
389     return OK;
390 }
391 
setUpVendorTags()392 bool LegacyCameraProviderImpl_2_4::setUpVendorTags() {
393     ATRACE_CALL();
394     vendor_tag_ops_t vOps = vendor_tag_ops_t();
395 
396     // Check if vendor operations have been implemented
397     if (!mModule->isVendorTagDefined()) {
398         ALOGI("%s: No vendor tags defined for this device.", __FUNCTION__);
399         return true;
400     }
401 
402     mModule->getVendorTagOps(&vOps);
403 
404     // Ensure all vendor operations are present
405     if (vOps.get_tag_count == nullptr || vOps.get_all_tags == nullptr ||
406             vOps.get_section_name == nullptr || vOps.get_tag_name == nullptr ||
407             vOps.get_tag_type == nullptr) {
408         ALOGE("%s: Vendor tag operations not fully defined. Ignoring definitions."
409                , __FUNCTION__);
410         return false;
411     }
412 
413     // Read all vendor tag definitions into a descriptor
414     sp<VendorTagDescriptor> desc;
415     status_t res;
416     if ((res = VendorTagDescriptor::createDescriptorFromOps(&vOps, /*out*/desc))
417             != OK) {
418         ALOGE("%s: Could not generate descriptor from vendor tag operations,"
419               "received error %s (%d). Camera clients will not be able to use"
420               "vendor tags", __FUNCTION__, strerror(res), res);
421         return false;
422     }
423 
424     // Set the global descriptor to use with camera metadata
425     VendorTagDescriptor::setAsGlobalVendorTagDescriptor(desc);
426     const SortedVector<String8>* sectionNames = desc->getAllSectionNames();
427     size_t numSections = sectionNames->size();
428     std::vector<std::vector<VendorTag>> tagsBySection(numSections);
429     int tagCount = desc->getTagCount();
430     std::vector<uint32_t> tags(tagCount);
431     desc->getTagArray(tags.data());
432     for (int i = 0; i < tagCount; i++) {
433         VendorTag vt;
434         vt.tagId = tags[i];
435         vt.tagName = desc->getTagName(tags[i]);
436         vt.tagType = (CameraMetadataType) desc->getTagType(tags[i]);
437         ssize_t sectionIdx = desc->getSectionIndex(tags[i]);
438         tagsBySection[sectionIdx].push_back(vt);
439     }
440     mVendorTagSections.resize(numSections);
441     for (size_t s = 0; s < numSections; s++) {
442         mVendorTagSections[s].sectionName = (*sectionNames)[s].string();
443         mVendorTagSections[s].tags = tagsBySection[s];
444     }
445     return true;
446 }
447 
448 // Methods from ::android::hardware::camera::provider::V2_4::ICameraProvider follow.
setCallback(const sp<ICameraProviderCallback> & callback)449 Return<Status> LegacyCameraProviderImpl_2_4::setCallback(
450         const sp<ICameraProviderCallback>& callback) {
451     Mutex::Autolock _l(mCbLock);
452     mCallbacks = callback;
453 
454     // Add and report all presenting external cameras.
455     for (auto const& statusPair : mCameraStatusMap) {
456         int id = std::stoi(statusPair.first);
457         auto status = static_cast<CameraDeviceStatus>(statusPair.second);
458         if (id >= mNumberOfLegacyCameras && status != CameraDeviceStatus::NOT_PRESENT) {
459             addDeviceNames(id, status, true);
460         }
461     }
462 
463     return Status::OK;
464 }
465 
getVendorTags(ICameraProvider::getVendorTags_cb _hidl_cb)466 Return<void> LegacyCameraProviderImpl_2_4::getVendorTags(
467         ICameraProvider::getVendorTags_cb _hidl_cb) {
468     _hidl_cb(Status::OK, mVendorTagSections);
469     return Void();
470 }
471 
getCameraIdList(ICameraProvider::getCameraIdList_cb _hidl_cb)472 Return<void> LegacyCameraProviderImpl_2_4::getCameraIdList(
473         ICameraProvider::getCameraIdList_cb _hidl_cb) {
474     std::vector<hidl_string> deviceNameList;
475     for (auto const& deviceNamePair : mCameraDeviceNames) {
476         if (std::stoi(deviceNamePair.first) >= mNumberOfLegacyCameras) {
477             // External camera devices must be reported through the device status change callback,
478             // not in this list.
479             continue;
480         }
481         if (mCameraStatusMap[deviceNamePair.first] == CAMERA_DEVICE_STATUS_PRESENT) {
482             deviceNameList.push_back(deviceNamePair.second);
483         }
484     }
485     hidl_vec<hidl_string> hidlDeviceNameList(deviceNameList);
486     _hidl_cb(Status::OK, hidlDeviceNameList);
487     return Void();
488 }
489 
isSetTorchModeSupported(ICameraProvider::isSetTorchModeSupported_cb _hidl_cb)490 Return<void> LegacyCameraProviderImpl_2_4::isSetTorchModeSupported(
491         ICameraProvider::isSetTorchModeSupported_cb _hidl_cb) {
492     bool support = mModule->isSetTorchModeSupported();
493     _hidl_cb (Status::OK, support);
494     return Void();
495 }
496 
getCameraDeviceInterface_V1_x(const hidl_string & cameraDeviceName,ICameraProvider::getCameraDeviceInterface_V1_x_cb _hidl_cb)497 Return<void> LegacyCameraProviderImpl_2_4::getCameraDeviceInterface_V1_x(
498         const hidl_string& cameraDeviceName,
499         ICameraProvider::getCameraDeviceInterface_V1_x_cb _hidl_cb)  {
500     std::string cameraId, deviceVersion;
501     bool match = matchDeviceName(cameraDeviceName, &deviceVersion, &cameraId);
502     if (!match) {
503         _hidl_cb(Status::ILLEGAL_ARGUMENT, nullptr);
504         return Void();
505     }
506 
507     std::string deviceName(cameraDeviceName.c_str());
508     ssize_t index = mCameraDeviceNames.indexOf(std::make_pair(cameraId, deviceName));
509     if (index == NAME_NOT_FOUND) { // Either an illegal name or a device version mismatch
510         Status status = Status::OK;
511         ssize_t idx = mCameraIds.indexOf(cameraId);
512         if (idx == NAME_NOT_FOUND) {
513             ALOGE("%s: cannot find camera %s!", __FUNCTION__, cameraId.c_str());
514             status = Status::ILLEGAL_ARGUMENT;
515         } else { // invalid version
516             ALOGE("%s: camera device %s does not support version %s!",
517                     __FUNCTION__, cameraId.c_str(), deviceVersion.c_str());
518             status = Status::OPERATION_NOT_SUPPORTED;
519         }
520         _hidl_cb(status, nullptr);
521         return Void();
522     }
523 
524     if (mCameraStatusMap.count(cameraId) == 0 ||
525             mCameraStatusMap[cameraId] != CAMERA_DEVICE_STATUS_PRESENT) {
526         _hidl_cb(Status::ILLEGAL_ARGUMENT, nullptr);
527         return Void();
528     }
529 
530     sp<android::hardware::camera::device::V1_0::implementation::CameraDevice> device =
531             new android::hardware::camera::device::V1_0::implementation::CameraDevice(
532                     mModule, cameraId, mCameraDeviceNames);
533 
534     if (device == nullptr) {
535         ALOGE("%s: cannot allocate camera device for id %s", __FUNCTION__, cameraId.c_str());
536         _hidl_cb(Status::INTERNAL_ERROR, nullptr);
537         return Void();
538     }
539 
540     if (device->isInitFailed()) {
541         ALOGE("%s: camera device %s init failed!", __FUNCTION__, cameraId.c_str());
542         device = nullptr;
543         _hidl_cb(Status::INTERNAL_ERROR, nullptr);
544         return Void();
545     }
546 
547     _hidl_cb (Status::OK, device);
548     return Void();
549 }
550 
getCameraDeviceInterface_V3_x(const hidl_string & cameraDeviceName,ICameraProvider::getCameraDeviceInterface_V3_x_cb _hidl_cb)551 Return<void> LegacyCameraProviderImpl_2_4::getCameraDeviceInterface_V3_x(
552         const hidl_string& cameraDeviceName,
553         ICameraProvider::getCameraDeviceInterface_V3_x_cb _hidl_cb)  {
554     std::string cameraId, deviceVersion;
555     bool match = matchDeviceName(cameraDeviceName, &deviceVersion, &cameraId);
556     if (!match) {
557         _hidl_cb(Status::ILLEGAL_ARGUMENT, nullptr);
558         return Void();
559     }
560 
561     std::string deviceName(cameraDeviceName.c_str());
562     ssize_t index = mCameraDeviceNames.indexOf(std::make_pair(cameraId, deviceName));
563     if (index == NAME_NOT_FOUND) { // Either an illegal name or a device version mismatch
564         Status status = Status::OK;
565         ssize_t idx = mCameraIds.indexOf(cameraId);
566         if (idx == NAME_NOT_FOUND) {
567             ALOGE("%s: cannot find camera %s!", __FUNCTION__, cameraId.c_str());
568             status = Status::ILLEGAL_ARGUMENT;
569         } else { // invalid version
570             ALOGE("%s: camera device %s does not support version %s!",
571                     __FUNCTION__, cameraId.c_str(), deviceVersion.c_str());
572             status = Status::OPERATION_NOT_SUPPORTED;
573         }
574         _hidl_cb(status, nullptr);
575         return Void();
576     }
577 
578     if (mCameraStatusMap.count(cameraId) == 0 ||
579             mCameraStatusMap[cameraId] != CAMERA_DEVICE_STATUS_PRESENT) {
580         _hidl_cb(Status::ILLEGAL_ARGUMENT, nullptr);
581         return Void();
582     }
583 
584     sp<android::hardware::camera::device::V3_2::implementation::CameraDevice> deviceImpl;
585 
586     // ICameraDevice 3.4 or upper
587     if (deviceVersion >= kHAL3_4) {
588         ALOGV("Constructing v3.4+ camera device");
589         if (deviceVersion == kHAL3_4) {
590             deviceImpl = new android::hardware::camera::device::V3_4::implementation::CameraDevice(
591                     mModule, cameraId, mCameraDeviceNames);
592         } else if (deviceVersion == kHAL3_5) {
593             deviceImpl = new android::hardware::camera::device::V3_5::implementation::CameraDevice(
594                     mModule, cameraId, mCameraDeviceNames);
595         }
596         if (deviceImpl == nullptr || deviceImpl->isInitFailed()) {
597             ALOGE("%s: camera device %s init failed!", __FUNCTION__, cameraId.c_str());
598             _hidl_cb(Status::INTERNAL_ERROR, nullptr);
599             return Void();
600         }
601         IF_ALOGV() {
602             deviceImpl->getInterface()->interfaceChain([](
603                 ::android::hardware::hidl_vec<::android::hardware::hidl_string> interfaceChain) {
604                     ALOGV("Device interface chain:");
605                     for (auto iface : interfaceChain) {
606                         ALOGV("  %s", iface.c_str());
607                     }
608                 });
609         }
610         _hidl_cb (Status::OK, deviceImpl->getInterface());
611         return Void();
612     }
613 
614     // ICameraDevice 3.2 and 3.3
615     // Since some Treble HAL revisions can map to the same legacy HAL version(s), we default
616     // to the newest possible Treble HAL revision, but allow for override if needed via
617     // system property.
618     switch (mPreferredHal3MinorVersion) {
619         case 2: { // Map legacy camera device v3 HAL to Treble camera device HAL v3.2
620             ALOGV("Constructing v3.2 camera device");
621             deviceImpl = new android::hardware::camera::device::V3_2::implementation::CameraDevice(
622                     mModule, cameraId, mCameraDeviceNames);
623             if (deviceImpl == nullptr || deviceImpl->isInitFailed()) {
624                 ALOGE("%s: camera device %s init failed!", __FUNCTION__, cameraId.c_str());
625                 _hidl_cb(Status::INTERNAL_ERROR, nullptr);
626                 return Void();
627             }
628             break;
629         }
630         case 3: { // Map legacy camera device v3 HAL to Treble camera device HAL v3.3
631             ALOGV("Constructing v3.3 camera device");
632             deviceImpl = new android::hardware::camera::device::V3_3::implementation::CameraDevice(
633                     mModule, cameraId, mCameraDeviceNames);
634             if (deviceImpl == nullptr || deviceImpl->isInitFailed()) {
635                 ALOGE("%s: camera device %s init failed!", __FUNCTION__, cameraId.c_str());
636                 _hidl_cb(Status::INTERNAL_ERROR, nullptr);
637                 return Void();
638             }
639             break;
640         }
641         default:
642             ALOGE("%s: Unknown HAL minor version %d!", __FUNCTION__, mPreferredHal3MinorVersion);
643             _hidl_cb(Status::INTERNAL_ERROR, nullptr);
644             return Void();
645     }
646 
647     _hidl_cb (Status::OK, deviceImpl->getInterface());
648     return Void();
649 }
650 
651 } // namespace implementation
652 }  // namespace V2_4
653 }  // namespace provider
654 }  // namespace camera
655 }  // namespace hardware
656 }  // namespace android
657