blob: 9f4d18838c0fb9d05144b1f0d58e0ebb98c95dd9 [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"
18#include <android/log.h>
19
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -080020#include "CameraProvider.h"
Yin-Chia Yeh248ed702017-01-23 17:27:26 -080021#include "CameraDevice_1_0.h"
22#include "CameraDevice_3_2.h"
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -080023#include <string.h>
24#include <utils/Trace.h>
25
26
27namespace android {
28namespace hardware {
29namespace camera {
30namespace provider {
31namespace V2_4 {
32namespace implementation {
33
34namespace {
35const char *kLegacyProviderName = "legacy/0";
36// "device@<version>/legacy/<id>"
37const std::regex kDeviceNameRE("device@([0-9]+\\.[0-9]+)/legacy/(.+)");
38const char *kHAL3_2 = "3.2";
39const char *kHAL1_0 = "1.0";
40const int kMaxCameraDeviceNameLen = 128;
41const int kMaxCameraIdLen = 16;
42
Andreas Gampe0b171f12017-04-04 20:02:25 -070043bool 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
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -080059} // anonymous namespace
60
61using ::android::hardware::camera::common::V1_0::CameraMetadataType;
62using ::android::hardware::camera::common::V1_0::Status;
63
64/**
65 * static callback forwarding methods from HAL to instance
66 */
67void CameraProvider::sCameraDeviceStatusChange(
68 const struct camera_module_callbacks* callbacks,
69 int camera_id,
70 int new_status) {
Yin-Chia Yeh6dc9b532017-02-09 18:43:35 -080071 CameraProvider* cp = const_cast<CameraProvider*>(
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -080072 static_cast<const CameraProvider*>(callbacks));
73
74 if (cp == nullptr) {
75 ALOGE("%s: callback ops is null", __FUNCTION__);
76 return;
77 }
78
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -080079 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 }
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -080093}
94
95void CameraProvider::sTorchModeStatusChange(
96 const struct camera_module_callbacks* callbacks,
97 const char* camera_id,
98 int new_status) {
Yin-Chia Yeh6dc9b532017-02-09 18:43:35 -080099 CameraProvider* cp = const_cast<CameraProvider*>(
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -0800100 static_cast<const CameraProvider*>(callbacks));
101
102 if (cp == nullptr) {
103 ALOGE("%s: callback ops is null", __FUNCTION__);
104 return;
105 }
106
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -0800107 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) {
Yin-Chia Yeh9c6dbd52016-12-22 14:55:02 -0800112 if (cameraIdStr.compare(deviceNamePair.first) == 0) {
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -0800113 cp->mCallbacks->torchModeStatusChange(
114 deviceNamePair.second, status);
115 }
116 }
117 }
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -0800118}
119
120Status 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
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -0800131std::string CameraProvider::getLegacyCameraId(const hidl_string& deviceName) {
Andreas Gampe0b171f12017-04-04 20:02:25 -0700132 std::string cameraId;
133 matchDeviceName(deviceName, nullptr, &cameraId);
134 return cameraId;
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -0800135}
136
137int CameraProvider::getCameraDeviceVersion(const hidl_string& deviceName) {
Andreas Gampe0b171f12017-04-04 20:02:25 -0700138 std::string deviceVersion;
139 bool match = matchDeviceName(deviceName, &deviceVersion, nullptr);
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -0800140 if (!match) {
141 return -1;
142 }
Andreas Gampe0b171f12017-04-04 20:02:25 -0700143 if (deviceVersion == kHAL3_2) {
Yin-Chia Yeh9c6dbd52016-12-22 14:55:02 -0800144 // maybe switched to 3.4 or define the hidl version enum later
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -0800145 return CAMERA_DEVICE_API_VERSION_3_2;
Andreas Gampe0b171f12017-04-04 20:02:25 -0700146 } else if (deviceVersion == kHAL1_0) {
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -0800147 return CAMERA_DEVICE_API_VERSION_1_0;
148 }
149 return 0;
150}
151
152std::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
168CameraProvider::CameraProvider() :
169 camera_module_callbacks_t({sCameraDeviceStatusChange,
170 sTorchModeStatusChange}) {
171 mInitFailed = initialize();
172}
173
174CameraProvider::~CameraProvider() {}
175
176bool 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) {
Yin-Chia Yehfca2e742017-01-31 16:00:20 -0800188 ALOGE("Could not initialize camera HAL module: %d (%s)", err, strerror(-err));
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -0800189 mModule.clear();
190 return true;
191 }
192 ALOGI("Loaded \"%s\" camera module", mModule->getModuleName());
193
Shuzhen Wangefb7bfa2017-03-15 18:26:39 -0700194 // 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
Yin-Chia Yehfca2e742017-01-31 16:00:20 -0800200 // 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
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -0800208 mNumberOfLegacyCameras = mModule->getNumberOfCameras();
209 for (int i = 0; i < mNumberOfLegacyCameras; i++) {
210 char cameraId[kMaxCameraIdLen];
211 snprintf(cameraId, sizeof(cameraId), "%d", i);
212 std::string cameraIdStr(cameraId);
213 mCameraStatusMap[cameraIdStr] = CAMERA_DEVICE_STATUS_PRESENT;
214 mCameraIds.add(cameraIdStr);
215
216 // initialize mCameraDeviceNames and mOpenLegacySupported
217 mOpenLegacySupported[cameraIdStr] = false;
218 int deviceVersion = mModule->getDeviceVersion(i);
219 mCameraDeviceNames.add(
220 std::make_pair(cameraIdStr,
221 getHidlDeviceName(cameraIdStr, deviceVersion)));
222 if (deviceVersion >= CAMERA_DEVICE_API_VERSION_3_2 &&
223 mModule->isOpenLegacyDefined()) {
224 // try open_legacy to see if it actually works
225 struct hw_device_t* halDev = nullptr;
226 int ret = mModule->openLegacy(cameraId, CAMERA_DEVICE_API_VERSION_1_0, &halDev);
227 if (ret == 0) {
228 mOpenLegacySupported[cameraIdStr] = true;
229 halDev->close(halDev);
230 mCameraDeviceNames.add(
231 std::make_pair(cameraIdStr,
232 getHidlDeviceName(cameraIdStr, CAMERA_DEVICE_API_VERSION_1_0)));
233 } else if (ret == -EBUSY || ret == -EUSERS) {
234 // Looks like this provider instance is not initialized during
235 // system startup and there are other camera users already.
236 // Not a good sign but not fatal.
237 ALOGW("%s: open_legacy try failed!", __FUNCTION__);
238 }
239 }
240 }
241
Eino-Ville Talvala0f5eb832017-02-09 19:45:31 -0800242 return false; // mInitFailed
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -0800243}
244
245bool CameraProvider::setUpVendorTags() {
246 ATRACE_CALL();
247 vendor_tag_ops_t vOps = vendor_tag_ops_t();
248
249 // Check if vendor operations have been implemented
250 if (!mModule->isVendorTagDefined()) {
251 ALOGI("%s: No vendor tags defined for this device.", __FUNCTION__);
Eino-Ville Talvala0f5eb832017-02-09 19:45:31 -0800252 return true;
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -0800253 }
254
255 mModule->getVendorTagOps(&vOps);
256
257 // Ensure all vendor operations are present
258 if (vOps.get_tag_count == nullptr || vOps.get_all_tags == nullptr ||
259 vOps.get_section_name == nullptr || vOps.get_tag_name == nullptr ||
260 vOps.get_tag_type == nullptr) {
261 ALOGE("%s: Vendor tag operations not fully defined. Ignoring definitions."
262 , __FUNCTION__);
263 return false;
264 }
265
266 // Read all vendor tag definitions into a descriptor
267 sp<VendorTagDescriptor> desc;
268 status_t res;
269 if ((res = VendorTagDescriptor::createDescriptorFromOps(&vOps, /*out*/desc))
270 != OK) {
271 ALOGE("%s: Could not generate descriptor from vendor tag operations,"
272 "received error %s (%d). Camera clients will not be able to use"
273 "vendor tags", __FUNCTION__, strerror(res), res);
274 return false;
275 }
276
277 // Set the global descriptor to use with camera metadata
278 VendorTagDescriptor::setAsGlobalVendorTagDescriptor(desc);
279 const SortedVector<String8>* sectionNames = desc->getAllSectionNames();
280 size_t numSections = sectionNames->size();
281 std::vector<std::vector<VendorTag>> tagsBySection(numSections);
282 int tagCount = desc->getTagCount();
283 std::vector<uint32_t> tags(tagCount);
284 desc->getTagArray(tags.data());
285 for (int i = 0; i < tagCount; i++) {
286 VendorTag vt;
287 vt.tagId = tags[i];
288 vt.tagName = desc->getTagName(tags[i]);
289 vt.tagType = (CameraMetadataType) desc->getTagType(tags[i]);
290 ssize_t sectionIdx = desc->getSectionIndex(tags[i]);
291 tagsBySection[sectionIdx].push_back(vt);
292 }
293 mVendorTagSections.resize(numSections);
294 for (size_t s = 0; s < numSections; s++) {
295 mVendorTagSections[s].sectionName = (*sectionNames)[s].string();
296 mVendorTagSections[s].tags = tagsBySection[s];
297 }
298 return true;
299}
300
301// Methods from ::android::hardware::camera::provider::V2_4::ICameraProvider follow.
302Return<Status> CameraProvider::setCallback(const sp<ICameraProviderCallback>& callback) {
Yin-Chia Yehfca2e742017-01-31 16:00:20 -0800303 Mutex::Autolock _l(mCbLock);
304 mCallbacks = callback;
305 return Status::OK;
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -0800306}
307
308Return<void> CameraProvider::getVendorTags(getVendorTags_cb _hidl_cb) {
309 _hidl_cb(Status::OK, mVendorTagSections);
310 return Void();
311}
312
313Return<void> CameraProvider::getCameraIdList(getCameraIdList_cb _hidl_cb) {
314 std::vector<hidl_string> deviceNameList;
315 for (auto const& deviceNamePair : mCameraDeviceNames) {
316 if (mCameraStatusMap[deviceNamePair.first] == CAMERA_DEVICE_STATUS_PRESENT) {
317 deviceNameList.push_back(deviceNamePair.second);
318 }
319 }
320 hidl_vec<hidl_string> hidlDeviceNameList(deviceNameList);
Yin-Chia Yeh9c6dbd52016-12-22 14:55:02 -0800321 _hidl_cb(Status::OK, hidlDeviceNameList);
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -0800322 return Void();
323}
324
325Return<void> CameraProvider::isSetTorchModeSupported(isSetTorchModeSupported_cb _hidl_cb) {
326 bool support = mModule->isSetTorchModeSupported();
327 _hidl_cb (Status::OK, support);
328 return Void();
329}
330
Yin-Chia Yeh9c6dbd52016-12-22 14:55:02 -0800331Return<void> CameraProvider::getCameraDeviceInterface_V1_x(
Yin-Chia Yeh248ed702017-01-23 17:27:26 -0800332 const hidl_string& cameraDeviceName, getCameraDeviceInterface_V1_x_cb _hidl_cb) {
Andreas Gampe0b171f12017-04-04 20:02:25 -0700333 std::string cameraId, deviceVersion;
334 bool match = matchDeviceName(cameraDeviceName, &deviceVersion, &cameraId);
Yin-Chia Yeh248ed702017-01-23 17:27:26 -0800335 if (!match) {
336 _hidl_cb(Status::ILLEGAL_ARGUMENT, nullptr);
337 return Void();
338 }
339
Yin-Chia Yeh248ed702017-01-23 17:27:26 -0800340 std::string deviceName(cameraDeviceName.c_str());
341 ssize_t index = mCameraDeviceNames.indexOf(std::make_pair(cameraId, deviceName));
342 if (index == NAME_NOT_FOUND) { // Either an illegal name or a device version mismatch
343 Status status = Status::OK;
344 ssize_t idx = mCameraIds.indexOf(cameraId);
345 if (idx == NAME_NOT_FOUND) {
346 ALOGE("%s: cannot find camera %s!", __FUNCTION__, cameraId.c_str());
347 status = Status::ILLEGAL_ARGUMENT;
348 } else { // invalid version
349 ALOGE("%s: camera device %s does not support version %s!",
350 __FUNCTION__, cameraId.c_str(), deviceVersion.c_str());
351 status = Status::OPERATION_NOT_SUPPORTED;
352 }
353 _hidl_cb(status, nullptr);
354 return Void();
355 }
356
357 if (mCameraStatusMap.count(cameraId) == 0 ||
358 mCameraStatusMap[cameraId] != CAMERA_DEVICE_STATUS_PRESENT) {
359 _hidl_cb(Status::ILLEGAL_ARGUMENT, nullptr);
360 return Void();
361 }
362
363 sp<android::hardware::camera::device::V1_0::implementation::CameraDevice> device =
364 new android::hardware::camera::device::V1_0::implementation::CameraDevice(
365 mModule, cameraId, mCameraDeviceNames);
366
367 if (device == nullptr) {
368 ALOGE("%s: cannot allocate camera device for id %s", __FUNCTION__, cameraId.c_str());
369 _hidl_cb(Status::INTERNAL_ERROR, nullptr);
370 return Void();
371 }
372
373 if (device->isInitFailed()) {
374 ALOGE("%s: camera device %s init failed!", __FUNCTION__, cameraId.c_str());
375 device = nullptr;
376 _hidl_cb(Status::INTERNAL_ERROR, nullptr);
377 return Void();
378 }
379
380 _hidl_cb (Status::OK, device);
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -0800381 return Void();
382}
383
Yin-Chia Yeh9c6dbd52016-12-22 14:55:02 -0800384Return<void> CameraProvider::getCameraDeviceInterface_V3_x(
385 const hidl_string& cameraDeviceName, getCameraDeviceInterface_V3_x_cb _hidl_cb) {
Andreas Gampe0b171f12017-04-04 20:02:25 -0700386 std::string cameraId, deviceVersion;
387 bool match = matchDeviceName(cameraDeviceName, &deviceVersion, &cameraId);
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -0800388 if (!match) {
389 _hidl_cb(Status::ILLEGAL_ARGUMENT, nullptr);
390 return Void();
391 }
392
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -0800393 std::string deviceName(cameraDeviceName.c_str());
394 ssize_t index = mCameraDeviceNames.indexOf(std::make_pair(cameraId, deviceName));
395 if (index == NAME_NOT_FOUND) { // Either an illegal name or a device version mismatch
396 Status status = Status::OK;
397 ssize_t idx = mCameraIds.indexOf(cameraId);
398 if (idx == NAME_NOT_FOUND) {
Yin-Chia Yeh9c6dbd52016-12-22 14:55:02 -0800399 ALOGE("%s: cannot find camera %s!", __FUNCTION__, cameraId.c_str());
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -0800400 status = Status::ILLEGAL_ARGUMENT;
401 } else { // invalid version
Yin-Chia Yeh9c6dbd52016-12-22 14:55:02 -0800402 ALOGE("%s: camera device %s does not support version %s!",
403 __FUNCTION__, cameraId.c_str(), deviceVersion.c_str());
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -0800404 status = Status::OPERATION_NOT_SUPPORTED;
405 }
406 _hidl_cb(status, nullptr);
407 return Void();
408 }
409
410 if (mCameraStatusMap.count(cameraId) == 0 ||
411 mCameraStatusMap[cameraId] != CAMERA_DEVICE_STATUS_PRESENT) {
412 _hidl_cb(Status::ILLEGAL_ARGUMENT, nullptr);
413 return Void();
414 }
415
416 // TODO: we also need to keep a wp list of all generated devices to notify
417 // devices of device present status change, but then each device might
418 // need a sp<provider> to keep provider alive until all device closed?
419 // Problem: do we have external camera products to test this?
420 sp<android::hardware::camera::device::V3_2::implementation::CameraDevice> device =
421 new android::hardware::camera::device::V3_2::implementation::CameraDevice(
422 mModule, cameraId, mCameraDeviceNames);
423
424 if (device == nullptr) {
Yin-Chia Yeh9c6dbd52016-12-22 14:55:02 -0800425 ALOGE("%s: cannot allocate camera device for id %s", __FUNCTION__, cameraId.c_str());
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -0800426 _hidl_cb(Status::INTERNAL_ERROR, nullptr);
427 return Void();
428 }
429
430 if (device->isInitFailed()) {
Yin-Chia Yeh9c6dbd52016-12-22 14:55:02 -0800431 ALOGE("%s: camera device %s init failed!", __FUNCTION__, cameraId.c_str());
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -0800432 device = nullptr;
433 _hidl_cb(Status::INTERNAL_ERROR, nullptr);
434 return Void();
435 }
436
437 _hidl_cb (Status::OK, device);
438 return Void();
439}
440
441ICameraProvider* HIDL_FETCH_ICameraProvider(const char* name) {
442 if (strcmp(name, kLegacyProviderName) != 0) {
443 return nullptr;
444 }
445 CameraProvider* provider = new CameraProvider();
446 if (provider == nullptr) {
447 ALOGE("%s: cannot allocate camera provider!", __FUNCTION__);
448 return nullptr;
449 }
450 if (provider->isInitFailed()) {
451 ALOGE("%s: camera provider init failed!", __FUNCTION__);
452 delete provider;
453 return nullptr;
454 }
455 return provider;
456}
457
458} // namespace implementation
459} // namespace V2_4
460} // namespace provider
461} // namespace camera
462} // namespace hardware
463} // namespace android