blob: 8701ec1db753887ae74727fc28e61fd63d983853 [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
43} // anonymous namespace
44
45using ::android::hardware::camera::common::V1_0::CameraMetadataType;
46using ::android::hardware::camera::common::V1_0::Status;
47
48/**
49 * static callback forwarding methods from HAL to instance
50 */
51void CameraProvider::sCameraDeviceStatusChange(
52 const struct camera_module_callbacks* callbacks,
53 int camera_id,
54 int new_status) {
Yin-Chia Yeh6dc9b532017-02-09 18:43:35 -080055 CameraProvider* cp = const_cast<CameraProvider*>(
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -080056 static_cast<const CameraProvider*>(callbacks));
57
58 if (cp == nullptr) {
59 ALOGE("%s: callback ops is null", __FUNCTION__);
60 return;
61 }
62
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -080063 Mutex::Autolock _l(cp->mCbLock);
64 char cameraId[kMaxCameraIdLen];
65 snprintf(cameraId, sizeof(cameraId), "%d", camera_id);
66 std::string cameraIdStr(cameraId);
67 cp->mCameraStatusMap[cameraIdStr] = (camera_device_status_t) new_status;
68 if (cp->mCallbacks != nullptr) {
69 CameraDeviceStatus status = (CameraDeviceStatus) new_status;
70 for (auto const& deviceNamePair : cp->mCameraDeviceNames) {
71 if (cameraIdStr.compare(deviceNamePair.first) == 0) {
72 cp->mCallbacks->cameraDeviceStatusChange(
73 deviceNamePair.second, status);
74 }
75 }
76 }
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -080077}
78
79void CameraProvider::sTorchModeStatusChange(
80 const struct camera_module_callbacks* callbacks,
81 const char* camera_id,
82 int new_status) {
Yin-Chia Yeh6dc9b532017-02-09 18:43:35 -080083 CameraProvider* cp = const_cast<CameraProvider*>(
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -080084 static_cast<const CameraProvider*>(callbacks));
85
86 if (cp == nullptr) {
87 ALOGE("%s: callback ops is null", __FUNCTION__);
88 return;
89 }
90
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -080091 Mutex::Autolock _l(cp->mCbLock);
92 if (cp->mCallbacks != nullptr) {
93 std::string cameraIdStr(camera_id);
94 TorchModeStatus status = (TorchModeStatus) new_status;
95 for (auto const& deviceNamePair : cp->mCameraDeviceNames) {
Yin-Chia Yeh9c6dbd52016-12-22 14:55:02 -080096 if (cameraIdStr.compare(deviceNamePair.first) == 0) {
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -080097 cp->mCallbacks->torchModeStatusChange(
98 deviceNamePair.second, status);
99 }
100 }
101 }
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -0800102}
103
104Status CameraProvider::getHidlStatus(int status) {
105 switch (status) {
106 case 0: return Status::OK;
107 case -ENODEV: return Status::INTERNAL_ERROR;
108 case -EINVAL: return Status::ILLEGAL_ARGUMENT;
109 default:
110 ALOGE("%s: unknown HAL status code %d", __FUNCTION__, status);
111 return Status::INTERNAL_ERROR;
112 }
113}
114
115bool CameraProvider::matchDeviceName(const hidl_string& deviceName, std::smatch& sm) {
116 std::string deviceNameStd(deviceName.c_str());
117 return std::regex_match(deviceNameStd, sm, kDeviceNameRE);
118}
119
120std::string CameraProvider::getLegacyCameraId(const hidl_string& deviceName) {
121 std::smatch sm;
122 bool match = matchDeviceName(deviceName, sm);
123 if (!match) {
124 return std::string("");
125 }
126 return sm[2];
127}
128
129int CameraProvider::getCameraDeviceVersion(const hidl_string& deviceName) {
130 std::smatch sm;
131 bool match = matchDeviceName(deviceName, sm);
132 if (!match) {
133 return -1;
134 }
135 if (sm[1].compare(kHAL3_2) == 0) {
Yin-Chia Yeh9c6dbd52016-12-22 14:55:02 -0800136 // maybe switched to 3.4 or define the hidl version enum later
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -0800137 return CAMERA_DEVICE_API_VERSION_3_2;
138 } else if (sm[1].compare(kHAL1_0) == 0) {
139 return CAMERA_DEVICE_API_VERSION_1_0;
140 }
141 return 0;
142}
143
144std::string CameraProvider::getHidlDeviceName(
145 std::string cameraId, int deviceVersion) {
146 // Maybe consider create a version check method and SortedVec to speed up?
147 if (deviceVersion != CAMERA_DEVICE_API_VERSION_1_0 &&
148 deviceVersion != CAMERA_DEVICE_API_VERSION_3_2 &&
149 deviceVersion != CAMERA_DEVICE_API_VERSION_3_3 &&
150 deviceVersion != CAMERA_DEVICE_API_VERSION_3_4 ) {
151 return hidl_string("");
152 }
153 const char* versionStr = (deviceVersion == CAMERA_DEVICE_API_VERSION_1_0) ? kHAL1_0 : kHAL3_2;
154 char deviceName[kMaxCameraDeviceNameLen];
155 snprintf(deviceName, sizeof(deviceName), "device@%s/legacy/%s",
156 versionStr, cameraId.c_str());
157 return deviceName;
158}
159
160CameraProvider::CameraProvider() :
161 camera_module_callbacks_t({sCameraDeviceStatusChange,
162 sTorchModeStatusChange}) {
163 mInitFailed = initialize();
164}
165
166CameraProvider::~CameraProvider() {}
167
168bool CameraProvider::initialize() {
169 camera_module_t *rawModule;
170 int err = hw_get_module(CAMERA_HARDWARE_MODULE_ID,
171 (const hw_module_t **)&rawModule);
172 if (err < 0) {
173 ALOGE("Could not load camera HAL module: %d (%s)", err, strerror(-err));
174 return true;
175 }
176
177 mModule = new CameraModule(rawModule);
178 err = mModule->init();
179 if (err != OK) {
Yin-Chia Yehfca2e742017-01-31 16:00:20 -0800180 ALOGE("Could not initialize camera HAL module: %d (%s)", err, strerror(-err));
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -0800181 mModule.clear();
182 return true;
183 }
184 ALOGI("Loaded \"%s\" camera module", mModule->getModuleName());
185
Shuzhen Wangefb7bfa2017-03-15 18:26:39 -0700186 // Setup vendor tags here so HAL can setup vendor keys in camera characteristics
187 VendorTagDescriptor::clearGlobalVendorTagDescriptor();
188 if (!setUpVendorTags()) {
189 ALOGE("%s: Vendor tag setup failed, will not be available.", __FUNCTION__);
190 }
191
Yin-Chia Yehfca2e742017-01-31 16:00:20 -0800192 // Setup callback now because we are going to try openLegacy next
193 err = mModule->setCallbacks(this);
194 if (err != OK) {
195 ALOGE("Could not set camera module callback: %d (%s)", err, strerror(-err));
196 mModule.clear();
197 return true;
198 }
199
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -0800200 mNumberOfLegacyCameras = mModule->getNumberOfCameras();
201 for (int i = 0; i < mNumberOfLegacyCameras; i++) {
202 char cameraId[kMaxCameraIdLen];
203 snprintf(cameraId, sizeof(cameraId), "%d", i);
204 std::string cameraIdStr(cameraId);
205 mCameraStatusMap[cameraIdStr] = CAMERA_DEVICE_STATUS_PRESENT;
206 mCameraIds.add(cameraIdStr);
207
208 // initialize mCameraDeviceNames and mOpenLegacySupported
209 mOpenLegacySupported[cameraIdStr] = false;
210 int deviceVersion = mModule->getDeviceVersion(i);
211 mCameraDeviceNames.add(
212 std::make_pair(cameraIdStr,
213 getHidlDeviceName(cameraIdStr, deviceVersion)));
214 if (deviceVersion >= CAMERA_DEVICE_API_VERSION_3_2 &&
215 mModule->isOpenLegacyDefined()) {
216 // try open_legacy to see if it actually works
217 struct hw_device_t* halDev = nullptr;
218 int ret = mModule->openLegacy(cameraId, CAMERA_DEVICE_API_VERSION_1_0, &halDev);
219 if (ret == 0) {
220 mOpenLegacySupported[cameraIdStr] = true;
221 halDev->close(halDev);
222 mCameraDeviceNames.add(
223 std::make_pair(cameraIdStr,
224 getHidlDeviceName(cameraIdStr, CAMERA_DEVICE_API_VERSION_1_0)));
225 } else if (ret == -EBUSY || ret == -EUSERS) {
226 // Looks like this provider instance is not initialized during
227 // system startup and there are other camera users already.
228 // Not a good sign but not fatal.
229 ALOGW("%s: open_legacy try failed!", __FUNCTION__);
230 }
231 }
232 }
233
Eino-Ville Talvala0f5eb832017-02-09 19:45:31 -0800234 return false; // mInitFailed
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -0800235}
236
237bool CameraProvider::setUpVendorTags() {
238 ATRACE_CALL();
239 vendor_tag_ops_t vOps = vendor_tag_ops_t();
240
241 // Check if vendor operations have been implemented
242 if (!mModule->isVendorTagDefined()) {
243 ALOGI("%s: No vendor tags defined for this device.", __FUNCTION__);
Eino-Ville Talvala0f5eb832017-02-09 19:45:31 -0800244 return true;
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -0800245 }
246
247 mModule->getVendorTagOps(&vOps);
248
249 // Ensure all vendor operations are present
250 if (vOps.get_tag_count == nullptr || vOps.get_all_tags == nullptr ||
251 vOps.get_section_name == nullptr || vOps.get_tag_name == nullptr ||
252 vOps.get_tag_type == nullptr) {
253 ALOGE("%s: Vendor tag operations not fully defined. Ignoring definitions."
254 , __FUNCTION__);
255 return false;
256 }
257
258 // Read all vendor tag definitions into a descriptor
259 sp<VendorTagDescriptor> desc;
260 status_t res;
261 if ((res = VendorTagDescriptor::createDescriptorFromOps(&vOps, /*out*/desc))
262 != OK) {
263 ALOGE("%s: Could not generate descriptor from vendor tag operations,"
264 "received error %s (%d). Camera clients will not be able to use"
265 "vendor tags", __FUNCTION__, strerror(res), res);
266 return false;
267 }
268
269 // Set the global descriptor to use with camera metadata
270 VendorTagDescriptor::setAsGlobalVendorTagDescriptor(desc);
271 const SortedVector<String8>* sectionNames = desc->getAllSectionNames();
272 size_t numSections = sectionNames->size();
273 std::vector<std::vector<VendorTag>> tagsBySection(numSections);
274 int tagCount = desc->getTagCount();
275 std::vector<uint32_t> tags(tagCount);
276 desc->getTagArray(tags.data());
277 for (int i = 0; i < tagCount; i++) {
278 VendorTag vt;
279 vt.tagId = tags[i];
280 vt.tagName = desc->getTagName(tags[i]);
281 vt.tagType = (CameraMetadataType) desc->getTagType(tags[i]);
282 ssize_t sectionIdx = desc->getSectionIndex(tags[i]);
283 tagsBySection[sectionIdx].push_back(vt);
284 }
285 mVendorTagSections.resize(numSections);
286 for (size_t s = 0; s < numSections; s++) {
287 mVendorTagSections[s].sectionName = (*sectionNames)[s].string();
288 mVendorTagSections[s].tags = tagsBySection[s];
289 }
290 return true;
291}
292
293// Methods from ::android::hardware::camera::provider::V2_4::ICameraProvider follow.
294Return<Status> CameraProvider::setCallback(const sp<ICameraProviderCallback>& callback) {
Yin-Chia Yehfca2e742017-01-31 16:00:20 -0800295 Mutex::Autolock _l(mCbLock);
296 mCallbacks = callback;
297 return Status::OK;
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -0800298}
299
300Return<void> CameraProvider::getVendorTags(getVendorTags_cb _hidl_cb) {
301 _hidl_cb(Status::OK, mVendorTagSections);
302 return Void();
303}
304
305Return<void> CameraProvider::getCameraIdList(getCameraIdList_cb _hidl_cb) {
306 std::vector<hidl_string> deviceNameList;
307 for (auto const& deviceNamePair : mCameraDeviceNames) {
308 if (mCameraStatusMap[deviceNamePair.first] == CAMERA_DEVICE_STATUS_PRESENT) {
309 deviceNameList.push_back(deviceNamePair.second);
310 }
311 }
312 hidl_vec<hidl_string> hidlDeviceNameList(deviceNameList);
Yin-Chia Yeh9c6dbd52016-12-22 14:55:02 -0800313 _hidl_cb(Status::OK, hidlDeviceNameList);
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -0800314 return Void();
315}
316
317Return<void> CameraProvider::isSetTorchModeSupported(isSetTorchModeSupported_cb _hidl_cb) {
318 bool support = mModule->isSetTorchModeSupported();
319 _hidl_cb (Status::OK, support);
320 return Void();
321}
322
Yin-Chia Yeh9c6dbd52016-12-22 14:55:02 -0800323Return<void> CameraProvider::getCameraDeviceInterface_V1_x(
Yin-Chia Yeh248ed702017-01-23 17:27:26 -0800324 const hidl_string& cameraDeviceName, getCameraDeviceInterface_V1_x_cb _hidl_cb) {
325 std::smatch sm;
326 bool match = matchDeviceName(cameraDeviceName, sm);
327 if (!match) {
328 _hidl_cb(Status::ILLEGAL_ARGUMENT, nullptr);
329 return Void();
330 }
331
332 std::string cameraId = sm[2];
333 std::string deviceVersion = sm[1];
334 std::string deviceName(cameraDeviceName.c_str());
335 ssize_t index = mCameraDeviceNames.indexOf(std::make_pair(cameraId, deviceName));
336 if (index == NAME_NOT_FOUND) { // Either an illegal name or a device version mismatch
337 Status status = Status::OK;
338 ssize_t idx = mCameraIds.indexOf(cameraId);
339 if (idx == NAME_NOT_FOUND) {
340 ALOGE("%s: cannot find camera %s!", __FUNCTION__, cameraId.c_str());
341 status = Status::ILLEGAL_ARGUMENT;
342 } else { // invalid version
343 ALOGE("%s: camera device %s does not support version %s!",
344 __FUNCTION__, cameraId.c_str(), deviceVersion.c_str());
345 status = Status::OPERATION_NOT_SUPPORTED;
346 }
347 _hidl_cb(status, nullptr);
348 return Void();
349 }
350
351 if (mCameraStatusMap.count(cameraId) == 0 ||
352 mCameraStatusMap[cameraId] != CAMERA_DEVICE_STATUS_PRESENT) {
353 _hidl_cb(Status::ILLEGAL_ARGUMENT, nullptr);
354 return Void();
355 }
356
357 sp<android::hardware::camera::device::V1_0::implementation::CameraDevice> device =
358 new android::hardware::camera::device::V1_0::implementation::CameraDevice(
359 mModule, cameraId, mCameraDeviceNames);
360
361 if (device == nullptr) {
362 ALOGE("%s: cannot allocate camera device for id %s", __FUNCTION__, cameraId.c_str());
363 _hidl_cb(Status::INTERNAL_ERROR, nullptr);
364 return Void();
365 }
366
367 if (device->isInitFailed()) {
368 ALOGE("%s: camera device %s init failed!", __FUNCTION__, cameraId.c_str());
369 device = nullptr;
370 _hidl_cb(Status::INTERNAL_ERROR, nullptr);
371 return Void();
372 }
373
374 _hidl_cb (Status::OK, device);
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -0800375 return Void();
376}
377
Yin-Chia Yeh9c6dbd52016-12-22 14:55:02 -0800378Return<void> CameraProvider::getCameraDeviceInterface_V3_x(
379 const hidl_string& cameraDeviceName, getCameraDeviceInterface_V3_x_cb _hidl_cb) {
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -0800380 std::smatch sm;
381 bool match = matchDeviceName(cameraDeviceName, sm);
382 if (!match) {
383 _hidl_cb(Status::ILLEGAL_ARGUMENT, nullptr);
384 return Void();
385 }
386
387 std::string cameraId = sm[2];
Yin-Chia Yeh9c6dbd52016-12-22 14:55:02 -0800388 std::string deviceVersion = sm[1];
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -0800389 std::string deviceName(cameraDeviceName.c_str());
390 ssize_t index = mCameraDeviceNames.indexOf(std::make_pair(cameraId, deviceName));
391 if (index == NAME_NOT_FOUND) { // Either an illegal name or a device version mismatch
392 Status status = Status::OK;
393 ssize_t idx = mCameraIds.indexOf(cameraId);
394 if (idx == NAME_NOT_FOUND) {
Yin-Chia Yeh9c6dbd52016-12-22 14:55:02 -0800395 ALOGE("%s: cannot find camera %s!", __FUNCTION__, cameraId.c_str());
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -0800396 status = Status::ILLEGAL_ARGUMENT;
397 } else { // invalid version
Yin-Chia Yeh9c6dbd52016-12-22 14:55:02 -0800398 ALOGE("%s: camera device %s does not support version %s!",
399 __FUNCTION__, cameraId.c_str(), deviceVersion.c_str());
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -0800400 status = Status::OPERATION_NOT_SUPPORTED;
401 }
402 _hidl_cb(status, nullptr);
403 return Void();
404 }
405
406 if (mCameraStatusMap.count(cameraId) == 0 ||
407 mCameraStatusMap[cameraId] != CAMERA_DEVICE_STATUS_PRESENT) {
408 _hidl_cb(Status::ILLEGAL_ARGUMENT, nullptr);
409 return Void();
410 }
411
412 // TODO: we also need to keep a wp list of all generated devices to notify
413 // devices of device present status change, but then each device might
414 // need a sp<provider> to keep provider alive until all device closed?
415 // Problem: do we have external camera products to test this?
416 sp<android::hardware::camera::device::V3_2::implementation::CameraDevice> device =
417 new android::hardware::camera::device::V3_2::implementation::CameraDevice(
418 mModule, cameraId, mCameraDeviceNames);
419
420 if (device == nullptr) {
Yin-Chia Yeh9c6dbd52016-12-22 14:55:02 -0800421 ALOGE("%s: cannot allocate camera device for id %s", __FUNCTION__, cameraId.c_str());
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -0800422 _hidl_cb(Status::INTERNAL_ERROR, nullptr);
423 return Void();
424 }
425
426 if (device->isInitFailed()) {
Yin-Chia Yeh9c6dbd52016-12-22 14:55:02 -0800427 ALOGE("%s: camera device %s init failed!", __FUNCTION__, cameraId.c_str());
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -0800428 device = nullptr;
429 _hidl_cb(Status::INTERNAL_ERROR, nullptr);
430 return Void();
431 }
432
433 _hidl_cb (Status::OK, device);
434 return Void();
435}
436
437ICameraProvider* HIDL_FETCH_ICameraProvider(const char* name) {
438 if (strcmp(name, kLegacyProviderName) != 0) {
439 return nullptr;
440 }
441 CameraProvider* provider = new CameraProvider();
442 if (provider == nullptr) {
443 ALOGE("%s: cannot allocate camera provider!", __FUNCTION__);
444 return nullptr;
445 }
446 if (provider->isInitFailed()) {
447 ALOGE("%s: camera provider init failed!", __FUNCTION__);
448 delete provider;
449 return nullptr;
450 }
451 return provider;
452}
453
454} // namespace implementation
455} // namespace V2_4
456} // namespace provider
457} // namespace camera
458} // namespace hardware
459} // namespace android