blob: 8c5af8e26c2982c3dc935a8e45a3256c22096c42 [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
Guennadi Liakhovetski7b7ede72017-11-28 09:28:56 +010067void CameraProvider::addDeviceNames(int camera_id, CameraDeviceStatus status, bool cam_new)
68{
69 char cameraId[kMaxCameraIdLen];
70 snprintf(cameraId, sizeof(cameraId), "%d", camera_id);
71 std::string cameraIdStr(cameraId);
72
73 mCameraIds.add(cameraIdStr);
74
75 // initialize mCameraDeviceNames and mOpenLegacySupported
76 mOpenLegacySupported[cameraIdStr] = false;
77 int deviceVersion = mModule->getDeviceVersion(camera_id);
78 auto deviceNamePair = std::make_pair(cameraIdStr,
79 getHidlDeviceName(cameraIdStr, deviceVersion));
80 mCameraDeviceNames.add(deviceNamePair);
81 if (cam_new) {
82 mCallbacks->cameraDeviceStatusChange(deviceNamePair.second, status);
83 }
84 if (deviceVersion >= CAMERA_DEVICE_API_VERSION_3_2 &&
85 mModule->isOpenLegacyDefined()) {
86 // try open_legacy to see if it actually works
87 struct hw_device_t* halDev = nullptr;
88 int ret = mModule->openLegacy(cameraId, CAMERA_DEVICE_API_VERSION_1_0, &halDev);
89 if (ret == 0) {
90 mOpenLegacySupported[cameraIdStr] = true;
91 halDev->close(halDev);
92 deviceNamePair = std::make_pair(cameraIdStr,
93 getHidlDeviceName(cameraIdStr, CAMERA_DEVICE_API_VERSION_1_0));
94 mCameraDeviceNames.add(deviceNamePair);
95 if (cam_new) {
96 mCallbacks->cameraDeviceStatusChange(deviceNamePair.second, status);
97 }
98 } else if (ret == -EBUSY || ret == -EUSERS) {
99 // Looks like this provider instance is not initialized during
100 // system startup and there are other camera users already.
101 // Not a good sign but not fatal.
102 ALOGW("%s: open_legacy try failed!", __FUNCTION__);
103 }
104 }
105}
106
Guennadi Liakhovetskieca1d452017-12-07 10:59:35 +0100107void CameraProvider::removeDeviceNames(int camera_id)
108{
109 std::string cameraIdStr = std::to_string(camera_id);
110
111 mCameraIds.remove(cameraIdStr);
112
113 int deviceVersion = mModule->getDeviceVersion(camera_id);
114 auto deviceNamePair = std::make_pair(cameraIdStr,
115 getHidlDeviceName(cameraIdStr, deviceVersion));
116 mCameraDeviceNames.remove(deviceNamePair);
117 mCallbacks->cameraDeviceStatusChange(deviceNamePair.second, CameraDeviceStatus::NOT_PRESENT);
118 if (deviceVersion >= CAMERA_DEVICE_API_VERSION_3_2 &&
119 mModule->isOpenLegacyDefined() && mOpenLegacySupported[cameraIdStr]) {
120
121 deviceNamePair = std::make_pair(cameraIdStr,
122 getHidlDeviceName(cameraIdStr, CAMERA_DEVICE_API_VERSION_1_0));
123 mCameraDeviceNames.remove(deviceNamePair);
124 mCallbacks->cameraDeviceStatusChange(deviceNamePair.second,
125 CameraDeviceStatus::NOT_PRESENT);
126 }
127
128 mModule->removeCamera(camera_id);
129}
130
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -0800131/**
132 * static callback forwarding methods from HAL to instance
133 */
134void CameraProvider::sCameraDeviceStatusChange(
135 const struct camera_module_callbacks* callbacks,
136 int camera_id,
137 int new_status) {
Yin-Chia Yeh6dc9b532017-02-09 18:43:35 -0800138 CameraProvider* cp = const_cast<CameraProvider*>(
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -0800139 static_cast<const CameraProvider*>(callbacks));
Guennadi Liakhovetski7b7ede72017-11-28 09:28:56 +0100140 bool found = false;
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -0800141
142 if (cp == nullptr) {
143 ALOGE("%s: callback ops is null", __FUNCTION__);
144 return;
145 }
146
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -0800147 Mutex::Autolock _l(cp->mCbLock);
148 char cameraId[kMaxCameraIdLen];
149 snprintf(cameraId, sizeof(cameraId), "%d", camera_id);
150 std::string cameraIdStr(cameraId);
151 cp->mCameraStatusMap[cameraIdStr] = (camera_device_status_t) new_status;
152 if (cp->mCallbacks != nullptr) {
153 CameraDeviceStatus status = (CameraDeviceStatus) new_status;
154 for (auto const& deviceNamePair : cp->mCameraDeviceNames) {
155 if (cameraIdStr.compare(deviceNamePair.first) == 0) {
156 cp->mCallbacks->cameraDeviceStatusChange(
157 deviceNamePair.second, status);
Guennadi Liakhovetski7b7ede72017-11-28 09:28:56 +0100158 found = true;
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -0800159 }
160 }
Guennadi Liakhovetski7b7ede72017-11-28 09:28:56 +0100161
Guennadi Liakhovetskieca1d452017-12-07 10:59:35 +0100162 switch (status) {
163 case CameraDeviceStatus::PRESENT:
164 case CameraDeviceStatus::ENUMERATING:
165 if (!found) {
166 cp->addDeviceNames(camera_id, status, true);
167 }
168 break;
169 case CameraDeviceStatus::NOT_PRESENT:
170 if (found) {
171 cp->removeDeviceNames(camera_id);
172 }
Guennadi Liakhovetski7b7ede72017-11-28 09:28:56 +0100173 }
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -0800174 }
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -0800175}
176
177void CameraProvider::sTorchModeStatusChange(
178 const struct camera_module_callbacks* callbacks,
179 const char* camera_id,
180 int new_status) {
Yin-Chia Yeh6dc9b532017-02-09 18:43:35 -0800181 CameraProvider* cp = const_cast<CameraProvider*>(
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -0800182 static_cast<const CameraProvider*>(callbacks));
183
184 if (cp == nullptr) {
185 ALOGE("%s: callback ops is null", __FUNCTION__);
186 return;
187 }
188
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -0800189 Mutex::Autolock _l(cp->mCbLock);
190 if (cp->mCallbacks != nullptr) {
191 std::string cameraIdStr(camera_id);
192 TorchModeStatus status = (TorchModeStatus) new_status;
193 for (auto const& deviceNamePair : cp->mCameraDeviceNames) {
Yin-Chia Yeh9c6dbd52016-12-22 14:55:02 -0800194 if (cameraIdStr.compare(deviceNamePair.first) == 0) {
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -0800195 cp->mCallbacks->torchModeStatusChange(
196 deviceNamePair.second, status);
197 }
198 }
199 }
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -0800200}
201
202Status CameraProvider::getHidlStatus(int status) {
203 switch (status) {
204 case 0: return Status::OK;
205 case -ENODEV: return Status::INTERNAL_ERROR;
206 case -EINVAL: return Status::ILLEGAL_ARGUMENT;
207 default:
208 ALOGE("%s: unknown HAL status code %d", __FUNCTION__, status);
209 return Status::INTERNAL_ERROR;
210 }
211}
212
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -0800213std::string CameraProvider::getLegacyCameraId(const hidl_string& deviceName) {
Andreas Gampe0b171f12017-04-04 20:02:25 -0700214 std::string cameraId;
215 matchDeviceName(deviceName, nullptr, &cameraId);
216 return cameraId;
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -0800217}
218
219int CameraProvider::getCameraDeviceVersion(const hidl_string& deviceName) {
Andreas Gampe0b171f12017-04-04 20:02:25 -0700220 std::string deviceVersion;
221 bool match = matchDeviceName(deviceName, &deviceVersion, nullptr);
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -0800222 if (!match) {
223 return -1;
224 }
Eino-Ville Talvala50fe4302017-08-22 16:15:09 -0700225 if (deviceVersion == kHAL3_3) {
226 return CAMERA_DEVICE_API_VERSION_3_3;
227 } else if (deviceVersion == kHAL3_2) {
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -0800228 return CAMERA_DEVICE_API_VERSION_3_2;
Andreas Gampe0b171f12017-04-04 20:02:25 -0700229 } else if (deviceVersion == kHAL1_0) {
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -0800230 return CAMERA_DEVICE_API_VERSION_1_0;
231 }
232 return 0;
233}
234
235std::string CameraProvider::getHidlDeviceName(
236 std::string cameraId, int deviceVersion) {
237 // Maybe consider create a version check method and SortedVec to speed up?
238 if (deviceVersion != CAMERA_DEVICE_API_VERSION_1_0 &&
239 deviceVersion != CAMERA_DEVICE_API_VERSION_3_2 &&
240 deviceVersion != CAMERA_DEVICE_API_VERSION_3_3 &&
241 deviceVersion != CAMERA_DEVICE_API_VERSION_3_4 ) {
242 return hidl_string("");
243 }
Eino-Ville Talvala50fe4302017-08-22 16:15:09 -0700244 bool isV1 = deviceVersion == CAMERA_DEVICE_API_VERSION_1_0;
245 int versionMajor = isV1 ? 1 : 3;
246 int versionMinor = isV1 ? 0 : mPreferredHal3MinorVersion;
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -0800247 char deviceName[kMaxCameraDeviceNameLen];
Eino-Ville Talvala50fe4302017-08-22 16:15:09 -0700248 snprintf(deviceName, sizeof(deviceName), "device@%d.%d/legacy/%s",
249 versionMajor, versionMinor, cameraId.c_str());
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -0800250 return deviceName;
251}
252
253CameraProvider::CameraProvider() :
254 camera_module_callbacks_t({sCameraDeviceStatusChange,
255 sTorchModeStatusChange}) {
256 mInitFailed = initialize();
257}
258
259CameraProvider::~CameraProvider() {}
260
261bool CameraProvider::initialize() {
262 camera_module_t *rawModule;
263 int err = hw_get_module(CAMERA_HARDWARE_MODULE_ID,
264 (const hw_module_t **)&rawModule);
265 if (err < 0) {
266 ALOGE("Could not load camera HAL module: %d (%s)", err, strerror(-err));
267 return true;
268 }
269
270 mModule = new CameraModule(rawModule);
271 err = mModule->init();
272 if (err != OK) {
Yin-Chia Yehfca2e742017-01-31 16:00:20 -0800273 ALOGE("Could not initialize camera HAL module: %d (%s)", err, strerror(-err));
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -0800274 mModule.clear();
275 return true;
276 }
277 ALOGI("Loaded \"%s\" camera module", mModule->getModuleName());
278
Shuzhen Wangefb7bfa2017-03-15 18:26:39 -0700279 // Setup vendor tags here so HAL can setup vendor keys in camera characteristics
280 VendorTagDescriptor::clearGlobalVendorTagDescriptor();
281 if (!setUpVendorTags()) {
282 ALOGE("%s: Vendor tag setup failed, will not be available.", __FUNCTION__);
283 }
284
Yin-Chia Yehfca2e742017-01-31 16:00:20 -0800285 // Setup callback now because we are going to try openLegacy next
286 err = mModule->setCallbacks(this);
287 if (err != OK) {
288 ALOGE("Could not set camera module callback: %d (%s)", err, strerror(-err));
289 mModule.clear();
290 return true;
291 }
292
Eino-Ville Talvala50fe4302017-08-22 16:15:09 -0700293 mPreferredHal3MinorVersion = property_get_int32("ro.camera.wrapper.hal3TrebleMinorVersion", 3);
294 ALOGV("Preferred HAL 3 minor version is %d", mPreferredHal3MinorVersion);
295 switch(mPreferredHal3MinorVersion) {
296 case 2:
297 case 3:
298 // OK
299 break;
300 default:
301 ALOGW("Unknown minor camera device HAL version %d in property "
302 "'camera.wrapper.hal3TrebleMinorVersion', defaulting to 3", mPreferredHal3MinorVersion);
303 mPreferredHal3MinorVersion = 3;
304 }
305
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -0800306 mNumberOfLegacyCameras = mModule->getNumberOfCameras();
307 for (int i = 0; i < mNumberOfLegacyCameras; i++) {
Emilian Peevc9ded512017-04-10 16:12:55 +0100308 struct camera_info info;
309 auto rc = mModule->getCameraInfo(i, &info);
310 if (rc != NO_ERROR) {
311 ALOGE("%s: Camera info query failed!", __func__);
312 mModule.clear();
313 return true;
314 }
315
316 if (checkCameraVersion(i, info) != OK) {
317 ALOGE("%s: Camera version check failed!", __func__);
318 mModule.clear();
319 return true;
320 }
321
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -0800322 char cameraId[kMaxCameraIdLen];
323 snprintf(cameraId, sizeof(cameraId), "%d", i);
324 std::string cameraIdStr(cameraId);
325 mCameraStatusMap[cameraIdStr] = CAMERA_DEVICE_STATUS_PRESENT;
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -0800326
Guennadi Liakhovetski7b7ede72017-11-28 09:28:56 +0100327 addDeviceNames(i);
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -0800328 }
329
Eino-Ville Talvala0f5eb832017-02-09 19:45:31 -0800330 return false; // mInitFailed
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -0800331}
332
Emilian Peevc9ded512017-04-10 16:12:55 +0100333/**
334 * Check that the device HAL version is still in supported.
335 */
336int CameraProvider::checkCameraVersion(int id, camera_info info) {
337 if (mModule == nullptr) {
338 return NO_INIT;
339 }
340
341 // device_version undefined in CAMERA_MODULE_API_VERSION_1_0,
342 // All CAMERA_MODULE_API_VERSION_1_0 devices are backward-compatible
343 if (mModule->getModuleApiVersion() >= CAMERA_MODULE_API_VERSION_2_0) {
344 // Verify the device version is in the supported range
345 switch (info.device_version) {
346 case CAMERA_DEVICE_API_VERSION_1_0:
347 case CAMERA_DEVICE_API_VERSION_3_2:
348 case CAMERA_DEVICE_API_VERSION_3_3:
349 case CAMERA_DEVICE_API_VERSION_3_4:
350 // in support
351 break;
352 case CAMERA_DEVICE_API_VERSION_2_0:
353 case CAMERA_DEVICE_API_VERSION_2_1:
354 case CAMERA_DEVICE_API_VERSION_3_0:
355 case CAMERA_DEVICE_API_VERSION_3_1:
356 // no longer supported
357 default:
358 ALOGE("%s: Device %d has HAL version %x, which is not supported",
359 __FUNCTION__, id, info.device_version);
360 return NO_INIT;
361 }
362 }
363
364 return OK;
365}
366
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -0800367bool CameraProvider::setUpVendorTags() {
368 ATRACE_CALL();
369 vendor_tag_ops_t vOps = vendor_tag_ops_t();
370
371 // Check if vendor operations have been implemented
372 if (!mModule->isVendorTagDefined()) {
373 ALOGI("%s: No vendor tags defined for this device.", __FUNCTION__);
Eino-Ville Talvala0f5eb832017-02-09 19:45:31 -0800374 return true;
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -0800375 }
376
377 mModule->getVendorTagOps(&vOps);
378
379 // Ensure all vendor operations are present
380 if (vOps.get_tag_count == nullptr || vOps.get_all_tags == nullptr ||
381 vOps.get_section_name == nullptr || vOps.get_tag_name == nullptr ||
382 vOps.get_tag_type == nullptr) {
383 ALOGE("%s: Vendor tag operations not fully defined. Ignoring definitions."
384 , __FUNCTION__);
385 return false;
386 }
387
388 // Read all vendor tag definitions into a descriptor
389 sp<VendorTagDescriptor> desc;
390 status_t res;
391 if ((res = VendorTagDescriptor::createDescriptorFromOps(&vOps, /*out*/desc))
392 != OK) {
393 ALOGE("%s: Could not generate descriptor from vendor tag operations,"
394 "received error %s (%d). Camera clients will not be able to use"
395 "vendor tags", __FUNCTION__, strerror(res), res);
396 return false;
397 }
398
399 // Set the global descriptor to use with camera metadata
400 VendorTagDescriptor::setAsGlobalVendorTagDescriptor(desc);
401 const SortedVector<String8>* sectionNames = desc->getAllSectionNames();
402 size_t numSections = sectionNames->size();
403 std::vector<std::vector<VendorTag>> tagsBySection(numSections);
404 int tagCount = desc->getTagCount();
405 std::vector<uint32_t> tags(tagCount);
406 desc->getTagArray(tags.data());
407 for (int i = 0; i < tagCount; i++) {
408 VendorTag vt;
409 vt.tagId = tags[i];
410 vt.tagName = desc->getTagName(tags[i]);
411 vt.tagType = (CameraMetadataType) desc->getTagType(tags[i]);
412 ssize_t sectionIdx = desc->getSectionIndex(tags[i]);
413 tagsBySection[sectionIdx].push_back(vt);
414 }
415 mVendorTagSections.resize(numSections);
416 for (size_t s = 0; s < numSections; s++) {
417 mVendorTagSections[s].sectionName = (*sectionNames)[s].string();
418 mVendorTagSections[s].tags = tagsBySection[s];
419 }
420 return true;
421}
422
423// Methods from ::android::hardware::camera::provider::V2_4::ICameraProvider follow.
424Return<Status> CameraProvider::setCallback(const sp<ICameraProviderCallback>& callback) {
Yin-Chia Yehfca2e742017-01-31 16:00:20 -0800425 Mutex::Autolock _l(mCbLock);
426 mCallbacks = callback;
427 return Status::OK;
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -0800428}
429
430Return<void> CameraProvider::getVendorTags(getVendorTags_cb _hidl_cb) {
431 _hidl_cb(Status::OK, mVendorTagSections);
432 return Void();
433}
434
435Return<void> CameraProvider::getCameraIdList(getCameraIdList_cb _hidl_cb) {
436 std::vector<hidl_string> deviceNameList;
437 for (auto const& deviceNamePair : mCameraDeviceNames) {
438 if (mCameraStatusMap[deviceNamePair.first] == CAMERA_DEVICE_STATUS_PRESENT) {
439 deviceNameList.push_back(deviceNamePair.second);
440 }
441 }
442 hidl_vec<hidl_string> hidlDeviceNameList(deviceNameList);
Yin-Chia Yeh9c6dbd52016-12-22 14:55:02 -0800443 _hidl_cb(Status::OK, hidlDeviceNameList);
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -0800444 return Void();
445}
446
447Return<void> CameraProvider::isSetTorchModeSupported(isSetTorchModeSupported_cb _hidl_cb) {
448 bool support = mModule->isSetTorchModeSupported();
449 _hidl_cb (Status::OK, support);
450 return Void();
451}
452
Yin-Chia Yeh9c6dbd52016-12-22 14:55:02 -0800453Return<void> CameraProvider::getCameraDeviceInterface_V1_x(
Yin-Chia Yeh248ed702017-01-23 17:27:26 -0800454 const hidl_string& cameraDeviceName, getCameraDeviceInterface_V1_x_cb _hidl_cb) {
Andreas Gampe0b171f12017-04-04 20:02:25 -0700455 std::string cameraId, deviceVersion;
456 bool match = matchDeviceName(cameraDeviceName, &deviceVersion, &cameraId);
Yin-Chia Yeh248ed702017-01-23 17:27:26 -0800457 if (!match) {
458 _hidl_cb(Status::ILLEGAL_ARGUMENT, nullptr);
459 return Void();
460 }
461
Yin-Chia Yeh248ed702017-01-23 17:27:26 -0800462 std::string deviceName(cameraDeviceName.c_str());
463 ssize_t index = mCameraDeviceNames.indexOf(std::make_pair(cameraId, deviceName));
464 if (index == NAME_NOT_FOUND) { // Either an illegal name or a device version mismatch
465 Status status = Status::OK;
466 ssize_t idx = mCameraIds.indexOf(cameraId);
467 if (idx == NAME_NOT_FOUND) {
468 ALOGE("%s: cannot find camera %s!", __FUNCTION__, cameraId.c_str());
469 status = Status::ILLEGAL_ARGUMENT;
470 } else { // invalid version
471 ALOGE("%s: camera device %s does not support version %s!",
472 __FUNCTION__, cameraId.c_str(), deviceVersion.c_str());
473 status = Status::OPERATION_NOT_SUPPORTED;
474 }
475 _hidl_cb(status, nullptr);
476 return Void();
477 }
478
479 if (mCameraStatusMap.count(cameraId) == 0 ||
480 mCameraStatusMap[cameraId] != CAMERA_DEVICE_STATUS_PRESENT) {
481 _hidl_cb(Status::ILLEGAL_ARGUMENT, nullptr);
482 return Void();
483 }
484
485 sp<android::hardware::camera::device::V1_0::implementation::CameraDevice> device =
486 new android::hardware::camera::device::V1_0::implementation::CameraDevice(
487 mModule, cameraId, mCameraDeviceNames);
488
489 if (device == nullptr) {
490 ALOGE("%s: cannot allocate camera device for id %s", __FUNCTION__, cameraId.c_str());
491 _hidl_cb(Status::INTERNAL_ERROR, nullptr);
492 return Void();
493 }
494
495 if (device->isInitFailed()) {
496 ALOGE("%s: camera device %s init failed!", __FUNCTION__, cameraId.c_str());
497 device = nullptr;
498 _hidl_cb(Status::INTERNAL_ERROR, nullptr);
499 return Void();
500 }
501
502 _hidl_cb (Status::OK, device);
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -0800503 return Void();
504}
505
Yin-Chia Yeh9c6dbd52016-12-22 14:55:02 -0800506Return<void> CameraProvider::getCameraDeviceInterface_V3_x(
507 const hidl_string& cameraDeviceName, getCameraDeviceInterface_V3_x_cb _hidl_cb) {
Andreas Gampe0b171f12017-04-04 20:02:25 -0700508 std::string cameraId, deviceVersion;
509 bool match = matchDeviceName(cameraDeviceName, &deviceVersion, &cameraId);
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -0800510 if (!match) {
511 _hidl_cb(Status::ILLEGAL_ARGUMENT, nullptr);
512 return Void();
513 }
514
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -0800515 std::string deviceName(cameraDeviceName.c_str());
516 ssize_t index = mCameraDeviceNames.indexOf(std::make_pair(cameraId, deviceName));
517 if (index == NAME_NOT_FOUND) { // Either an illegal name or a device version mismatch
518 Status status = Status::OK;
519 ssize_t idx = mCameraIds.indexOf(cameraId);
520 if (idx == NAME_NOT_FOUND) {
Yin-Chia Yeh9c6dbd52016-12-22 14:55:02 -0800521 ALOGE("%s: cannot find camera %s!", __FUNCTION__, cameraId.c_str());
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -0800522 status = Status::ILLEGAL_ARGUMENT;
523 } else { // invalid version
Yin-Chia Yeh9c6dbd52016-12-22 14:55:02 -0800524 ALOGE("%s: camera device %s does not support version %s!",
525 __FUNCTION__, cameraId.c_str(), deviceVersion.c_str());
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -0800526 status = Status::OPERATION_NOT_SUPPORTED;
527 }
528 _hidl_cb(status, nullptr);
529 return Void();
530 }
531
532 if (mCameraStatusMap.count(cameraId) == 0 ||
533 mCameraStatusMap[cameraId] != CAMERA_DEVICE_STATUS_PRESENT) {
534 _hidl_cb(Status::ILLEGAL_ARGUMENT, nullptr);
535 return Void();
536 }
537
Eino-Ville Talvala50fe4302017-08-22 16:15:09 -0700538 // Since some Treble HAL revisions can map to the same legacy HAL version(s), we default
539 // to the newest possible Treble HAL revision, but allow for override if needed via
540 // system property.
541 sp<android::hardware::camera::device::V3_2::ICameraDevice> device;
542 switch (mPreferredHal3MinorVersion) {
543 case 2: { // Map legacy camera device v3 HAL to Treble camera device HAL v3.2
544 ALOGV("Constructing v3.2 camera device");
545 sp<android::hardware::camera::device::V3_2::implementation::CameraDevice> deviceImpl =
546 new android::hardware::camera::device::V3_2::implementation::CameraDevice(
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -0800547 mModule, cameraId, mCameraDeviceNames);
Eino-Ville Talvala50fe4302017-08-22 16:15:09 -0700548 if (deviceImpl == nullptr || deviceImpl->isInitFailed()) {
549 ALOGE("%s: camera device %s init failed!", __FUNCTION__, cameraId.c_str());
550 device = nullptr;
551 _hidl_cb(Status::INTERNAL_ERROR, nullptr);
552 return Void();
553 }
554 device = deviceImpl;
555 break;
556 }
557 case 3: { // Map legacy camera device v3 HAL to Treble camera device HAL v3.3
558 ALOGV("Constructing v3.3 camera device");
559 sp<android::hardware::camera::device::V3_2::implementation::CameraDevice> deviceImpl =
560 new android::hardware::camera::device::V3_3::implementation::CameraDevice(
561 mModule, cameraId, mCameraDeviceNames);
562 if (deviceImpl == nullptr || deviceImpl->isInitFailed()) {
563 ALOGE("%s: camera device %s init failed!", __FUNCTION__, cameraId.c_str());
564 device = nullptr;
565 _hidl_cb(Status::INTERNAL_ERROR, nullptr);
566 return Void();
567 }
568 device = deviceImpl;
569 break;
570 }
571 default:
572 ALOGE("%s: Unknown HAL minor version %d!", __FUNCTION__, mPreferredHal3MinorVersion);
573 device = nullptr;
574 _hidl_cb(Status::INTERNAL_ERROR, nullptr);
575 return Void();
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -0800576 }
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -0800577 _hidl_cb (Status::OK, device);
578 return Void();
579}
580
581ICameraProvider* HIDL_FETCH_ICameraProvider(const char* name) {
582 if (strcmp(name, kLegacyProviderName) != 0) {
583 return nullptr;
584 }
585 CameraProvider* provider = new CameraProvider();
586 if (provider == nullptr) {
587 ALOGE("%s: cannot allocate camera provider!", __FUNCTION__);
588 return nullptr;
589 }
590 if (provider->isInitFailed()) {
591 ALOGE("%s: camera provider init failed!", __FUNCTION__);
592 delete provider;
593 return nullptr;
594 }
595 return provider;
596}
597
598} // namespace implementation
599} // namespace V2_4
600} // namespace provider
601} // namespace camera
602} // namespace hardware
603} // namespace android