blob: d50168a20b87847ce063ebf4ef405767b9f8b3b9 [file] [log] [blame]
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -08001/*
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"
Eino-Ville Talvala50fe4302017-08-22 16:15:09 -070018//#define LOG_NDEBUG 0
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -080019#include <android/log.h>
20
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -080021#include "CameraProvider.h"
Yin-Chia Yeh248ed702017-01-23 17:27:26 -080022#include "CameraDevice_1_0.h"
Eino-Ville Talvala50fe4302017-08-22 16:15:09 -070023#include "CameraDevice_3_3.h"
24#include <cutils/properties.h>
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -080025#include <string.h>
26#include <utils/Trace.h>
27
28
29namespace android {
30namespace hardware {
31namespace camera {
32namespace provider {
33namespace V2_4 {
34namespace implementation {
35
36namespace {
37const char *kLegacyProviderName = "legacy/0";
38// "device@<version>/legacy/<id>"
39const std::regex kDeviceNameRE("device@([0-9]+\\.[0-9]+)/legacy/(.+)");
40const char *kHAL3_2 = "3.2";
Eino-Ville Talvala50fe4302017-08-22 16:15:09 -070041const char *kHAL3_3 = "3.3";
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -080042const char *kHAL1_0 = "1.0";
43const int kMaxCameraDeviceNameLen = 128;
44const int kMaxCameraIdLen = 16;
45
Andreas Gampe0b171f12017-04-04 20:02:25 -070046bool matchDeviceName(const hidl_string& deviceName, std::string* deviceVersion,
47 std::string* cameraId) {
48 std::string deviceNameStd(deviceName.c_str());
49 std::smatch sm;
50 if (std::regex_match(deviceNameStd, sm, kDeviceNameRE)) {
51 if (deviceVersion != nullptr) {
52 *deviceVersion = sm[1];
53 }
54 if (cameraId != nullptr) {
55 *cameraId = sm[2];
56 }
57 return true;
58 }
59 return false;
60}
61
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -080062} // anonymous namespace
63
64using ::android::hardware::camera::common::V1_0::CameraMetadataType;
65using ::android::hardware::camera::common::V1_0::Status;
66
67/**
68 * static callback forwarding methods from HAL to instance
69 */
70void CameraProvider::sCameraDeviceStatusChange(
71 const struct camera_module_callbacks* callbacks,
72 int camera_id,
73 int new_status) {
Yin-Chia Yeh6dc9b532017-02-09 18:43:35 -080074 CameraProvider* cp = const_cast<CameraProvider*>(
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -080075 static_cast<const CameraProvider*>(callbacks));
76
77 if (cp == nullptr) {
78 ALOGE("%s: callback ops is null", __FUNCTION__);
79 return;
80 }
81
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -080082 Mutex::Autolock _l(cp->mCbLock);
83 char cameraId[kMaxCameraIdLen];
84 snprintf(cameraId, sizeof(cameraId), "%d", camera_id);
85 std::string cameraIdStr(cameraId);
86 cp->mCameraStatusMap[cameraIdStr] = (camera_device_status_t) new_status;
87 if (cp->mCallbacks != nullptr) {
88 CameraDeviceStatus status = (CameraDeviceStatus) new_status;
89 for (auto const& deviceNamePair : cp->mCameraDeviceNames) {
90 if (cameraIdStr.compare(deviceNamePair.first) == 0) {
91 cp->mCallbacks->cameraDeviceStatusChange(
92 deviceNamePair.second, status);
93 }
94 }
95 }
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -080096}
97
98void CameraProvider::sTorchModeStatusChange(
99 const struct camera_module_callbacks* callbacks,
100 const char* camera_id,
101 int new_status) {
Yin-Chia Yeh6dc9b532017-02-09 18:43:35 -0800102 CameraProvider* cp = const_cast<CameraProvider*>(
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -0800103 static_cast<const CameraProvider*>(callbacks));
104
105 if (cp == nullptr) {
106 ALOGE("%s: callback ops is null", __FUNCTION__);
107 return;
108 }
109
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -0800110 Mutex::Autolock _l(cp->mCbLock);
111 if (cp->mCallbacks != nullptr) {
112 std::string cameraIdStr(camera_id);
113 TorchModeStatus status = (TorchModeStatus) new_status;
114 for (auto const& deviceNamePair : cp->mCameraDeviceNames) {
Yin-Chia Yeh9c6dbd52016-12-22 14:55:02 -0800115 if (cameraIdStr.compare(deviceNamePair.first) == 0) {
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -0800116 cp->mCallbacks->torchModeStatusChange(
117 deviceNamePair.second, status);
118 }
119 }
120 }
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -0800121}
122
123Status CameraProvider::getHidlStatus(int status) {
124 switch (status) {
125 case 0: return Status::OK;
126 case -ENODEV: return Status::INTERNAL_ERROR;
127 case -EINVAL: return Status::ILLEGAL_ARGUMENT;
128 default:
129 ALOGE("%s: unknown HAL status code %d", __FUNCTION__, status);
130 return Status::INTERNAL_ERROR;
131 }
132}
133
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -0800134std::string CameraProvider::getLegacyCameraId(const hidl_string& deviceName) {
Andreas Gampe0b171f12017-04-04 20:02:25 -0700135 std::string cameraId;
136 matchDeviceName(deviceName, nullptr, &cameraId);
137 return cameraId;
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -0800138}
139
140int CameraProvider::getCameraDeviceVersion(const hidl_string& deviceName) {
Andreas Gampe0b171f12017-04-04 20:02:25 -0700141 std::string deviceVersion;
142 bool match = matchDeviceName(deviceName, &deviceVersion, nullptr);
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -0800143 if (!match) {
144 return -1;
145 }
Eino-Ville Talvala50fe4302017-08-22 16:15:09 -0700146 if (deviceVersion == kHAL3_3) {
147 return CAMERA_DEVICE_API_VERSION_3_3;
148 } else if (deviceVersion == kHAL3_2) {
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -0800149 return CAMERA_DEVICE_API_VERSION_3_2;
Andreas Gampe0b171f12017-04-04 20:02:25 -0700150 } else if (deviceVersion == kHAL1_0) {
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -0800151 return CAMERA_DEVICE_API_VERSION_1_0;
152 }
153 return 0;
154}
155
156std::string CameraProvider::getHidlDeviceName(
157 std::string cameraId, int deviceVersion) {
158 // Maybe consider create a version check method and SortedVec to speed up?
159 if (deviceVersion != CAMERA_DEVICE_API_VERSION_1_0 &&
160 deviceVersion != CAMERA_DEVICE_API_VERSION_3_2 &&
161 deviceVersion != CAMERA_DEVICE_API_VERSION_3_3 &&
162 deviceVersion != CAMERA_DEVICE_API_VERSION_3_4 ) {
163 return hidl_string("");
164 }
Eino-Ville Talvala50fe4302017-08-22 16:15:09 -0700165 bool isV1 = deviceVersion == CAMERA_DEVICE_API_VERSION_1_0;
166 int versionMajor = isV1 ? 1 : 3;
167 int versionMinor = isV1 ? 0 : mPreferredHal3MinorVersion;
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -0800168 char deviceName[kMaxCameraDeviceNameLen];
Eino-Ville Talvala50fe4302017-08-22 16:15:09 -0700169 snprintf(deviceName, sizeof(deviceName), "device@%d.%d/legacy/%s",
170 versionMajor, versionMinor, cameraId.c_str());
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -0800171 return deviceName;
172}
173
174CameraProvider::CameraProvider() :
175 camera_module_callbacks_t({sCameraDeviceStatusChange,
176 sTorchModeStatusChange}) {
177 mInitFailed = initialize();
178}
179
180CameraProvider::~CameraProvider() {}
181
182bool CameraProvider::initialize() {
183 camera_module_t *rawModule;
184 int err = hw_get_module(CAMERA_HARDWARE_MODULE_ID,
185 (const hw_module_t **)&rawModule);
186 if (err < 0) {
187 ALOGE("Could not load camera HAL module: %d (%s)", err, strerror(-err));
188 return true;
189 }
190
191 mModule = new CameraModule(rawModule);
192 err = mModule->init();
193 if (err != OK) {
Yin-Chia Yehfca2e742017-01-31 16:00:20 -0800194 ALOGE("Could not initialize camera HAL module: %d (%s)", err, strerror(-err));
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -0800195 mModule.clear();
196 return true;
197 }
198 ALOGI("Loaded \"%s\" camera module", mModule->getModuleName());
199
Shuzhen Wangefb7bfa2017-03-15 18:26:39 -0700200 // Setup vendor tags here so HAL can setup vendor keys in camera characteristics
201 VendorTagDescriptor::clearGlobalVendorTagDescriptor();
202 if (!setUpVendorTags()) {
203 ALOGE("%s: Vendor tag setup failed, will not be available.", __FUNCTION__);
204 }
205
Yin-Chia Yehfca2e742017-01-31 16:00:20 -0800206 // Setup callback now because we are going to try openLegacy next
207 err = mModule->setCallbacks(this);
208 if (err != OK) {
209 ALOGE("Could not set camera module callback: %d (%s)", err, strerror(-err));
210 mModule.clear();
211 return true;
212 }
213
Eino-Ville Talvala50fe4302017-08-22 16:15:09 -0700214 mPreferredHal3MinorVersion = property_get_int32("ro.camera.wrapper.hal3TrebleMinorVersion", 3);
215 ALOGV("Preferred HAL 3 minor version is %d", mPreferredHal3MinorVersion);
216 switch(mPreferredHal3MinorVersion) {
217 case 2:
218 case 3:
219 // OK
220 break;
221 default:
222 ALOGW("Unknown minor camera device HAL version %d in property "
223 "'camera.wrapper.hal3TrebleMinorVersion', defaulting to 3", mPreferredHal3MinorVersion);
224 mPreferredHal3MinorVersion = 3;
225 }
226
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -0800227 mNumberOfLegacyCameras = mModule->getNumberOfCameras();
228 for (int i = 0; i < mNumberOfLegacyCameras; i++) {
Emilian Peevc9ded512017-04-10 16:12:55 +0100229 struct camera_info info;
230 auto rc = mModule->getCameraInfo(i, &info);
231 if (rc != NO_ERROR) {
232 ALOGE("%s: Camera info query failed!", __func__);
233 mModule.clear();
234 return true;
235 }
236
237 if (checkCameraVersion(i, info) != OK) {
238 ALOGE("%s: Camera version check failed!", __func__);
239 mModule.clear();
240 return true;
241 }
242
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -0800243 char cameraId[kMaxCameraIdLen];
244 snprintf(cameraId, sizeof(cameraId), "%d", i);
245 std::string cameraIdStr(cameraId);
246 mCameraStatusMap[cameraIdStr] = CAMERA_DEVICE_STATUS_PRESENT;
247 mCameraIds.add(cameraIdStr);
248
249 // initialize mCameraDeviceNames and mOpenLegacySupported
250 mOpenLegacySupported[cameraIdStr] = false;
251 int deviceVersion = mModule->getDeviceVersion(i);
252 mCameraDeviceNames.add(
253 std::make_pair(cameraIdStr,
254 getHidlDeviceName(cameraIdStr, deviceVersion)));
255 if (deviceVersion >= CAMERA_DEVICE_API_VERSION_3_2 &&
256 mModule->isOpenLegacyDefined()) {
257 // try open_legacy to see if it actually works
258 struct hw_device_t* halDev = nullptr;
259 int ret = mModule->openLegacy(cameraId, CAMERA_DEVICE_API_VERSION_1_0, &halDev);
260 if (ret == 0) {
261 mOpenLegacySupported[cameraIdStr] = true;
262 halDev->close(halDev);
263 mCameraDeviceNames.add(
264 std::make_pair(cameraIdStr,
265 getHidlDeviceName(cameraIdStr, CAMERA_DEVICE_API_VERSION_1_0)));
266 } else if (ret == -EBUSY || ret == -EUSERS) {
267 // Looks like this provider instance is not initialized during
268 // system startup and there are other camera users already.
269 // Not a good sign but not fatal.
270 ALOGW("%s: open_legacy try failed!", __FUNCTION__);
271 }
272 }
273 }
274
Eino-Ville Talvala0f5eb832017-02-09 19:45:31 -0800275 return false; // mInitFailed
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -0800276}
277
Emilian Peevc9ded512017-04-10 16:12:55 +0100278/**
279 * Check that the device HAL version is still in supported.
280 */
281int CameraProvider::checkCameraVersion(int id, camera_info info) {
282 if (mModule == nullptr) {
283 return NO_INIT;
284 }
285
286 // device_version undefined in CAMERA_MODULE_API_VERSION_1_0,
287 // All CAMERA_MODULE_API_VERSION_1_0 devices are backward-compatible
288 if (mModule->getModuleApiVersion() >= CAMERA_MODULE_API_VERSION_2_0) {
289 // Verify the device version is in the supported range
290 switch (info.device_version) {
291 case CAMERA_DEVICE_API_VERSION_1_0:
292 case CAMERA_DEVICE_API_VERSION_3_2:
293 case CAMERA_DEVICE_API_VERSION_3_3:
294 case CAMERA_DEVICE_API_VERSION_3_4:
295 // in support
296 break;
297 case CAMERA_DEVICE_API_VERSION_2_0:
298 case CAMERA_DEVICE_API_VERSION_2_1:
299 case CAMERA_DEVICE_API_VERSION_3_0:
300 case CAMERA_DEVICE_API_VERSION_3_1:
301 // no longer supported
302 default:
303 ALOGE("%s: Device %d has HAL version %x, which is not supported",
304 __FUNCTION__, id, info.device_version);
305 return NO_INIT;
306 }
307 }
308
309 return OK;
310}
311
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -0800312bool CameraProvider::setUpVendorTags() {
313 ATRACE_CALL();
314 vendor_tag_ops_t vOps = vendor_tag_ops_t();
315
316 // Check if vendor operations have been implemented
317 if (!mModule->isVendorTagDefined()) {
318 ALOGI("%s: No vendor tags defined for this device.", __FUNCTION__);
Eino-Ville Talvala0f5eb832017-02-09 19:45:31 -0800319 return true;
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -0800320 }
321
322 mModule->getVendorTagOps(&vOps);
323
324 // Ensure all vendor operations are present
325 if (vOps.get_tag_count == nullptr || vOps.get_all_tags == nullptr ||
326 vOps.get_section_name == nullptr || vOps.get_tag_name == nullptr ||
327 vOps.get_tag_type == nullptr) {
328 ALOGE("%s: Vendor tag operations not fully defined. Ignoring definitions."
329 , __FUNCTION__);
330 return false;
331 }
332
333 // Read all vendor tag definitions into a descriptor
334 sp<VendorTagDescriptor> desc;
335 status_t res;
336 if ((res = VendorTagDescriptor::createDescriptorFromOps(&vOps, /*out*/desc))
337 != OK) {
338 ALOGE("%s: Could not generate descriptor from vendor tag operations,"
339 "received error %s (%d). Camera clients will not be able to use"
340 "vendor tags", __FUNCTION__, strerror(res), res);
341 return false;
342 }
343
344 // Set the global descriptor to use with camera metadata
345 VendorTagDescriptor::setAsGlobalVendorTagDescriptor(desc);
346 const SortedVector<String8>* sectionNames = desc->getAllSectionNames();
347 size_t numSections = sectionNames->size();
348 std::vector<std::vector<VendorTag>> tagsBySection(numSections);
349 int tagCount = desc->getTagCount();
350 std::vector<uint32_t> tags(tagCount);
351 desc->getTagArray(tags.data());
352 for (int i = 0; i < tagCount; i++) {
353 VendorTag vt;
354 vt.tagId = tags[i];
355 vt.tagName = desc->getTagName(tags[i]);
356 vt.tagType = (CameraMetadataType) desc->getTagType(tags[i]);
357 ssize_t sectionIdx = desc->getSectionIndex(tags[i]);
358 tagsBySection[sectionIdx].push_back(vt);
359 }
360 mVendorTagSections.resize(numSections);
361 for (size_t s = 0; s < numSections; s++) {
362 mVendorTagSections[s].sectionName = (*sectionNames)[s].string();
363 mVendorTagSections[s].tags = tagsBySection[s];
364 }
365 return true;
366}
367
368// Methods from ::android::hardware::camera::provider::V2_4::ICameraProvider follow.
369Return<Status> CameraProvider::setCallback(const sp<ICameraProviderCallback>& callback) {
Yin-Chia Yehfca2e742017-01-31 16:00:20 -0800370 Mutex::Autolock _l(mCbLock);
371 mCallbacks = callback;
372 return Status::OK;
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -0800373}
374
375Return<void> CameraProvider::getVendorTags(getVendorTags_cb _hidl_cb) {
376 _hidl_cb(Status::OK, mVendorTagSections);
377 return Void();
378}
379
380Return<void> CameraProvider::getCameraIdList(getCameraIdList_cb _hidl_cb) {
381 std::vector<hidl_string> deviceNameList;
382 for (auto const& deviceNamePair : mCameraDeviceNames) {
383 if (mCameraStatusMap[deviceNamePair.first] == CAMERA_DEVICE_STATUS_PRESENT) {
384 deviceNameList.push_back(deviceNamePair.second);
385 }
386 }
387 hidl_vec<hidl_string> hidlDeviceNameList(deviceNameList);
Yin-Chia Yeh9c6dbd52016-12-22 14:55:02 -0800388 _hidl_cb(Status::OK, hidlDeviceNameList);
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -0800389 return Void();
390}
391
392Return<void> CameraProvider::isSetTorchModeSupported(isSetTorchModeSupported_cb _hidl_cb) {
393 bool support = mModule->isSetTorchModeSupported();
394 _hidl_cb (Status::OK, support);
395 return Void();
396}
397
Yin-Chia Yeh9c6dbd52016-12-22 14:55:02 -0800398Return<void> CameraProvider::getCameraDeviceInterface_V1_x(
Yin-Chia Yeh248ed702017-01-23 17:27:26 -0800399 const hidl_string& cameraDeviceName, getCameraDeviceInterface_V1_x_cb _hidl_cb) {
Andreas Gampe0b171f12017-04-04 20:02:25 -0700400 std::string cameraId, deviceVersion;
401 bool match = matchDeviceName(cameraDeviceName, &deviceVersion, &cameraId);
Yin-Chia Yeh248ed702017-01-23 17:27:26 -0800402 if (!match) {
403 _hidl_cb(Status::ILLEGAL_ARGUMENT, nullptr);
404 return Void();
405 }
406
Yin-Chia Yeh248ed702017-01-23 17:27:26 -0800407 std::string deviceName(cameraDeviceName.c_str());
408 ssize_t index = mCameraDeviceNames.indexOf(std::make_pair(cameraId, deviceName));
409 if (index == NAME_NOT_FOUND) { // Either an illegal name or a device version mismatch
410 Status status = Status::OK;
411 ssize_t idx = mCameraIds.indexOf(cameraId);
412 if (idx == NAME_NOT_FOUND) {
413 ALOGE("%s: cannot find camera %s!", __FUNCTION__, cameraId.c_str());
414 status = Status::ILLEGAL_ARGUMENT;
415 } else { // invalid version
416 ALOGE("%s: camera device %s does not support version %s!",
417 __FUNCTION__, cameraId.c_str(), deviceVersion.c_str());
418 status = Status::OPERATION_NOT_SUPPORTED;
419 }
420 _hidl_cb(status, nullptr);
421 return Void();
422 }
423
424 if (mCameraStatusMap.count(cameraId) == 0 ||
425 mCameraStatusMap[cameraId] != CAMERA_DEVICE_STATUS_PRESENT) {
426 _hidl_cb(Status::ILLEGAL_ARGUMENT, nullptr);
427 return Void();
428 }
429
430 sp<android::hardware::camera::device::V1_0::implementation::CameraDevice> device =
431 new android::hardware::camera::device::V1_0::implementation::CameraDevice(
432 mModule, cameraId, mCameraDeviceNames);
433
434 if (device == nullptr) {
435 ALOGE("%s: cannot allocate camera device for id %s", __FUNCTION__, cameraId.c_str());
436 _hidl_cb(Status::INTERNAL_ERROR, nullptr);
437 return Void();
438 }
439
440 if (device->isInitFailed()) {
441 ALOGE("%s: camera device %s init failed!", __FUNCTION__, cameraId.c_str());
442 device = nullptr;
443 _hidl_cb(Status::INTERNAL_ERROR, nullptr);
444 return Void();
445 }
446
447 _hidl_cb (Status::OK, device);
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -0800448 return Void();
449}
450
Yin-Chia Yeh9c6dbd52016-12-22 14:55:02 -0800451Return<void> CameraProvider::getCameraDeviceInterface_V3_x(
452 const hidl_string& cameraDeviceName, getCameraDeviceInterface_V3_x_cb _hidl_cb) {
Andreas Gampe0b171f12017-04-04 20:02:25 -0700453 std::string cameraId, deviceVersion;
454 bool match = matchDeviceName(cameraDeviceName, &deviceVersion, &cameraId);
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -0800455 if (!match) {
456 _hidl_cb(Status::ILLEGAL_ARGUMENT, nullptr);
457 return Void();
458 }
459
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -0800460 std::string deviceName(cameraDeviceName.c_str());
461 ssize_t index = mCameraDeviceNames.indexOf(std::make_pair(cameraId, deviceName));
462 if (index == NAME_NOT_FOUND) { // Either an illegal name or a device version mismatch
463 Status status = Status::OK;
464 ssize_t idx = mCameraIds.indexOf(cameraId);
465 if (idx == NAME_NOT_FOUND) {
Yin-Chia Yeh9c6dbd52016-12-22 14:55:02 -0800466 ALOGE("%s: cannot find camera %s!", __FUNCTION__, cameraId.c_str());
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -0800467 status = Status::ILLEGAL_ARGUMENT;
468 } else { // invalid version
Yin-Chia Yeh9c6dbd52016-12-22 14:55:02 -0800469 ALOGE("%s: camera device %s does not support version %s!",
470 __FUNCTION__, cameraId.c_str(), deviceVersion.c_str());
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -0800471 status = Status::OPERATION_NOT_SUPPORTED;
472 }
473 _hidl_cb(status, nullptr);
474 return Void();
475 }
476
477 if (mCameraStatusMap.count(cameraId) == 0 ||
478 mCameraStatusMap[cameraId] != CAMERA_DEVICE_STATUS_PRESENT) {
479 _hidl_cb(Status::ILLEGAL_ARGUMENT, nullptr);
480 return Void();
481 }
482
Eino-Ville Talvala50fe4302017-08-22 16:15:09 -0700483 // Since some Treble HAL revisions can map to the same legacy HAL version(s), we default
484 // to the newest possible Treble HAL revision, but allow for override if needed via
485 // system property.
486 sp<android::hardware::camera::device::V3_2::ICameraDevice> device;
487 switch (mPreferredHal3MinorVersion) {
488 case 2: { // Map legacy camera device v3 HAL to Treble camera device HAL v3.2
489 ALOGV("Constructing v3.2 camera device");
490 sp<android::hardware::camera::device::V3_2::implementation::CameraDevice> deviceImpl =
491 new android::hardware::camera::device::V3_2::implementation::CameraDevice(
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -0800492 mModule, cameraId, mCameraDeviceNames);
Eino-Ville Talvala50fe4302017-08-22 16:15:09 -0700493 if (deviceImpl == nullptr || deviceImpl->isInitFailed()) {
494 ALOGE("%s: camera device %s init failed!", __FUNCTION__, cameraId.c_str());
495 device = nullptr;
496 _hidl_cb(Status::INTERNAL_ERROR, nullptr);
497 return Void();
498 }
499 device = deviceImpl;
500 break;
501 }
502 case 3: { // Map legacy camera device v3 HAL to Treble camera device HAL v3.3
503 ALOGV("Constructing v3.3 camera device");
504 sp<android::hardware::camera::device::V3_2::implementation::CameraDevice> deviceImpl =
505 new android::hardware::camera::device::V3_3::implementation::CameraDevice(
506 mModule, cameraId, mCameraDeviceNames);
507 if (deviceImpl == nullptr || deviceImpl->isInitFailed()) {
508 ALOGE("%s: camera device %s init failed!", __FUNCTION__, cameraId.c_str());
509 device = nullptr;
510 _hidl_cb(Status::INTERNAL_ERROR, nullptr);
511 return Void();
512 }
513 device = deviceImpl;
514 break;
515 }
516 default:
517 ALOGE("%s: Unknown HAL minor version %d!", __FUNCTION__, mPreferredHal3MinorVersion);
518 device = nullptr;
519 _hidl_cb(Status::INTERNAL_ERROR, nullptr);
520 return Void();
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -0800521 }
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -0800522 _hidl_cb (Status::OK, device);
523 return Void();
524}
525
526ICameraProvider* HIDL_FETCH_ICameraProvider(const char* name) {
527 if (strcmp(name, kLegacyProviderName) != 0) {
528 return nullptr;
529 }
530 CameraProvider* provider = new CameraProvider();
531 if (provider == nullptr) {
532 ALOGE("%s: cannot allocate camera provider!", __FUNCTION__);
533 return nullptr;
534 }
535 if (provider->isInitFailed()) {
536 ALOGE("%s: camera provider init failed!", __FUNCTION__);
537 delete provider;
538 return nullptr;
539 }
540 return provider;
541}
542
543} // namespace implementation
544} // namespace V2_4
545} // namespace provider
546} // namespace camera
547} // namespace hardware
548} // namespace android