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].c_str();
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 if (callback == nullptr) {
454 return Status::OK;
455 }
456 // Add and report all presenting external cameras.
457 for (auto const& statusPair : mCameraStatusMap) {
458 int id = std::stoi(statusPair.first);
459 auto status = static_cast<CameraDeviceStatus>(statusPair.second);
460 if (id >= mNumberOfLegacyCameras && status != CameraDeviceStatus::NOT_PRESENT) {
461 addDeviceNames(id, status, true);
462 }
463 }
464
465 return Status::OK;
466 }
467
getVendorTags(ICameraProvider::getVendorTags_cb _hidl_cb)468 Return<void> LegacyCameraProviderImpl_2_4::getVendorTags(
469 ICameraProvider::getVendorTags_cb _hidl_cb) {
470 _hidl_cb(Status::OK, mVendorTagSections);
471 return Void();
472 }
473
getCameraIdList(ICameraProvider::getCameraIdList_cb _hidl_cb)474 Return<void> LegacyCameraProviderImpl_2_4::getCameraIdList(
475 ICameraProvider::getCameraIdList_cb _hidl_cb) {
476 std::vector<hidl_string> deviceNameList;
477 for (auto const& deviceNamePair : mCameraDeviceNames) {
478 if (std::stoi(deviceNamePair.first) >= mNumberOfLegacyCameras) {
479 // External camera devices must be reported through the device status change callback,
480 // not in this list.
481 continue;
482 }
483 if (mCameraStatusMap[deviceNamePair.first] == CAMERA_DEVICE_STATUS_PRESENT) {
484 deviceNameList.push_back(deviceNamePair.second);
485 }
486 }
487 hidl_vec<hidl_string> hidlDeviceNameList(deviceNameList);
488 _hidl_cb(Status::OK, hidlDeviceNameList);
489 return Void();
490 }
491
isSetTorchModeSupported(ICameraProvider::isSetTorchModeSupported_cb _hidl_cb)492 Return<void> LegacyCameraProviderImpl_2_4::isSetTorchModeSupported(
493 ICameraProvider::isSetTorchModeSupported_cb _hidl_cb) {
494 bool support = mModule->isSetTorchModeSupported();
495 _hidl_cb (Status::OK, support);
496 return Void();
497 }
498
getCameraDeviceInterface_V1_x(const hidl_string & cameraDeviceName,ICameraProvider::getCameraDeviceInterface_V1_x_cb _hidl_cb)499 Return<void> LegacyCameraProviderImpl_2_4::getCameraDeviceInterface_V1_x(
500 const hidl_string& cameraDeviceName,
501 ICameraProvider::getCameraDeviceInterface_V1_x_cb _hidl_cb) {
502 std::string cameraId, deviceVersion;
503 bool match = matchDeviceName(cameraDeviceName, &deviceVersion, &cameraId);
504 if (!match) {
505 _hidl_cb(Status::ILLEGAL_ARGUMENT, nullptr);
506 return Void();
507 }
508
509 std::string deviceName(cameraDeviceName.c_str());
510 ssize_t index = mCameraDeviceNames.indexOf(std::make_pair(cameraId, deviceName));
511 if (index == NAME_NOT_FOUND) { // Either an illegal name or a device version mismatch
512 Status status = Status::OK;
513 ssize_t idx = mCameraIds.indexOf(cameraId);
514 if (idx == NAME_NOT_FOUND) {
515 ALOGE("%s: cannot find camera %s!", __FUNCTION__, cameraId.c_str());
516 status = Status::ILLEGAL_ARGUMENT;
517 } else { // invalid version
518 ALOGE("%s: camera device %s does not support version %s!",
519 __FUNCTION__, cameraId.c_str(), deviceVersion.c_str());
520 status = Status::OPERATION_NOT_SUPPORTED;
521 }
522 _hidl_cb(status, nullptr);
523 return Void();
524 }
525
526 if (mCameraStatusMap.count(cameraId) == 0 ||
527 mCameraStatusMap[cameraId] != CAMERA_DEVICE_STATUS_PRESENT) {
528 _hidl_cb(Status::ILLEGAL_ARGUMENT, nullptr);
529 return Void();
530 }
531
532 sp<android::hardware::camera::device::V1_0::implementation::CameraDevice> device =
533 new android::hardware::camera::device::V1_0::implementation::CameraDevice(
534 mModule, cameraId, mCameraDeviceNames);
535
536 if (device == nullptr) {
537 ALOGE("%s: cannot allocate camera device for id %s", __FUNCTION__, cameraId.c_str());
538 _hidl_cb(Status::INTERNAL_ERROR, nullptr);
539 return Void();
540 }
541
542 if (device->isInitFailed()) {
543 ALOGE("%s: camera device %s init failed!", __FUNCTION__, cameraId.c_str());
544 device = nullptr;
545 _hidl_cb(Status::INTERNAL_ERROR, nullptr);
546 return Void();
547 }
548
549 _hidl_cb (Status::OK, device);
550 return Void();
551 }
552
getCameraDeviceInterface_V3_x(const hidl_string & cameraDeviceName,ICameraProvider::getCameraDeviceInterface_V3_x_cb _hidl_cb)553 Return<void> LegacyCameraProviderImpl_2_4::getCameraDeviceInterface_V3_x(
554 const hidl_string& cameraDeviceName,
555 ICameraProvider::getCameraDeviceInterface_V3_x_cb _hidl_cb) {
556 std::string cameraId, deviceVersion;
557 bool match = matchDeviceName(cameraDeviceName, &deviceVersion, &cameraId);
558 if (!match) {
559 _hidl_cb(Status::ILLEGAL_ARGUMENT, nullptr);
560 return Void();
561 }
562
563 std::string deviceName(cameraDeviceName.c_str());
564 ssize_t index = mCameraDeviceNames.indexOf(std::make_pair(cameraId, deviceName));
565 if (index == NAME_NOT_FOUND) { // Either an illegal name or a device version mismatch
566 Status status = Status::OK;
567 ssize_t idx = mCameraIds.indexOf(cameraId);
568 if (idx == NAME_NOT_FOUND) {
569 ALOGE("%s: cannot find camera %s!", __FUNCTION__, cameraId.c_str());
570 status = Status::ILLEGAL_ARGUMENT;
571 } else { // invalid version
572 ALOGE("%s: camera device %s does not support version %s!",
573 __FUNCTION__, cameraId.c_str(), deviceVersion.c_str());
574 status = Status::OPERATION_NOT_SUPPORTED;
575 }
576 _hidl_cb(status, nullptr);
577 return Void();
578 }
579
580 if (mCameraStatusMap.count(cameraId) == 0 ||
581 mCameraStatusMap[cameraId] != CAMERA_DEVICE_STATUS_PRESENT) {
582 _hidl_cb(Status::ILLEGAL_ARGUMENT, nullptr);
583 return Void();
584 }
585
586 sp<android::hardware::camera::device::V3_2::implementation::CameraDevice> deviceImpl;
587
588 // ICameraDevice 3.4 or upper
589 if (deviceVersion >= kHAL3_4) {
590 ALOGV("Constructing v3.4+ camera device");
591 if (deviceVersion == kHAL3_4) {
592 deviceImpl = new android::hardware::camera::device::V3_4::implementation::CameraDevice(
593 mModule, cameraId, mCameraDeviceNames);
594 } else if (deviceVersion == kHAL3_5) {
595 deviceImpl = new android::hardware::camera::device::V3_5::implementation::CameraDevice(
596 mModule, cameraId, mCameraDeviceNames);
597 }
598 if (deviceImpl == nullptr || deviceImpl->isInitFailed()) {
599 ALOGE("%s: camera device %s init failed!", __FUNCTION__, cameraId.c_str());
600 _hidl_cb(Status::INTERNAL_ERROR, nullptr);
601 return Void();
602 }
603 IF_ALOGV() {
604 deviceImpl->getInterface()->interfaceChain([](
605 ::android::hardware::hidl_vec<::android::hardware::hidl_string> interfaceChain) {
606 ALOGV("Device interface chain:");
607 for (auto iface : interfaceChain) {
608 ALOGV(" %s", iface.c_str());
609 }
610 });
611 }
612 _hidl_cb (Status::OK, deviceImpl->getInterface());
613 return Void();
614 }
615
616 // ICameraDevice 3.2 and 3.3
617 // Since some Treble HAL revisions can map to the same legacy HAL version(s), we default
618 // to the newest possible Treble HAL revision, but allow for override if needed via
619 // system property.
620 switch (mPreferredHal3MinorVersion) {
621 case 2: { // Map legacy camera device v3 HAL to Treble camera device HAL v3.2
622 ALOGV("Constructing v3.2 camera device");
623 deviceImpl = new android::hardware::camera::device::V3_2::implementation::CameraDevice(
624 mModule, cameraId, mCameraDeviceNames);
625 if (deviceImpl == nullptr || deviceImpl->isInitFailed()) {
626 ALOGE("%s: camera device %s init failed!", __FUNCTION__, cameraId.c_str());
627 _hidl_cb(Status::INTERNAL_ERROR, nullptr);
628 return Void();
629 }
630 break;
631 }
632 case 3: { // Map legacy camera device v3 HAL to Treble camera device HAL v3.3
633 ALOGV("Constructing v3.3 camera device");
634 deviceImpl = new android::hardware::camera::device::V3_3::implementation::CameraDevice(
635 mModule, cameraId, mCameraDeviceNames);
636 if (deviceImpl == nullptr || deviceImpl->isInitFailed()) {
637 ALOGE("%s: camera device %s init failed!", __FUNCTION__, cameraId.c_str());
638 _hidl_cb(Status::INTERNAL_ERROR, nullptr);
639 return Void();
640 }
641 break;
642 }
643 default:
644 ALOGE("%s: Unknown HAL minor version %d!", __FUNCTION__, mPreferredHal3MinorVersion);
645 _hidl_cb(Status::INTERNAL_ERROR, nullptr);
646 return Void();
647 }
648
649 _hidl_cb (Status::OK, deviceImpl->getInterface());
650 return Void();
651 }
652
653 } // namespace implementation
654 } // namespace V2_4
655 } // namespace provider
656 } // namespace camera
657 } // namespace hardware
658 } // namespace android
659