blob: ed974a57d00880ab379634451bf73a89aeb8f740 [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"
Emilian Peeve18057b2017-11-13 16:03:44 +000024#include "CameraDevice_3_4.h"
Eino-Ville Talvala50fe4302017-08-22 16:15:09 -070025#include <cutils/properties.h>
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -080026#include <string.h>
27#include <utils/Trace.h>
28
29
30namespace android {
31namespace hardware {
32namespace camera {
33namespace provider {
34namespace V2_4 {
35namespace implementation {
36
37namespace {
38const char *kLegacyProviderName = "legacy/0";
39// "device@<version>/legacy/<id>"
40const std::regex kDeviceNameRE("device@([0-9]+\\.[0-9]+)/legacy/(.+)");
41const char *kHAL3_2 = "3.2";
Eino-Ville Talvala50fe4302017-08-22 16:15:09 -070042const char *kHAL3_3 = "3.3";
Emilian Peeve18057b2017-11-13 16:03:44 +000043const char *kHAL3_4 = "3.4";
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -080044const char *kHAL1_0 = "1.0";
45const int kMaxCameraDeviceNameLen = 128;
46const int kMaxCameraIdLen = 16;
47
Andreas Gampe0b171f12017-04-04 20:02:25 -070048bool matchDeviceName(const hidl_string& deviceName, std::string* deviceVersion,
49 std::string* cameraId) {
50 std::string deviceNameStd(deviceName.c_str());
51 std::smatch sm;
52 if (std::regex_match(deviceNameStd, sm, kDeviceNameRE)) {
53 if (deviceVersion != nullptr) {
54 *deviceVersion = sm[1];
55 }
56 if (cameraId != nullptr) {
57 *cameraId = sm[2];
58 }
59 return true;
60 }
61 return false;
62}
63
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -080064} // anonymous namespace
65
66using ::android::hardware::camera::common::V1_0::CameraMetadataType;
67using ::android::hardware::camera::common::V1_0::Status;
68
69/**
70 * static callback forwarding methods from HAL to instance
71 */
72void CameraProvider::sCameraDeviceStatusChange(
73 const struct camera_module_callbacks* callbacks,
74 int camera_id,
75 int new_status) {
Yin-Chia Yeh6dc9b532017-02-09 18:43:35 -080076 CameraProvider* cp = const_cast<CameraProvider*>(
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -080077 static_cast<const CameraProvider*>(callbacks));
78
79 if (cp == nullptr) {
80 ALOGE("%s: callback ops is null", __FUNCTION__);
81 return;
82 }
83
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -080084 Mutex::Autolock _l(cp->mCbLock);
85 char cameraId[kMaxCameraIdLen];
86 snprintf(cameraId, sizeof(cameraId), "%d", camera_id);
87 std::string cameraIdStr(cameraId);
88 cp->mCameraStatusMap[cameraIdStr] = (camera_device_status_t) new_status;
89 if (cp->mCallbacks != nullptr) {
90 CameraDeviceStatus status = (CameraDeviceStatus) new_status;
91 for (auto const& deviceNamePair : cp->mCameraDeviceNames) {
92 if (cameraIdStr.compare(deviceNamePair.first) == 0) {
93 cp->mCallbacks->cameraDeviceStatusChange(
94 deviceNamePair.second, status);
95 }
96 }
97 }
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -080098}
99
100void CameraProvider::sTorchModeStatusChange(
101 const struct camera_module_callbacks* callbacks,
102 const char* camera_id,
103 int new_status) {
Yin-Chia Yeh6dc9b532017-02-09 18:43:35 -0800104 CameraProvider* cp = const_cast<CameraProvider*>(
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -0800105 static_cast<const CameraProvider*>(callbacks));
106
107 if (cp == nullptr) {
108 ALOGE("%s: callback ops is null", __FUNCTION__);
109 return;
110 }
111
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -0800112 Mutex::Autolock _l(cp->mCbLock);
113 if (cp->mCallbacks != nullptr) {
114 std::string cameraIdStr(camera_id);
115 TorchModeStatus status = (TorchModeStatus) new_status;
116 for (auto const& deviceNamePair : cp->mCameraDeviceNames) {
Yin-Chia Yeh9c6dbd52016-12-22 14:55:02 -0800117 if (cameraIdStr.compare(deviceNamePair.first) == 0) {
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -0800118 cp->mCallbacks->torchModeStatusChange(
119 deviceNamePair.second, status);
120 }
121 }
122 }
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -0800123}
124
125Status CameraProvider::getHidlStatus(int status) {
126 switch (status) {
127 case 0: return Status::OK;
128 case -ENODEV: return Status::INTERNAL_ERROR;
129 case -EINVAL: return Status::ILLEGAL_ARGUMENT;
130 default:
131 ALOGE("%s: unknown HAL status code %d", __FUNCTION__, status);
132 return Status::INTERNAL_ERROR;
133 }
134}
135
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -0800136std::string CameraProvider::getLegacyCameraId(const hidl_string& deviceName) {
Andreas Gampe0b171f12017-04-04 20:02:25 -0700137 std::string cameraId;
138 matchDeviceName(deviceName, nullptr, &cameraId);
139 return cameraId;
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -0800140}
141
142int CameraProvider::getCameraDeviceVersion(const hidl_string& deviceName) {
Andreas Gampe0b171f12017-04-04 20:02:25 -0700143 std::string deviceVersion;
144 bool match = matchDeviceName(deviceName, &deviceVersion, nullptr);
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -0800145 if (!match) {
146 return -1;
147 }
Eino-Ville Talvala50fe4302017-08-22 16:15:09 -0700148 if (deviceVersion == kHAL3_3) {
149 return CAMERA_DEVICE_API_VERSION_3_3;
150 } else if (deviceVersion == kHAL3_2) {
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -0800151 return CAMERA_DEVICE_API_VERSION_3_2;
Andreas Gampe0b171f12017-04-04 20:02:25 -0700152 } else if (deviceVersion == kHAL1_0) {
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -0800153 return CAMERA_DEVICE_API_VERSION_1_0;
154 }
155 return 0;
156}
157
158std::string CameraProvider::getHidlDeviceName(
159 std::string cameraId, int deviceVersion) {
160 // Maybe consider create a version check method and SortedVec to speed up?
161 if (deviceVersion != CAMERA_DEVICE_API_VERSION_1_0 &&
162 deviceVersion != CAMERA_DEVICE_API_VERSION_3_2 &&
163 deviceVersion != CAMERA_DEVICE_API_VERSION_3_3 &&
Emilian Peeve18057b2017-11-13 16:03:44 +0000164 deviceVersion != CAMERA_DEVICE_API_VERSION_3_4 &&
165 deviceVersion != CAMERA_DEVICE_API_VERSION_3_5) {
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -0800166 return hidl_string("");
167 }
Eino-Ville Talvala50fe4302017-08-22 16:15:09 -0700168 bool isV1 = deviceVersion == CAMERA_DEVICE_API_VERSION_1_0;
169 int versionMajor = isV1 ? 1 : 3;
170 int versionMinor = isV1 ? 0 : mPreferredHal3MinorVersion;
Emilian Peeve18057b2017-11-13 16:03:44 +0000171 if (deviceVersion == CAMERA_DEVICE_API_VERSION_3_5) {
172 versionMinor = 4;
173 }
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -0800174 char deviceName[kMaxCameraDeviceNameLen];
Eino-Ville Talvala50fe4302017-08-22 16:15:09 -0700175 snprintf(deviceName, sizeof(deviceName), "device@%d.%d/legacy/%s",
176 versionMajor, versionMinor, cameraId.c_str());
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -0800177 return deviceName;
178}
179
180CameraProvider::CameraProvider() :
181 camera_module_callbacks_t({sCameraDeviceStatusChange,
182 sTorchModeStatusChange}) {
183 mInitFailed = initialize();
184}
185
186CameraProvider::~CameraProvider() {}
187
188bool CameraProvider::initialize() {
189 camera_module_t *rawModule;
190 int err = hw_get_module(CAMERA_HARDWARE_MODULE_ID,
191 (const hw_module_t **)&rawModule);
192 if (err < 0) {
193 ALOGE("Could not load camera HAL module: %d (%s)", err, strerror(-err));
194 return true;
195 }
196
197 mModule = new CameraModule(rawModule);
198 err = mModule->init();
199 if (err != OK) {
Yin-Chia Yehfca2e742017-01-31 16:00:20 -0800200 ALOGE("Could not initialize camera HAL module: %d (%s)", err, strerror(-err));
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -0800201 mModule.clear();
202 return true;
203 }
204 ALOGI("Loaded \"%s\" camera module", mModule->getModuleName());
205
Shuzhen Wangefb7bfa2017-03-15 18:26:39 -0700206 // Setup vendor tags here so HAL can setup vendor keys in camera characteristics
207 VendorTagDescriptor::clearGlobalVendorTagDescriptor();
208 if (!setUpVendorTags()) {
209 ALOGE("%s: Vendor tag setup failed, will not be available.", __FUNCTION__);
210 }
211
Yin-Chia Yehfca2e742017-01-31 16:00:20 -0800212 // Setup callback now because we are going to try openLegacy next
213 err = mModule->setCallbacks(this);
214 if (err != OK) {
215 ALOGE("Could not set camera module callback: %d (%s)", err, strerror(-err));
216 mModule.clear();
217 return true;
218 }
219
Eino-Ville Talvala50fe4302017-08-22 16:15:09 -0700220 mPreferredHal3MinorVersion = property_get_int32("ro.camera.wrapper.hal3TrebleMinorVersion", 3);
221 ALOGV("Preferred HAL 3 minor version is %d", mPreferredHal3MinorVersion);
222 switch(mPreferredHal3MinorVersion) {
223 case 2:
224 case 3:
225 // OK
226 break;
227 default:
228 ALOGW("Unknown minor camera device HAL version %d in property "
Emilian Peeve18057b2017-11-13 16:03:44 +0000229 "'camera.wrapper.hal3TrebleMinorVersion', defaulting to 3",
230 mPreferredHal3MinorVersion);
Eino-Ville Talvala50fe4302017-08-22 16:15:09 -0700231 mPreferredHal3MinorVersion = 3;
232 }
233
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -0800234 mNumberOfLegacyCameras = mModule->getNumberOfCameras();
235 for (int i = 0; i < mNumberOfLegacyCameras; i++) {
Emilian Peevc9ded512017-04-10 16:12:55 +0100236 struct camera_info info;
237 auto rc = mModule->getCameraInfo(i, &info);
238 if (rc != NO_ERROR) {
239 ALOGE("%s: Camera info query failed!", __func__);
240 mModule.clear();
241 return true;
242 }
243
244 if (checkCameraVersion(i, info) != OK) {
245 ALOGE("%s: Camera version check failed!", __func__);
246 mModule.clear();
247 return true;
248 }
249
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -0800250 char cameraId[kMaxCameraIdLen];
251 snprintf(cameraId, sizeof(cameraId), "%d", i);
252 std::string cameraIdStr(cameraId);
253 mCameraStatusMap[cameraIdStr] = CAMERA_DEVICE_STATUS_PRESENT;
254 mCameraIds.add(cameraIdStr);
255
256 // initialize mCameraDeviceNames and mOpenLegacySupported
257 mOpenLegacySupported[cameraIdStr] = false;
258 int deviceVersion = mModule->getDeviceVersion(i);
259 mCameraDeviceNames.add(
260 std::make_pair(cameraIdStr,
261 getHidlDeviceName(cameraIdStr, deviceVersion)));
262 if (deviceVersion >= CAMERA_DEVICE_API_VERSION_3_2 &&
263 mModule->isOpenLegacyDefined()) {
264 // try open_legacy to see if it actually works
265 struct hw_device_t* halDev = nullptr;
266 int ret = mModule->openLegacy(cameraId, CAMERA_DEVICE_API_VERSION_1_0, &halDev);
267 if (ret == 0) {
268 mOpenLegacySupported[cameraIdStr] = true;
269 halDev->close(halDev);
270 mCameraDeviceNames.add(
271 std::make_pair(cameraIdStr,
272 getHidlDeviceName(cameraIdStr, CAMERA_DEVICE_API_VERSION_1_0)));
273 } else if (ret == -EBUSY || ret == -EUSERS) {
274 // Looks like this provider instance is not initialized during
275 // system startup and there are other camera users already.
276 // Not a good sign but not fatal.
277 ALOGW("%s: open_legacy try failed!", __FUNCTION__);
278 }
279 }
280 }
281
Eino-Ville Talvala0f5eb832017-02-09 19:45:31 -0800282 return false; // mInitFailed
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -0800283}
284
Emilian Peevc9ded512017-04-10 16:12:55 +0100285/**
286 * Check that the device HAL version is still in supported.
287 */
288int CameraProvider::checkCameraVersion(int id, camera_info info) {
289 if (mModule == nullptr) {
290 return NO_INIT;
291 }
292
293 // device_version undefined in CAMERA_MODULE_API_VERSION_1_0,
294 // All CAMERA_MODULE_API_VERSION_1_0 devices are backward-compatible
295 if (mModule->getModuleApiVersion() >= CAMERA_MODULE_API_VERSION_2_0) {
296 // Verify the device version is in the supported range
297 switch (info.device_version) {
298 case CAMERA_DEVICE_API_VERSION_1_0:
299 case CAMERA_DEVICE_API_VERSION_3_2:
300 case CAMERA_DEVICE_API_VERSION_3_3:
301 case CAMERA_DEVICE_API_VERSION_3_4:
Emilian Peeve18057b2017-11-13 16:03:44 +0000302 case CAMERA_DEVICE_API_VERSION_3_5:
Emilian Peevc9ded512017-04-10 16:12:55 +0100303 // in support
304 break;
305 case CAMERA_DEVICE_API_VERSION_2_0:
306 case CAMERA_DEVICE_API_VERSION_2_1:
307 case CAMERA_DEVICE_API_VERSION_3_0:
308 case CAMERA_DEVICE_API_VERSION_3_1:
309 // no longer supported
310 default:
311 ALOGE("%s: Device %d has HAL version %x, which is not supported",
312 __FUNCTION__, id, info.device_version);
313 return NO_INIT;
314 }
315 }
316
317 return OK;
318}
319
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -0800320bool CameraProvider::setUpVendorTags() {
321 ATRACE_CALL();
322 vendor_tag_ops_t vOps = vendor_tag_ops_t();
323
324 // Check if vendor operations have been implemented
325 if (!mModule->isVendorTagDefined()) {
326 ALOGI("%s: No vendor tags defined for this device.", __FUNCTION__);
Eino-Ville Talvala0f5eb832017-02-09 19:45:31 -0800327 return true;
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -0800328 }
329
330 mModule->getVendorTagOps(&vOps);
331
332 // Ensure all vendor operations are present
333 if (vOps.get_tag_count == nullptr || vOps.get_all_tags == nullptr ||
334 vOps.get_section_name == nullptr || vOps.get_tag_name == nullptr ||
335 vOps.get_tag_type == nullptr) {
336 ALOGE("%s: Vendor tag operations not fully defined. Ignoring definitions."
337 , __FUNCTION__);
338 return false;
339 }
340
341 // Read all vendor tag definitions into a descriptor
342 sp<VendorTagDescriptor> desc;
343 status_t res;
344 if ((res = VendorTagDescriptor::createDescriptorFromOps(&vOps, /*out*/desc))
345 != OK) {
346 ALOGE("%s: Could not generate descriptor from vendor tag operations,"
347 "received error %s (%d). Camera clients will not be able to use"
348 "vendor tags", __FUNCTION__, strerror(res), res);
349 return false;
350 }
351
352 // Set the global descriptor to use with camera metadata
353 VendorTagDescriptor::setAsGlobalVendorTagDescriptor(desc);
354 const SortedVector<String8>* sectionNames = desc->getAllSectionNames();
355 size_t numSections = sectionNames->size();
356 std::vector<std::vector<VendorTag>> tagsBySection(numSections);
357 int tagCount = desc->getTagCount();
358 std::vector<uint32_t> tags(tagCount);
359 desc->getTagArray(tags.data());
360 for (int i = 0; i < tagCount; i++) {
361 VendorTag vt;
362 vt.tagId = tags[i];
363 vt.tagName = desc->getTagName(tags[i]);
364 vt.tagType = (CameraMetadataType) desc->getTagType(tags[i]);
365 ssize_t sectionIdx = desc->getSectionIndex(tags[i]);
366 tagsBySection[sectionIdx].push_back(vt);
367 }
368 mVendorTagSections.resize(numSections);
369 for (size_t s = 0; s < numSections; s++) {
370 mVendorTagSections[s].sectionName = (*sectionNames)[s].string();
371 mVendorTagSections[s].tags = tagsBySection[s];
372 }
373 return true;
374}
375
376// Methods from ::android::hardware::camera::provider::V2_4::ICameraProvider follow.
377Return<Status> CameraProvider::setCallback(const sp<ICameraProviderCallback>& callback) {
Yin-Chia Yehfca2e742017-01-31 16:00:20 -0800378 Mutex::Autolock _l(mCbLock);
379 mCallbacks = callback;
380 return Status::OK;
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -0800381}
382
383Return<void> CameraProvider::getVendorTags(getVendorTags_cb _hidl_cb) {
384 _hidl_cb(Status::OK, mVendorTagSections);
385 return Void();
386}
387
388Return<void> CameraProvider::getCameraIdList(getCameraIdList_cb _hidl_cb) {
389 std::vector<hidl_string> deviceNameList;
390 for (auto const& deviceNamePair : mCameraDeviceNames) {
391 if (mCameraStatusMap[deviceNamePair.first] == CAMERA_DEVICE_STATUS_PRESENT) {
392 deviceNameList.push_back(deviceNamePair.second);
393 }
394 }
395 hidl_vec<hidl_string> hidlDeviceNameList(deviceNameList);
Yin-Chia Yeh9c6dbd52016-12-22 14:55:02 -0800396 _hidl_cb(Status::OK, hidlDeviceNameList);
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -0800397 return Void();
398}
399
400Return<void> CameraProvider::isSetTorchModeSupported(isSetTorchModeSupported_cb _hidl_cb) {
401 bool support = mModule->isSetTorchModeSupported();
402 _hidl_cb (Status::OK, support);
403 return Void();
404}
405
Yin-Chia Yeh9c6dbd52016-12-22 14:55:02 -0800406Return<void> CameraProvider::getCameraDeviceInterface_V1_x(
Yin-Chia Yeh248ed702017-01-23 17:27:26 -0800407 const hidl_string& cameraDeviceName, getCameraDeviceInterface_V1_x_cb _hidl_cb) {
Andreas Gampe0b171f12017-04-04 20:02:25 -0700408 std::string cameraId, deviceVersion;
409 bool match = matchDeviceName(cameraDeviceName, &deviceVersion, &cameraId);
Yin-Chia Yeh248ed702017-01-23 17:27:26 -0800410 if (!match) {
411 _hidl_cb(Status::ILLEGAL_ARGUMENT, nullptr);
412 return Void();
413 }
414
Yin-Chia Yeh248ed702017-01-23 17:27:26 -0800415 std::string deviceName(cameraDeviceName.c_str());
416 ssize_t index = mCameraDeviceNames.indexOf(std::make_pair(cameraId, deviceName));
417 if (index == NAME_NOT_FOUND) { // Either an illegal name or a device version mismatch
418 Status status = Status::OK;
419 ssize_t idx = mCameraIds.indexOf(cameraId);
420 if (idx == NAME_NOT_FOUND) {
421 ALOGE("%s: cannot find camera %s!", __FUNCTION__, cameraId.c_str());
422 status = Status::ILLEGAL_ARGUMENT;
423 } else { // invalid version
424 ALOGE("%s: camera device %s does not support version %s!",
425 __FUNCTION__, cameraId.c_str(), deviceVersion.c_str());
426 status = Status::OPERATION_NOT_SUPPORTED;
427 }
428 _hidl_cb(status, nullptr);
429 return Void();
430 }
431
432 if (mCameraStatusMap.count(cameraId) == 0 ||
433 mCameraStatusMap[cameraId] != CAMERA_DEVICE_STATUS_PRESENT) {
434 _hidl_cb(Status::ILLEGAL_ARGUMENT, nullptr);
435 return Void();
436 }
437
438 sp<android::hardware::camera::device::V1_0::implementation::CameraDevice> device =
439 new android::hardware::camera::device::V1_0::implementation::CameraDevice(
440 mModule, cameraId, mCameraDeviceNames);
441
442 if (device == nullptr) {
443 ALOGE("%s: cannot allocate camera device for id %s", __FUNCTION__, cameraId.c_str());
444 _hidl_cb(Status::INTERNAL_ERROR, nullptr);
445 return Void();
446 }
447
448 if (device->isInitFailed()) {
449 ALOGE("%s: camera device %s init failed!", __FUNCTION__, cameraId.c_str());
450 device = nullptr;
451 _hidl_cb(Status::INTERNAL_ERROR, nullptr);
452 return Void();
453 }
454
455 _hidl_cb (Status::OK, device);
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -0800456 return Void();
457}
458
Yin-Chia Yeh9c6dbd52016-12-22 14:55:02 -0800459Return<void> CameraProvider::getCameraDeviceInterface_V3_x(
460 const hidl_string& cameraDeviceName, getCameraDeviceInterface_V3_x_cb _hidl_cb) {
Andreas Gampe0b171f12017-04-04 20:02:25 -0700461 std::string cameraId, deviceVersion;
462 bool match = matchDeviceName(cameraDeviceName, &deviceVersion, &cameraId);
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -0800463 if (!match) {
464 _hidl_cb(Status::ILLEGAL_ARGUMENT, nullptr);
465 return Void();
466 }
467
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -0800468 std::string deviceName(cameraDeviceName.c_str());
469 ssize_t index = mCameraDeviceNames.indexOf(std::make_pair(cameraId, deviceName));
470 if (index == NAME_NOT_FOUND) { // Either an illegal name or a device version mismatch
471 Status status = Status::OK;
472 ssize_t idx = mCameraIds.indexOf(cameraId);
473 if (idx == NAME_NOT_FOUND) {
Yin-Chia Yeh9c6dbd52016-12-22 14:55:02 -0800474 ALOGE("%s: cannot find camera %s!", __FUNCTION__, cameraId.c_str());
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -0800475 status = Status::ILLEGAL_ARGUMENT;
476 } else { // invalid version
Yin-Chia Yeh9c6dbd52016-12-22 14:55:02 -0800477 ALOGE("%s: camera device %s does not support version %s!",
478 __FUNCTION__, cameraId.c_str(), deviceVersion.c_str());
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -0800479 status = Status::OPERATION_NOT_SUPPORTED;
480 }
481 _hidl_cb(status, nullptr);
482 return Void();
483 }
484
485 if (mCameraStatusMap.count(cameraId) == 0 ||
486 mCameraStatusMap[cameraId] != CAMERA_DEVICE_STATUS_PRESENT) {
487 _hidl_cb(Status::ILLEGAL_ARGUMENT, nullptr);
488 return Void();
489 }
490
Emilian Peeve18057b2017-11-13 16:03:44 +0000491 sp<android::hardware::camera::device::V3_2::ICameraDevice> device;
492 if (deviceVersion == kHAL3_4) {
493 ALOGV("Constructing v3.4 camera device");
494 sp<android::hardware::camera::device::V3_2::implementation::CameraDevice> deviceImpl =
495 new android::hardware::camera::device::V3_4::implementation::CameraDevice(
496 mModule, cameraId, mCameraDeviceNames);
497 if (deviceImpl == nullptr || deviceImpl->isInitFailed()) {
498 ALOGE("%s: camera device %s init failed!", __FUNCTION__, cameraId.c_str());
499 device = nullptr;
500 _hidl_cb(Status::INTERNAL_ERROR, nullptr);
501 return Void();
502 }
503
504 device = deviceImpl;
505 _hidl_cb (Status::OK, device);
506 return Void();
507 }
508
Eino-Ville Talvala50fe4302017-08-22 16:15:09 -0700509 // Since some Treble HAL revisions can map to the same legacy HAL version(s), we default
510 // to the newest possible Treble HAL revision, but allow for override if needed via
511 // system property.
Eino-Ville Talvala50fe4302017-08-22 16:15:09 -0700512 switch (mPreferredHal3MinorVersion) {
513 case 2: { // Map legacy camera device v3 HAL to Treble camera device HAL v3.2
514 ALOGV("Constructing v3.2 camera device");
515 sp<android::hardware::camera::device::V3_2::implementation::CameraDevice> deviceImpl =
516 new android::hardware::camera::device::V3_2::implementation::CameraDevice(
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -0800517 mModule, cameraId, mCameraDeviceNames);
Eino-Ville Talvala50fe4302017-08-22 16:15:09 -0700518 if (deviceImpl == nullptr || deviceImpl->isInitFailed()) {
519 ALOGE("%s: camera device %s init failed!", __FUNCTION__, cameraId.c_str());
520 device = nullptr;
521 _hidl_cb(Status::INTERNAL_ERROR, nullptr);
522 return Void();
523 }
524 device = deviceImpl;
525 break;
526 }
527 case 3: { // Map legacy camera device v3 HAL to Treble camera device HAL v3.3
528 ALOGV("Constructing v3.3 camera device");
529 sp<android::hardware::camera::device::V3_2::implementation::CameraDevice> deviceImpl =
530 new android::hardware::camera::device::V3_3::implementation::CameraDevice(
531 mModule, cameraId, mCameraDeviceNames);
532 if (deviceImpl == nullptr || deviceImpl->isInitFailed()) {
533 ALOGE("%s: camera device %s init failed!", __FUNCTION__, cameraId.c_str());
534 device = nullptr;
535 _hidl_cb(Status::INTERNAL_ERROR, nullptr);
536 return Void();
537 }
538 device = deviceImpl;
539 break;
540 }
541 default:
542 ALOGE("%s: Unknown HAL minor version %d!", __FUNCTION__, mPreferredHal3MinorVersion);
543 device = nullptr;
544 _hidl_cb(Status::INTERNAL_ERROR, nullptr);
545 return Void();
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -0800546 }
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -0800547 _hidl_cb (Status::OK, device);
548 return Void();
549}
550
551ICameraProvider* HIDL_FETCH_ICameraProvider(const char* name) {
552 if (strcmp(name, kLegacyProviderName) != 0) {
553 return nullptr;
554 }
555 CameraProvider* provider = new CameraProvider();
556 if (provider == nullptr) {
557 ALOGE("%s: cannot allocate camera provider!", __FUNCTION__);
558 return nullptr;
559 }
560 if (provider->isInitFailed()) {
561 ALOGE("%s: camera provider init failed!", __FUNCTION__);
562 delete provider;
563 return nullptr;
564 }
565 return provider;
566}
567
568} // namespace implementation
569} // namespace V2_4
570} // namespace provider
571} // namespace camera
572} // namespace hardware
573} // namespace android