1 /*
2 * Copyright (C) 2016 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #define LOG_TAG "CamProvider@2.4-impl"
18 #include <android/log.h>
19
20 #include "CameraProvider.h"
21 #include "CameraDevice_1_0.h"
22 #include "CameraDevice_3_2.h"
23 #include <string.h>
24 #include <utils/Trace.h>
25
26
27 namespace android {
28 namespace hardware {
29 namespace camera {
30 namespace provider {
31 namespace V2_4 {
32 namespace implementation {
33
34 namespace {
35 const char *kLegacyProviderName = "legacy/0";
36 // "device@<version>/legacy/<id>"
37 const std::regex kDeviceNameRE("device@([0-9]+\\.[0-9]+)/legacy/(.+)");
38 const char *kHAL3_2 = "3.2";
39 const char *kHAL1_0 = "1.0";
40 const int kMaxCameraDeviceNameLen = 128;
41 const int kMaxCameraIdLen = 16;
42
matchDeviceName(const hidl_string & deviceName,std::string * deviceVersion,std::string * cameraId)43 bool matchDeviceName(const hidl_string& deviceName, std::string* deviceVersion,
44 std::string* cameraId) {
45 std::string deviceNameStd(deviceName.c_str());
46 std::smatch sm;
47 if (std::regex_match(deviceNameStd, sm, kDeviceNameRE)) {
48 if (deviceVersion != nullptr) {
49 *deviceVersion = sm[1];
50 }
51 if (cameraId != nullptr) {
52 *cameraId = sm[2];
53 }
54 return true;
55 }
56 return false;
57 }
58
59 } // anonymous namespace
60
61 using ::android::hardware::camera::common::V1_0::CameraMetadataType;
62 using ::android::hardware::camera::common::V1_0::Status;
63
64 /**
65 * static callback forwarding methods from HAL to instance
66 */
sCameraDeviceStatusChange(const struct camera_module_callbacks * callbacks,int camera_id,int new_status)67 void CameraProvider::sCameraDeviceStatusChange(
68 const struct camera_module_callbacks* callbacks,
69 int camera_id,
70 int new_status) {
71 CameraProvider* cp = const_cast<CameraProvider*>(
72 static_cast<const CameraProvider*>(callbacks));
73
74 if (cp == nullptr) {
75 ALOGE("%s: callback ops is null", __FUNCTION__);
76 return;
77 }
78
79 Mutex::Autolock _l(cp->mCbLock);
80 char cameraId[kMaxCameraIdLen];
81 snprintf(cameraId, sizeof(cameraId), "%d", camera_id);
82 std::string cameraIdStr(cameraId);
83 cp->mCameraStatusMap[cameraIdStr] = (camera_device_status_t) new_status;
84 if (cp->mCallbacks != nullptr) {
85 CameraDeviceStatus status = (CameraDeviceStatus) new_status;
86 for (auto const& deviceNamePair : cp->mCameraDeviceNames) {
87 if (cameraIdStr.compare(deviceNamePair.first) == 0) {
88 cp->mCallbacks->cameraDeviceStatusChange(
89 deviceNamePair.second, status);
90 }
91 }
92 }
93 }
94
sTorchModeStatusChange(const struct camera_module_callbacks * callbacks,const char * camera_id,int new_status)95 void CameraProvider::sTorchModeStatusChange(
96 const struct camera_module_callbacks* callbacks,
97 const char* camera_id,
98 int new_status) {
99 CameraProvider* cp = const_cast<CameraProvider*>(
100 static_cast<const CameraProvider*>(callbacks));
101
102 if (cp == nullptr) {
103 ALOGE("%s: callback ops is null", __FUNCTION__);
104 return;
105 }
106
107 Mutex::Autolock _l(cp->mCbLock);
108 if (cp->mCallbacks != nullptr) {
109 std::string cameraIdStr(camera_id);
110 TorchModeStatus status = (TorchModeStatus) new_status;
111 for (auto const& deviceNamePair : cp->mCameraDeviceNames) {
112 if (cameraIdStr.compare(deviceNamePair.first) == 0) {
113 cp->mCallbacks->torchModeStatusChange(
114 deviceNamePair.second, status);
115 }
116 }
117 }
118 }
119
getHidlStatus(int status)120 Status CameraProvider::getHidlStatus(int status) {
121 switch (status) {
122 case 0: return Status::OK;
123 case -ENODEV: return Status::INTERNAL_ERROR;
124 case -EINVAL: return Status::ILLEGAL_ARGUMENT;
125 default:
126 ALOGE("%s: unknown HAL status code %d", __FUNCTION__, status);
127 return Status::INTERNAL_ERROR;
128 }
129 }
130
getLegacyCameraId(const hidl_string & deviceName)131 std::string CameraProvider::getLegacyCameraId(const hidl_string& deviceName) {
132 std::string cameraId;
133 matchDeviceName(deviceName, nullptr, &cameraId);
134 return cameraId;
135 }
136
getCameraDeviceVersion(const hidl_string & deviceName)137 int CameraProvider::getCameraDeviceVersion(const hidl_string& deviceName) {
138 std::string deviceVersion;
139 bool match = matchDeviceName(deviceName, &deviceVersion, nullptr);
140 if (!match) {
141 return -1;
142 }
143 if (deviceVersion == kHAL3_2) {
144 // maybe switched to 3.4 or define the hidl version enum later
145 return CAMERA_DEVICE_API_VERSION_3_2;
146 } else if (deviceVersion == kHAL1_0) {
147 return CAMERA_DEVICE_API_VERSION_1_0;
148 }
149 return 0;
150 }
151
getHidlDeviceName(std::string cameraId,int deviceVersion)152 std::string CameraProvider::getHidlDeviceName(
153 std::string cameraId, int deviceVersion) {
154 // Maybe consider create a version check method and SortedVec to speed up?
155 if (deviceVersion != CAMERA_DEVICE_API_VERSION_1_0 &&
156 deviceVersion != CAMERA_DEVICE_API_VERSION_3_2 &&
157 deviceVersion != CAMERA_DEVICE_API_VERSION_3_3 &&
158 deviceVersion != CAMERA_DEVICE_API_VERSION_3_4 ) {
159 return hidl_string("");
160 }
161 const char* versionStr = (deviceVersion == CAMERA_DEVICE_API_VERSION_1_0) ? kHAL1_0 : kHAL3_2;
162 char deviceName[kMaxCameraDeviceNameLen];
163 snprintf(deviceName, sizeof(deviceName), "device@%s/legacy/%s",
164 versionStr, cameraId.c_str());
165 return deviceName;
166 }
167
CameraProvider()168 CameraProvider::CameraProvider() :
169 camera_module_callbacks_t({sCameraDeviceStatusChange,
170 sTorchModeStatusChange}) {
171 mInitFailed = initialize();
172 }
173
~CameraProvider()174 CameraProvider::~CameraProvider() {}
175
initialize()176 bool CameraProvider::initialize() {
177 camera_module_t *rawModule;
178 int err = hw_get_module(CAMERA_HARDWARE_MODULE_ID,
179 (const hw_module_t **)&rawModule);
180 if (err < 0) {
181 ALOGE("Could not load camera HAL module: %d (%s)", err, strerror(-err));
182 return true;
183 }
184
185 mModule = new CameraModule(rawModule);
186 err = mModule->init();
187 if (err != OK) {
188 ALOGE("Could not initialize camera HAL module: %d (%s)", err, strerror(-err));
189 mModule.clear();
190 return true;
191 }
192 ALOGI("Loaded \"%s\" camera module", mModule->getModuleName());
193
194 // Setup vendor tags here so HAL can setup vendor keys in camera characteristics
195 VendorTagDescriptor::clearGlobalVendorTagDescriptor();
196 if (!setUpVendorTags()) {
197 ALOGE("%s: Vendor tag setup failed, will not be available.", __FUNCTION__);
198 }
199
200 // Setup callback now because we are going to try openLegacy next
201 err = mModule->setCallbacks(this);
202 if (err != OK) {
203 ALOGE("Could not set camera module callback: %d (%s)", err, strerror(-err));
204 mModule.clear();
205 return true;
206 }
207
208 mNumberOfLegacyCameras = mModule->getNumberOfCameras();
209 for (int i = 0; i < mNumberOfLegacyCameras; i++) {
210 struct camera_info info;
211 auto rc = mModule->getCameraInfo(i, &info);
212 if (rc != NO_ERROR) {
213 ALOGE("%s: Camera info query failed!", __func__);
214 mModule.clear();
215 return true;
216 }
217
218 if (checkCameraVersion(i, info) != OK) {
219 ALOGE("%s: Camera version check failed!", __func__);
220 mModule.clear();
221 return true;
222 }
223
224 char cameraId[kMaxCameraIdLen];
225 snprintf(cameraId, sizeof(cameraId), "%d", i);
226 std::string cameraIdStr(cameraId);
227 mCameraStatusMap[cameraIdStr] = CAMERA_DEVICE_STATUS_PRESENT;
228 mCameraIds.add(cameraIdStr);
229
230 // initialize mCameraDeviceNames and mOpenLegacySupported
231 mOpenLegacySupported[cameraIdStr] = false;
232 int deviceVersion = mModule->getDeviceVersion(i);
233 mCameraDeviceNames.add(
234 std::make_pair(cameraIdStr,
235 getHidlDeviceName(cameraIdStr, deviceVersion)));
236 if (deviceVersion >= CAMERA_DEVICE_API_VERSION_3_2 &&
237 mModule->isOpenLegacyDefined()) {
238 // try open_legacy to see if it actually works
239 struct hw_device_t* halDev = nullptr;
240 int ret = mModule->openLegacy(cameraId, CAMERA_DEVICE_API_VERSION_1_0, &halDev);
241 if (ret == 0) {
242 mOpenLegacySupported[cameraIdStr] = true;
243 halDev->close(halDev);
244 mCameraDeviceNames.add(
245 std::make_pair(cameraIdStr,
246 getHidlDeviceName(cameraIdStr, CAMERA_DEVICE_API_VERSION_1_0)));
247 } else if (ret == -EBUSY || ret == -EUSERS) {
248 // Looks like this provider instance is not initialized during
249 // system startup and there are other camera users already.
250 // Not a good sign but not fatal.
251 ALOGW("%s: open_legacy try failed!", __FUNCTION__);
252 }
253 }
254 }
255
256 return false; // mInitFailed
257 }
258
259 /**
260 * Check that the device HAL version is still in supported.
261 */
checkCameraVersion(int id,camera_info info)262 int CameraProvider::checkCameraVersion(int id, camera_info info) {
263 if (mModule == nullptr) {
264 return NO_INIT;
265 }
266
267 // device_version undefined in CAMERA_MODULE_API_VERSION_1_0,
268 // All CAMERA_MODULE_API_VERSION_1_0 devices are backward-compatible
269 if (mModule->getModuleApiVersion() >= CAMERA_MODULE_API_VERSION_2_0) {
270 // Verify the device version is in the supported range
271 switch (info.device_version) {
272 case CAMERA_DEVICE_API_VERSION_1_0:
273 case CAMERA_DEVICE_API_VERSION_3_2:
274 case CAMERA_DEVICE_API_VERSION_3_3:
275 case CAMERA_DEVICE_API_VERSION_3_4:
276 // in support
277 break;
278 case CAMERA_DEVICE_API_VERSION_2_0:
279 case CAMERA_DEVICE_API_VERSION_2_1:
280 case CAMERA_DEVICE_API_VERSION_3_0:
281 case CAMERA_DEVICE_API_VERSION_3_1:
282 // no longer supported
283 default:
284 ALOGE("%s: Device %d has HAL version %x, which is not supported",
285 __FUNCTION__, id, info.device_version);
286 return NO_INIT;
287 }
288 }
289
290 return OK;
291 }
292
setUpVendorTags()293 bool CameraProvider::setUpVendorTags() {
294 ATRACE_CALL();
295 vendor_tag_ops_t vOps = vendor_tag_ops_t();
296
297 // Check if vendor operations have been implemented
298 if (!mModule->isVendorTagDefined()) {
299 ALOGI("%s: No vendor tags defined for this device.", __FUNCTION__);
300 return true;
301 }
302
303 mModule->getVendorTagOps(&vOps);
304
305 // Ensure all vendor operations are present
306 if (vOps.get_tag_count == nullptr || vOps.get_all_tags == nullptr ||
307 vOps.get_section_name == nullptr || vOps.get_tag_name == nullptr ||
308 vOps.get_tag_type == nullptr) {
309 ALOGE("%s: Vendor tag operations not fully defined. Ignoring definitions."
310 , __FUNCTION__);
311 return false;
312 }
313
314 // Read all vendor tag definitions into a descriptor
315 sp<VendorTagDescriptor> desc;
316 status_t res;
317 if ((res = VendorTagDescriptor::createDescriptorFromOps(&vOps, /*out*/desc))
318 != OK) {
319 ALOGE("%s: Could not generate descriptor from vendor tag operations,"
320 "received error %s (%d). Camera clients will not be able to use"
321 "vendor tags", __FUNCTION__, strerror(res), res);
322 return false;
323 }
324
325 // Set the global descriptor to use with camera metadata
326 VendorTagDescriptor::setAsGlobalVendorTagDescriptor(desc);
327 const SortedVector<String8>* sectionNames = desc->getAllSectionNames();
328 size_t numSections = sectionNames->size();
329 std::vector<std::vector<VendorTag>> tagsBySection(numSections);
330 int tagCount = desc->getTagCount();
331 std::vector<uint32_t> tags(tagCount);
332 desc->getTagArray(tags.data());
333 for (int i = 0; i < tagCount; i++) {
334 VendorTag vt;
335 vt.tagId = tags[i];
336 vt.tagName = desc->getTagName(tags[i]);
337 vt.tagType = (CameraMetadataType) desc->getTagType(tags[i]);
338 ssize_t sectionIdx = desc->getSectionIndex(tags[i]);
339 tagsBySection[sectionIdx].push_back(vt);
340 }
341 mVendorTagSections.resize(numSections);
342 for (size_t s = 0; s < numSections; s++) {
343 mVendorTagSections[s].sectionName = (*sectionNames)[s].string();
344 mVendorTagSections[s].tags = tagsBySection[s];
345 }
346 return true;
347 }
348
349 // Methods from ::android::hardware::camera::provider::V2_4::ICameraProvider follow.
setCallback(const sp<ICameraProviderCallback> & callback)350 Return<Status> CameraProvider::setCallback(const sp<ICameraProviderCallback>& callback) {
351 Mutex::Autolock _l(mCbLock);
352 mCallbacks = callback;
353 return Status::OK;
354 }
355
getVendorTags(getVendorTags_cb _hidl_cb)356 Return<void> CameraProvider::getVendorTags(getVendorTags_cb _hidl_cb) {
357 _hidl_cb(Status::OK, mVendorTagSections);
358 return Void();
359 }
360
getCameraIdList(getCameraIdList_cb _hidl_cb)361 Return<void> CameraProvider::getCameraIdList(getCameraIdList_cb _hidl_cb) {
362 std::vector<hidl_string> deviceNameList;
363 for (auto const& deviceNamePair : mCameraDeviceNames) {
364 if (mCameraStatusMap[deviceNamePair.first] == CAMERA_DEVICE_STATUS_PRESENT) {
365 deviceNameList.push_back(deviceNamePair.second);
366 }
367 }
368 hidl_vec<hidl_string> hidlDeviceNameList(deviceNameList);
369 _hidl_cb(Status::OK, hidlDeviceNameList);
370 return Void();
371 }
372
isSetTorchModeSupported(isSetTorchModeSupported_cb _hidl_cb)373 Return<void> CameraProvider::isSetTorchModeSupported(isSetTorchModeSupported_cb _hidl_cb) {
374 bool support = mModule->isSetTorchModeSupported();
375 _hidl_cb (Status::OK, support);
376 return Void();
377 }
378
getCameraDeviceInterface_V1_x(const hidl_string & cameraDeviceName,getCameraDeviceInterface_V1_x_cb _hidl_cb)379 Return<void> CameraProvider::getCameraDeviceInterface_V1_x(
380 const hidl_string& cameraDeviceName, getCameraDeviceInterface_V1_x_cb _hidl_cb) {
381 std::string cameraId, deviceVersion;
382 bool match = matchDeviceName(cameraDeviceName, &deviceVersion, &cameraId);
383 if (!match) {
384 _hidl_cb(Status::ILLEGAL_ARGUMENT, nullptr);
385 return Void();
386 }
387
388 std::string deviceName(cameraDeviceName.c_str());
389 ssize_t index = mCameraDeviceNames.indexOf(std::make_pair(cameraId, deviceName));
390 if (index == NAME_NOT_FOUND) { // Either an illegal name or a device version mismatch
391 Status status = Status::OK;
392 ssize_t idx = mCameraIds.indexOf(cameraId);
393 if (idx == NAME_NOT_FOUND) {
394 ALOGE("%s: cannot find camera %s!", __FUNCTION__, cameraId.c_str());
395 status = Status::ILLEGAL_ARGUMENT;
396 } else { // invalid version
397 ALOGE("%s: camera device %s does not support version %s!",
398 __FUNCTION__, cameraId.c_str(), deviceVersion.c_str());
399 status = Status::OPERATION_NOT_SUPPORTED;
400 }
401 _hidl_cb(status, nullptr);
402 return Void();
403 }
404
405 if (mCameraStatusMap.count(cameraId) == 0 ||
406 mCameraStatusMap[cameraId] != CAMERA_DEVICE_STATUS_PRESENT) {
407 _hidl_cb(Status::ILLEGAL_ARGUMENT, nullptr);
408 return Void();
409 }
410
411 sp<android::hardware::camera::device::V1_0::implementation::CameraDevice> device =
412 new android::hardware::camera::device::V1_0::implementation::CameraDevice(
413 mModule, cameraId, mCameraDeviceNames);
414
415 if (device == nullptr) {
416 ALOGE("%s: cannot allocate camera device for id %s", __FUNCTION__, cameraId.c_str());
417 _hidl_cb(Status::INTERNAL_ERROR, nullptr);
418 return Void();
419 }
420
421 if (device->isInitFailed()) {
422 ALOGE("%s: camera device %s init failed!", __FUNCTION__, cameraId.c_str());
423 device = nullptr;
424 _hidl_cb(Status::INTERNAL_ERROR, nullptr);
425 return Void();
426 }
427
428 _hidl_cb (Status::OK, device);
429 return Void();
430 }
431
getCameraDeviceInterface_V3_x(const hidl_string & cameraDeviceName,getCameraDeviceInterface_V3_x_cb _hidl_cb)432 Return<void> CameraProvider::getCameraDeviceInterface_V3_x(
433 const hidl_string& cameraDeviceName, getCameraDeviceInterface_V3_x_cb _hidl_cb) {
434 std::string cameraId, deviceVersion;
435 bool match = matchDeviceName(cameraDeviceName, &deviceVersion, &cameraId);
436 if (!match) {
437 _hidl_cb(Status::ILLEGAL_ARGUMENT, nullptr);
438 return Void();
439 }
440
441 std::string deviceName(cameraDeviceName.c_str());
442 ssize_t index = mCameraDeviceNames.indexOf(std::make_pair(cameraId, deviceName));
443 if (index == NAME_NOT_FOUND) { // Either an illegal name or a device version mismatch
444 Status status = Status::OK;
445 ssize_t idx = mCameraIds.indexOf(cameraId);
446 if (idx == NAME_NOT_FOUND) {
447 ALOGE("%s: cannot find camera %s!", __FUNCTION__, cameraId.c_str());
448 status = Status::ILLEGAL_ARGUMENT;
449 } else { // invalid version
450 ALOGE("%s: camera device %s does not support version %s!",
451 __FUNCTION__, cameraId.c_str(), deviceVersion.c_str());
452 status = Status::OPERATION_NOT_SUPPORTED;
453 }
454 _hidl_cb(status, nullptr);
455 return Void();
456 }
457
458 if (mCameraStatusMap.count(cameraId) == 0 ||
459 mCameraStatusMap[cameraId] != CAMERA_DEVICE_STATUS_PRESENT) {
460 _hidl_cb(Status::ILLEGAL_ARGUMENT, nullptr);
461 return Void();
462 }
463
464 sp<android::hardware::camera::device::V3_2::implementation::CameraDevice> device =
465 new android::hardware::camera::device::V3_2::implementation::CameraDevice(
466 mModule, cameraId, mCameraDeviceNames);
467
468 if (device == nullptr) {
469 ALOGE("%s: cannot allocate camera device for id %s", __FUNCTION__, cameraId.c_str());
470 _hidl_cb(Status::INTERNAL_ERROR, nullptr);
471 return Void();
472 }
473
474 if (device->isInitFailed()) {
475 ALOGE("%s: camera device %s init failed!", __FUNCTION__, cameraId.c_str());
476 device = nullptr;
477 _hidl_cb(Status::INTERNAL_ERROR, nullptr);
478 return Void();
479 }
480
481 _hidl_cb (Status::OK, device);
482 return Void();
483 }
484
HIDL_FETCH_ICameraProvider(const char * name)485 ICameraProvider* HIDL_FETCH_ICameraProvider(const char* name) {
486 if (strcmp(name, kLegacyProviderName) != 0) {
487 return nullptr;
488 }
489 CameraProvider* provider = new CameraProvider();
490 if (provider == nullptr) {
491 ALOGE("%s: cannot allocate camera provider!", __FUNCTION__);
492 return nullptr;
493 }
494 if (provider->isInitFailed()) {
495 ALOGE("%s: camera provider init failed!", __FUNCTION__);
496 delete provider;
497 return nullptr;
498 }
499 return provider;
500 }
501
502 } // namespace implementation
503 } // namespace V2_4
504 } // namespace provider
505 } // namespace camera
506 } // namespace hardware
507 } // namespace android
508