blob: 2fb920cc4fb1900064535538a1c5aec26e71a5fb [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 Yeh19030592017-10-19 17:30:11 -070022#include "ExternalCameraProvider.h"
Yin-Chia Yeh248ed702017-01-23 17:27:26 -080023#include "CameraDevice_1_0.h"
Eino-Ville Talvala50fe4302017-08-22 16:15:09 -070024#include "CameraDevice_3_3.h"
Emilian Peeve18057b2017-11-13 16:03:44 +000025#include "CameraDevice_3_4.h"
Eino-Ville Talvala50fe4302017-08-22 16:15:09 -070026#include <cutils/properties.h>
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -080027#include <string.h>
28#include <utils/Trace.h>
29
30
31namespace android {
32namespace hardware {
33namespace camera {
34namespace provider {
35namespace V2_4 {
36namespace implementation {
37
38namespace {
39const char *kLegacyProviderName = "legacy/0";
Yin-Chia Yeh19030592017-10-19 17:30:11 -070040const char *kExternalProviderName = "external/0";
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -080041// "device@<version>/legacy/<id>"
42const std::regex kDeviceNameRE("device@([0-9]+\\.[0-9]+)/legacy/(.+)");
43const char *kHAL3_2 = "3.2";
Eino-Ville Talvala50fe4302017-08-22 16:15:09 -070044const char *kHAL3_3 = "3.3";
Emilian Peeve18057b2017-11-13 16:03:44 +000045const char *kHAL3_4 = "3.4";
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -080046const char *kHAL1_0 = "1.0";
47const int kMaxCameraDeviceNameLen = 128;
48const int kMaxCameraIdLen = 16;
49
Andreas Gampe0b171f12017-04-04 20:02:25 -070050bool 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
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -080066} // anonymous namespace
67
68using ::android::hardware::camera::common::V1_0::CameraMetadataType;
69using ::android::hardware::camera::common::V1_0::Status;
70
Guennadi Liakhovetski7b7ede72017-11-28 09:28:56 +010071void 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
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -0800111/**
112 * static callback forwarding methods from HAL to instance
113 */
114void CameraProvider::sCameraDeviceStatusChange(
115 const struct camera_module_callbacks* callbacks,
116 int camera_id,
117 int new_status) {
Yin-Chia Yeh6dc9b532017-02-09 18:43:35 -0800118 CameraProvider* cp = const_cast<CameraProvider*>(
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -0800119 static_cast<const CameraProvider*>(callbacks));
Guennadi Liakhovetski7b7ede72017-11-28 09:28:56 +0100120 bool found = false;
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -0800121
122 if (cp == nullptr) {
123 ALOGE("%s: callback ops is null", __FUNCTION__);
124 return;
125 }
126
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -0800127 Mutex::Autolock _l(cp->mCbLock);
128 char cameraId[kMaxCameraIdLen];
129 snprintf(cameraId, sizeof(cameraId), "%d", camera_id);
130 std::string cameraIdStr(cameraId);
131 cp->mCameraStatusMap[cameraIdStr] = (camera_device_status_t) new_status;
132 if (cp->mCallbacks != nullptr) {
133 CameraDeviceStatus status = (CameraDeviceStatus) new_status;
134 for (auto const& deviceNamePair : cp->mCameraDeviceNames) {
135 if (cameraIdStr.compare(deviceNamePair.first) == 0) {
136 cp->mCallbacks->cameraDeviceStatusChange(
137 deviceNamePair.second, status);
Guennadi Liakhovetski7b7ede72017-11-28 09:28:56 +0100138 found = true;
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -0800139 }
140 }
Guennadi Liakhovetski7b7ede72017-11-28 09:28:56 +0100141
142 if (!found) {
143 cp->addDeviceNames(camera_id, status, true);
144 }
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -0800145 }
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -0800146}
147
148void CameraProvider::sTorchModeStatusChange(
149 const struct camera_module_callbacks* callbacks,
150 const char* camera_id,
151 int new_status) {
Yin-Chia Yeh6dc9b532017-02-09 18:43:35 -0800152 CameraProvider* cp = const_cast<CameraProvider*>(
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -0800153 static_cast<const CameraProvider*>(callbacks));
154
155 if (cp == nullptr) {
156 ALOGE("%s: callback ops is null", __FUNCTION__);
157 return;
158 }
159
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -0800160 Mutex::Autolock _l(cp->mCbLock);
161 if (cp->mCallbacks != nullptr) {
162 std::string cameraIdStr(camera_id);
163 TorchModeStatus status = (TorchModeStatus) new_status;
164 for (auto const& deviceNamePair : cp->mCameraDeviceNames) {
Yin-Chia Yeh9c6dbd52016-12-22 14:55:02 -0800165 if (cameraIdStr.compare(deviceNamePair.first) == 0) {
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -0800166 cp->mCallbacks->torchModeStatusChange(
167 deviceNamePair.second, status);
168 }
169 }
170 }
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -0800171}
172
173Status CameraProvider::getHidlStatus(int status) {
174 switch (status) {
175 case 0: return Status::OK;
176 case -ENODEV: return Status::INTERNAL_ERROR;
177 case -EINVAL: return Status::ILLEGAL_ARGUMENT;
178 default:
179 ALOGE("%s: unknown HAL status code %d", __FUNCTION__, status);
180 return Status::INTERNAL_ERROR;
181 }
182}
183
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -0800184std::string CameraProvider::getLegacyCameraId(const hidl_string& deviceName) {
Andreas Gampe0b171f12017-04-04 20:02:25 -0700185 std::string cameraId;
186 matchDeviceName(deviceName, nullptr, &cameraId);
187 return cameraId;
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -0800188}
189
190int CameraProvider::getCameraDeviceVersion(const hidl_string& deviceName) {
Andreas Gampe0b171f12017-04-04 20:02:25 -0700191 std::string deviceVersion;
192 bool match = matchDeviceName(deviceName, &deviceVersion, nullptr);
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -0800193 if (!match) {
194 return -1;
195 }
Eino-Ville Talvala50fe4302017-08-22 16:15:09 -0700196 if (deviceVersion == kHAL3_3) {
197 return CAMERA_DEVICE_API_VERSION_3_3;
198 } else if (deviceVersion == kHAL3_2) {
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -0800199 return CAMERA_DEVICE_API_VERSION_3_2;
Andreas Gampe0b171f12017-04-04 20:02:25 -0700200 } else if (deviceVersion == kHAL1_0) {
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -0800201 return CAMERA_DEVICE_API_VERSION_1_0;
202 }
203 return 0;
204}
205
206std::string CameraProvider::getHidlDeviceName(
207 std::string cameraId, int deviceVersion) {
208 // Maybe consider create a version check method and SortedVec to speed up?
209 if (deviceVersion != CAMERA_DEVICE_API_VERSION_1_0 &&
210 deviceVersion != CAMERA_DEVICE_API_VERSION_3_2 &&
211 deviceVersion != CAMERA_DEVICE_API_VERSION_3_3 &&
Emilian Peeve18057b2017-11-13 16:03:44 +0000212 deviceVersion != CAMERA_DEVICE_API_VERSION_3_4 &&
213 deviceVersion != CAMERA_DEVICE_API_VERSION_3_5) {
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -0800214 return hidl_string("");
215 }
Eino-Ville Talvala50fe4302017-08-22 16:15:09 -0700216 bool isV1 = deviceVersion == CAMERA_DEVICE_API_VERSION_1_0;
217 int versionMajor = isV1 ? 1 : 3;
218 int versionMinor = isV1 ? 0 : mPreferredHal3MinorVersion;
Emilian Peeve18057b2017-11-13 16:03:44 +0000219 if (deviceVersion == CAMERA_DEVICE_API_VERSION_3_5) {
220 versionMinor = 4;
221 }
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -0800222 char deviceName[kMaxCameraDeviceNameLen];
Eino-Ville Talvala50fe4302017-08-22 16:15:09 -0700223 snprintf(deviceName, sizeof(deviceName), "device@%d.%d/legacy/%s",
224 versionMajor, versionMinor, cameraId.c_str());
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -0800225 return deviceName;
226}
227
228CameraProvider::CameraProvider() :
229 camera_module_callbacks_t({sCameraDeviceStatusChange,
230 sTorchModeStatusChange}) {
231 mInitFailed = initialize();
232}
233
234CameraProvider::~CameraProvider() {}
235
236bool CameraProvider::initialize() {
237 camera_module_t *rawModule;
238 int err = hw_get_module(CAMERA_HARDWARE_MODULE_ID,
239 (const hw_module_t **)&rawModule);
240 if (err < 0) {
241 ALOGE("Could not load camera HAL module: %d (%s)", err, strerror(-err));
242 return true;
243 }
244
245 mModule = new CameraModule(rawModule);
246 err = mModule->init();
247 if (err != OK) {
Yin-Chia Yehfca2e742017-01-31 16:00:20 -0800248 ALOGE("Could not initialize camera HAL module: %d (%s)", err, strerror(-err));
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -0800249 mModule.clear();
250 return true;
251 }
252 ALOGI("Loaded \"%s\" camera module", mModule->getModuleName());
253
Shuzhen Wangefb7bfa2017-03-15 18:26:39 -0700254 // Setup vendor tags here so HAL can setup vendor keys in camera characteristics
255 VendorTagDescriptor::clearGlobalVendorTagDescriptor();
256 if (!setUpVendorTags()) {
257 ALOGE("%s: Vendor tag setup failed, will not be available.", __FUNCTION__);
258 }
259
Yin-Chia Yehfca2e742017-01-31 16:00:20 -0800260 // Setup callback now because we are going to try openLegacy next
261 err = mModule->setCallbacks(this);
262 if (err != OK) {
263 ALOGE("Could not set camera module callback: %d (%s)", err, strerror(-err));
264 mModule.clear();
265 return true;
266 }
267
Eino-Ville Talvala50fe4302017-08-22 16:15:09 -0700268 mPreferredHal3MinorVersion = property_get_int32("ro.camera.wrapper.hal3TrebleMinorVersion", 3);
269 ALOGV("Preferred HAL 3 minor version is %d", mPreferredHal3MinorVersion);
270 switch(mPreferredHal3MinorVersion) {
271 case 2:
272 case 3:
273 // OK
274 break;
275 default:
276 ALOGW("Unknown minor camera device HAL version %d in property "
Emilian Peeve18057b2017-11-13 16:03:44 +0000277 "'camera.wrapper.hal3TrebleMinorVersion', defaulting to 3",
278 mPreferredHal3MinorVersion);
Eino-Ville Talvala50fe4302017-08-22 16:15:09 -0700279 mPreferredHal3MinorVersion = 3;
280 }
281
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -0800282 mNumberOfLegacyCameras = mModule->getNumberOfCameras();
283 for (int i = 0; i < mNumberOfLegacyCameras; i++) {
Emilian Peevc9ded512017-04-10 16:12:55 +0100284 struct camera_info info;
285 auto rc = mModule->getCameraInfo(i, &info);
286 if (rc != NO_ERROR) {
287 ALOGE("%s: Camera info query failed!", __func__);
288 mModule.clear();
289 return true;
290 }
291
292 if (checkCameraVersion(i, info) != OK) {
293 ALOGE("%s: Camera version check failed!", __func__);
294 mModule.clear();
295 return true;
296 }
297
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -0800298 char cameraId[kMaxCameraIdLen];
299 snprintf(cameraId, sizeof(cameraId), "%d", i);
300 std::string cameraIdStr(cameraId);
301 mCameraStatusMap[cameraIdStr] = CAMERA_DEVICE_STATUS_PRESENT;
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -0800302
Guennadi Liakhovetski7b7ede72017-11-28 09:28:56 +0100303 addDeviceNames(i);
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -0800304 }
305
Eino-Ville Talvala0f5eb832017-02-09 19:45:31 -0800306 return false; // mInitFailed
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -0800307}
308
Emilian Peevc9ded512017-04-10 16:12:55 +0100309/**
310 * Check that the device HAL version is still in supported.
311 */
312int CameraProvider::checkCameraVersion(int id, camera_info info) {
313 if (mModule == nullptr) {
314 return NO_INIT;
315 }
316
317 // device_version undefined in CAMERA_MODULE_API_VERSION_1_0,
318 // All CAMERA_MODULE_API_VERSION_1_0 devices are backward-compatible
319 if (mModule->getModuleApiVersion() >= CAMERA_MODULE_API_VERSION_2_0) {
320 // Verify the device version is in the supported range
321 switch (info.device_version) {
322 case CAMERA_DEVICE_API_VERSION_1_0:
323 case CAMERA_DEVICE_API_VERSION_3_2:
324 case CAMERA_DEVICE_API_VERSION_3_3:
325 case CAMERA_DEVICE_API_VERSION_3_4:
Emilian Peeve18057b2017-11-13 16:03:44 +0000326 case CAMERA_DEVICE_API_VERSION_3_5:
Emilian Peevc9ded512017-04-10 16:12:55 +0100327 // in support
328 break;
329 case CAMERA_DEVICE_API_VERSION_2_0:
330 case CAMERA_DEVICE_API_VERSION_2_1:
331 case CAMERA_DEVICE_API_VERSION_3_0:
332 case CAMERA_DEVICE_API_VERSION_3_1:
333 // no longer supported
334 default:
335 ALOGE("%s: Device %d has HAL version %x, which is not supported",
336 __FUNCTION__, id, info.device_version);
337 return NO_INIT;
338 }
339 }
340
341 return OK;
342}
343
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -0800344bool CameraProvider::setUpVendorTags() {
345 ATRACE_CALL();
346 vendor_tag_ops_t vOps = vendor_tag_ops_t();
347
348 // Check if vendor operations have been implemented
349 if (!mModule->isVendorTagDefined()) {
350 ALOGI("%s: No vendor tags defined for this device.", __FUNCTION__);
Eino-Ville Talvala0f5eb832017-02-09 19:45:31 -0800351 return true;
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -0800352 }
353
354 mModule->getVendorTagOps(&vOps);
355
356 // Ensure all vendor operations are present
357 if (vOps.get_tag_count == nullptr || vOps.get_all_tags == nullptr ||
358 vOps.get_section_name == nullptr || vOps.get_tag_name == nullptr ||
359 vOps.get_tag_type == nullptr) {
360 ALOGE("%s: Vendor tag operations not fully defined. Ignoring definitions."
361 , __FUNCTION__);
362 return false;
363 }
364
365 // Read all vendor tag definitions into a descriptor
366 sp<VendorTagDescriptor> desc;
367 status_t res;
368 if ((res = VendorTagDescriptor::createDescriptorFromOps(&vOps, /*out*/desc))
369 != OK) {
370 ALOGE("%s: Could not generate descriptor from vendor tag operations,"
371 "received error %s (%d). Camera clients will not be able to use"
372 "vendor tags", __FUNCTION__, strerror(res), res);
373 return false;
374 }
375
376 // Set the global descriptor to use with camera metadata
377 VendorTagDescriptor::setAsGlobalVendorTagDescriptor(desc);
378 const SortedVector<String8>* sectionNames = desc->getAllSectionNames();
379 size_t numSections = sectionNames->size();
380 std::vector<std::vector<VendorTag>> tagsBySection(numSections);
381 int tagCount = desc->getTagCount();
382 std::vector<uint32_t> tags(tagCount);
383 desc->getTagArray(tags.data());
384 for (int i = 0; i < tagCount; i++) {
385 VendorTag vt;
386 vt.tagId = tags[i];
387 vt.tagName = desc->getTagName(tags[i]);
388 vt.tagType = (CameraMetadataType) desc->getTagType(tags[i]);
389 ssize_t sectionIdx = desc->getSectionIndex(tags[i]);
390 tagsBySection[sectionIdx].push_back(vt);
391 }
392 mVendorTagSections.resize(numSections);
393 for (size_t s = 0; s < numSections; s++) {
394 mVendorTagSections[s].sectionName = (*sectionNames)[s].string();
395 mVendorTagSections[s].tags = tagsBySection[s];
396 }
397 return true;
398}
399
400// Methods from ::android::hardware::camera::provider::V2_4::ICameraProvider follow.
401Return<Status> CameraProvider::setCallback(const sp<ICameraProviderCallback>& callback) {
Yin-Chia Yehfca2e742017-01-31 16:00:20 -0800402 Mutex::Autolock _l(mCbLock);
403 mCallbacks = callback;
404 return Status::OK;
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -0800405}
406
407Return<void> CameraProvider::getVendorTags(getVendorTags_cb _hidl_cb) {
408 _hidl_cb(Status::OK, mVendorTagSections);
409 return Void();
410}
411
412Return<void> CameraProvider::getCameraIdList(getCameraIdList_cb _hidl_cb) {
413 std::vector<hidl_string> deviceNameList;
414 for (auto const& deviceNamePair : mCameraDeviceNames) {
415 if (mCameraStatusMap[deviceNamePair.first] == CAMERA_DEVICE_STATUS_PRESENT) {
416 deviceNameList.push_back(deviceNamePair.second);
417 }
418 }
419 hidl_vec<hidl_string> hidlDeviceNameList(deviceNameList);
Yin-Chia Yeh9c6dbd52016-12-22 14:55:02 -0800420 _hidl_cb(Status::OK, hidlDeviceNameList);
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -0800421 return Void();
422}
423
424Return<void> CameraProvider::isSetTorchModeSupported(isSetTorchModeSupported_cb _hidl_cb) {
425 bool support = mModule->isSetTorchModeSupported();
426 _hidl_cb (Status::OK, support);
427 return Void();
428}
429
Yin-Chia Yeh9c6dbd52016-12-22 14:55:02 -0800430Return<void> CameraProvider::getCameraDeviceInterface_V1_x(
Yin-Chia Yeh248ed702017-01-23 17:27:26 -0800431 const hidl_string& cameraDeviceName, getCameraDeviceInterface_V1_x_cb _hidl_cb) {
Andreas Gampe0b171f12017-04-04 20:02:25 -0700432 std::string cameraId, deviceVersion;
433 bool match = matchDeviceName(cameraDeviceName, &deviceVersion, &cameraId);
Yin-Chia Yeh248ed702017-01-23 17:27:26 -0800434 if (!match) {
435 _hidl_cb(Status::ILLEGAL_ARGUMENT, nullptr);
436 return Void();
437 }
438
Yin-Chia Yeh248ed702017-01-23 17:27:26 -0800439 std::string deviceName(cameraDeviceName.c_str());
440 ssize_t index = mCameraDeviceNames.indexOf(std::make_pair(cameraId, deviceName));
441 if (index == NAME_NOT_FOUND) { // Either an illegal name or a device version mismatch
442 Status status = Status::OK;
443 ssize_t idx = mCameraIds.indexOf(cameraId);
444 if (idx == NAME_NOT_FOUND) {
445 ALOGE("%s: cannot find camera %s!", __FUNCTION__, cameraId.c_str());
446 status = Status::ILLEGAL_ARGUMENT;
447 } else { // invalid version
448 ALOGE("%s: camera device %s does not support version %s!",
449 __FUNCTION__, cameraId.c_str(), deviceVersion.c_str());
450 status = Status::OPERATION_NOT_SUPPORTED;
451 }
452 _hidl_cb(status, nullptr);
453 return Void();
454 }
455
456 if (mCameraStatusMap.count(cameraId) == 0 ||
457 mCameraStatusMap[cameraId] != CAMERA_DEVICE_STATUS_PRESENT) {
458 _hidl_cb(Status::ILLEGAL_ARGUMENT, nullptr);
459 return Void();
460 }
461
462 sp<android::hardware::camera::device::V1_0::implementation::CameraDevice> device =
463 new android::hardware::camera::device::V1_0::implementation::CameraDevice(
464 mModule, cameraId, mCameraDeviceNames);
465
466 if (device == nullptr) {
467 ALOGE("%s: cannot allocate camera device for id %s", __FUNCTION__, cameraId.c_str());
468 _hidl_cb(Status::INTERNAL_ERROR, nullptr);
469 return Void();
470 }
471
472 if (device->isInitFailed()) {
473 ALOGE("%s: camera device %s init failed!", __FUNCTION__, cameraId.c_str());
474 device = nullptr;
475 _hidl_cb(Status::INTERNAL_ERROR, nullptr);
476 return Void();
477 }
478
479 _hidl_cb (Status::OK, device);
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -0800480 return Void();
481}
482
Yin-Chia Yeh9c6dbd52016-12-22 14:55:02 -0800483Return<void> CameraProvider::getCameraDeviceInterface_V3_x(
484 const hidl_string& cameraDeviceName, getCameraDeviceInterface_V3_x_cb _hidl_cb) {
Andreas Gampe0b171f12017-04-04 20:02:25 -0700485 std::string cameraId, deviceVersion;
486 bool match = matchDeviceName(cameraDeviceName, &deviceVersion, &cameraId);
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -0800487 if (!match) {
488 _hidl_cb(Status::ILLEGAL_ARGUMENT, nullptr);
489 return Void();
490 }
491
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -0800492 std::string deviceName(cameraDeviceName.c_str());
493 ssize_t index = mCameraDeviceNames.indexOf(std::make_pair(cameraId, deviceName));
494 if (index == NAME_NOT_FOUND) { // Either an illegal name or a device version mismatch
495 Status status = Status::OK;
496 ssize_t idx = mCameraIds.indexOf(cameraId);
497 if (idx == NAME_NOT_FOUND) {
Yin-Chia Yeh9c6dbd52016-12-22 14:55:02 -0800498 ALOGE("%s: cannot find camera %s!", __FUNCTION__, cameraId.c_str());
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -0800499 status = Status::ILLEGAL_ARGUMENT;
500 } else { // invalid version
Yin-Chia Yeh9c6dbd52016-12-22 14:55:02 -0800501 ALOGE("%s: camera device %s does not support version %s!",
502 __FUNCTION__, cameraId.c_str(), deviceVersion.c_str());
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -0800503 status = Status::OPERATION_NOT_SUPPORTED;
504 }
505 _hidl_cb(status, nullptr);
506 return Void();
507 }
508
509 if (mCameraStatusMap.count(cameraId) == 0 ||
510 mCameraStatusMap[cameraId] != CAMERA_DEVICE_STATUS_PRESENT) {
511 _hidl_cb(Status::ILLEGAL_ARGUMENT, nullptr);
512 return Void();
513 }
514
Emilian Peeve18057b2017-11-13 16:03:44 +0000515 sp<android::hardware::camera::device::V3_2::ICameraDevice> device;
516 if (deviceVersion == kHAL3_4) {
517 ALOGV("Constructing v3.4 camera device");
518 sp<android::hardware::camera::device::V3_2::implementation::CameraDevice> deviceImpl =
519 new android::hardware::camera::device::V3_4::implementation::CameraDevice(
520 mModule, cameraId, mCameraDeviceNames);
521 if (deviceImpl == nullptr || deviceImpl->isInitFailed()) {
522 ALOGE("%s: camera device %s init failed!", __FUNCTION__, cameraId.c_str());
523 device = nullptr;
524 _hidl_cb(Status::INTERNAL_ERROR, nullptr);
525 return Void();
526 }
527
528 device = deviceImpl;
529 _hidl_cb (Status::OK, device);
530 return Void();
531 }
532
Eino-Ville Talvala50fe4302017-08-22 16:15:09 -0700533 // Since some Treble HAL revisions can map to the same legacy HAL version(s), we default
534 // to the newest possible Treble HAL revision, but allow for override if needed via
535 // system property.
Eino-Ville Talvala50fe4302017-08-22 16:15:09 -0700536 switch (mPreferredHal3MinorVersion) {
537 case 2: { // Map legacy camera device v3 HAL to Treble camera device HAL v3.2
538 ALOGV("Constructing v3.2 camera device");
539 sp<android::hardware::camera::device::V3_2::implementation::CameraDevice> deviceImpl =
540 new android::hardware::camera::device::V3_2::implementation::CameraDevice(
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -0800541 mModule, cameraId, mCameraDeviceNames);
Eino-Ville Talvala50fe4302017-08-22 16:15:09 -0700542 if (deviceImpl == nullptr || deviceImpl->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 device = deviceImpl;
549 break;
550 }
551 case 3: { // Map legacy camera device v3 HAL to Treble camera device HAL v3.3
552 ALOGV("Constructing v3.3 camera device");
553 sp<android::hardware::camera::device::V3_2::implementation::CameraDevice> deviceImpl =
554 new android::hardware::camera::device::V3_3::implementation::CameraDevice(
555 mModule, cameraId, mCameraDeviceNames);
556 if (deviceImpl == nullptr || deviceImpl->isInitFailed()) {
557 ALOGE("%s: camera device %s init failed!", __FUNCTION__, cameraId.c_str());
558 device = nullptr;
559 _hidl_cb(Status::INTERNAL_ERROR, nullptr);
560 return Void();
561 }
562 device = deviceImpl;
563 break;
564 }
565 default:
566 ALOGE("%s: Unknown HAL minor version %d!", __FUNCTION__, mPreferredHal3MinorVersion);
567 device = nullptr;
568 _hidl_cb(Status::INTERNAL_ERROR, nullptr);
569 return Void();
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -0800570 }
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -0800571 _hidl_cb (Status::OK, device);
572 return Void();
573}
574
575ICameraProvider* HIDL_FETCH_ICameraProvider(const char* name) {
Yin-Chia Yeh19030592017-10-19 17:30:11 -0700576 if (strcmp(name, kLegacyProviderName) == 0) {
577 CameraProvider* provider = new CameraProvider();
578 if (provider == nullptr) {
579 ALOGE("%s: cannot allocate camera provider!", __FUNCTION__);
580 return nullptr;
581 }
582 if (provider->isInitFailed()) {
583 ALOGE("%s: camera provider init failed!", __FUNCTION__);
584 delete provider;
585 return nullptr;
586 }
587 return provider;
588 } else if (strcmp(name, kExternalProviderName) == 0) {
589 ExternalCameraProvider* provider = new ExternalCameraProvider();
590 return provider;
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -0800591 }
Yin-Chia Yeh19030592017-10-19 17:30:11 -0700592 ALOGE("%s: unknown instance name: %s", __FUNCTION__, name);
593 return nullptr;
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -0800594}
595
596} // namespace implementation
597} // namespace V2_4
598} // namespace provider
599} // namespace camera
600} // namespace hardware
601} // namespace android