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