blob: ad9f0b8621be02d21df32e7f80efce5bc7b0eb46 [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
Yin-Chia Yehfca2e742017-01-31 16:00:20 -0800186 // Setup callback now because we are going to try openLegacy next
187 err = mModule->setCallbacks(this);
188 if (err != OK) {
189 ALOGE("Could not set camera module callback: %d (%s)", err, strerror(-err));
190 mModule.clear();
191 return true;
192 }
193
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -0800194 mNumberOfLegacyCameras = mModule->getNumberOfCameras();
195 for (int i = 0; i < mNumberOfLegacyCameras; i++) {
196 char cameraId[kMaxCameraIdLen];
197 snprintf(cameraId, sizeof(cameraId), "%d", i);
198 std::string cameraIdStr(cameraId);
199 mCameraStatusMap[cameraIdStr] = CAMERA_DEVICE_STATUS_PRESENT;
200 mCameraIds.add(cameraIdStr);
201
202 // initialize mCameraDeviceNames and mOpenLegacySupported
203 mOpenLegacySupported[cameraIdStr] = false;
204 int deviceVersion = mModule->getDeviceVersion(i);
205 mCameraDeviceNames.add(
206 std::make_pair(cameraIdStr,
207 getHidlDeviceName(cameraIdStr, deviceVersion)));
208 if (deviceVersion >= CAMERA_DEVICE_API_VERSION_3_2 &&
209 mModule->isOpenLegacyDefined()) {
210 // try open_legacy to see if it actually works
211 struct hw_device_t* halDev = nullptr;
212 int ret = mModule->openLegacy(cameraId, CAMERA_DEVICE_API_VERSION_1_0, &halDev);
213 if (ret == 0) {
214 mOpenLegacySupported[cameraIdStr] = true;
215 halDev->close(halDev);
216 mCameraDeviceNames.add(
217 std::make_pair(cameraIdStr,
218 getHidlDeviceName(cameraIdStr, CAMERA_DEVICE_API_VERSION_1_0)));
219 } else if (ret == -EBUSY || ret == -EUSERS) {
220 // Looks like this provider instance is not initialized during
221 // system startup and there are other camera users already.
222 // Not a good sign but not fatal.
223 ALOGW("%s: open_legacy try failed!", __FUNCTION__);
224 }
225 }
226 }
227
228 // Setup vendor tags here so HAL can setup vendor keys in camera characteristics
229 VendorTagDescriptor::clearGlobalVendorTagDescriptor();
Eino-Ville Talvala0f5eb832017-02-09 19:45:31 -0800230 if (!setUpVendorTags()) {
231 ALOGE("%s: Vendor tag setup failed, will not be available.", __FUNCTION__);
232 }
233 return false; // mInitFailed
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -0800234}
235
236bool CameraProvider::setUpVendorTags() {
237 ATRACE_CALL();
238 vendor_tag_ops_t vOps = vendor_tag_ops_t();
239
240 // Check if vendor operations have been implemented
241 if (!mModule->isVendorTagDefined()) {
242 ALOGI("%s: No vendor tags defined for this device.", __FUNCTION__);
Eino-Ville Talvala0f5eb832017-02-09 19:45:31 -0800243 return true;
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -0800244 }
245
246 mModule->getVendorTagOps(&vOps);
247
248 // Ensure all vendor operations are present
249 if (vOps.get_tag_count == nullptr || vOps.get_all_tags == nullptr ||
250 vOps.get_section_name == nullptr || vOps.get_tag_name == nullptr ||
251 vOps.get_tag_type == nullptr) {
252 ALOGE("%s: Vendor tag operations not fully defined. Ignoring definitions."
253 , __FUNCTION__);
254 return false;
255 }
256
257 // Read all vendor tag definitions into a descriptor
258 sp<VendorTagDescriptor> desc;
259 status_t res;
260 if ((res = VendorTagDescriptor::createDescriptorFromOps(&vOps, /*out*/desc))
261 != OK) {
262 ALOGE("%s: Could not generate descriptor from vendor tag operations,"
263 "received error %s (%d). Camera clients will not be able to use"
264 "vendor tags", __FUNCTION__, strerror(res), res);
265 return false;
266 }
267
268 // Set the global descriptor to use with camera metadata
269 VendorTagDescriptor::setAsGlobalVendorTagDescriptor(desc);
270 const SortedVector<String8>* sectionNames = desc->getAllSectionNames();
271 size_t numSections = sectionNames->size();
272 std::vector<std::vector<VendorTag>> tagsBySection(numSections);
273 int tagCount = desc->getTagCount();
274 std::vector<uint32_t> tags(tagCount);
275 desc->getTagArray(tags.data());
276 for (int i = 0; i < tagCount; i++) {
277 VendorTag vt;
278 vt.tagId = tags[i];
279 vt.tagName = desc->getTagName(tags[i]);
280 vt.tagType = (CameraMetadataType) desc->getTagType(tags[i]);
281 ssize_t sectionIdx = desc->getSectionIndex(tags[i]);
282 tagsBySection[sectionIdx].push_back(vt);
283 }
284 mVendorTagSections.resize(numSections);
285 for (size_t s = 0; s < numSections; s++) {
286 mVendorTagSections[s].sectionName = (*sectionNames)[s].string();
287 mVendorTagSections[s].tags = tagsBySection[s];
288 }
289 return true;
290}
291
292// Methods from ::android::hardware::camera::provider::V2_4::ICameraProvider follow.
293Return<Status> CameraProvider::setCallback(const sp<ICameraProviderCallback>& callback) {
Yin-Chia Yehfca2e742017-01-31 16:00:20 -0800294 Mutex::Autolock _l(mCbLock);
295 mCallbacks = callback;
296 return Status::OK;
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -0800297}
298
299Return<void> CameraProvider::getVendorTags(getVendorTags_cb _hidl_cb) {
300 _hidl_cb(Status::OK, mVendorTagSections);
301 return Void();
302}
303
304Return<void> CameraProvider::getCameraIdList(getCameraIdList_cb _hidl_cb) {
305 std::vector<hidl_string> deviceNameList;
306 for (auto const& deviceNamePair : mCameraDeviceNames) {
307 if (mCameraStatusMap[deviceNamePair.first] == CAMERA_DEVICE_STATUS_PRESENT) {
308 deviceNameList.push_back(deviceNamePair.second);
309 }
310 }
311 hidl_vec<hidl_string> hidlDeviceNameList(deviceNameList);
Yin-Chia Yeh9c6dbd52016-12-22 14:55:02 -0800312 _hidl_cb(Status::OK, hidlDeviceNameList);
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -0800313 return Void();
314}
315
316Return<void> CameraProvider::isSetTorchModeSupported(isSetTorchModeSupported_cb _hidl_cb) {
317 bool support = mModule->isSetTorchModeSupported();
318 _hidl_cb (Status::OK, support);
319 return Void();
320}
321
Yin-Chia Yeh9c6dbd52016-12-22 14:55:02 -0800322Return<void> CameraProvider::getCameraDeviceInterface_V1_x(
Yin-Chia Yeh248ed702017-01-23 17:27:26 -0800323 const hidl_string& cameraDeviceName, getCameraDeviceInterface_V1_x_cb _hidl_cb) {
324 std::smatch sm;
325 bool match = matchDeviceName(cameraDeviceName, sm);
326 if (!match) {
327 _hidl_cb(Status::ILLEGAL_ARGUMENT, nullptr);
328 return Void();
329 }
330
331 std::string cameraId = sm[2];
332 std::string deviceVersion = sm[1];
333 std::string deviceName(cameraDeviceName.c_str());
334 ssize_t index = mCameraDeviceNames.indexOf(std::make_pair(cameraId, deviceName));
335 if (index == NAME_NOT_FOUND) { // Either an illegal name or a device version mismatch
336 Status status = Status::OK;
337 ssize_t idx = mCameraIds.indexOf(cameraId);
338 if (idx == NAME_NOT_FOUND) {
339 ALOGE("%s: cannot find camera %s!", __FUNCTION__, cameraId.c_str());
340 status = Status::ILLEGAL_ARGUMENT;
341 } else { // invalid version
342 ALOGE("%s: camera device %s does not support version %s!",
343 __FUNCTION__, cameraId.c_str(), deviceVersion.c_str());
344 status = Status::OPERATION_NOT_SUPPORTED;
345 }
346 _hidl_cb(status, nullptr);
347 return Void();
348 }
349
350 if (mCameraStatusMap.count(cameraId) == 0 ||
351 mCameraStatusMap[cameraId] != CAMERA_DEVICE_STATUS_PRESENT) {
352 _hidl_cb(Status::ILLEGAL_ARGUMENT, nullptr);
353 return Void();
354 }
355
356 sp<android::hardware::camera::device::V1_0::implementation::CameraDevice> device =
357 new android::hardware::camera::device::V1_0::implementation::CameraDevice(
358 mModule, cameraId, mCameraDeviceNames);
359
360 if (device == nullptr) {
361 ALOGE("%s: cannot allocate camera device for id %s", __FUNCTION__, cameraId.c_str());
362 _hidl_cb(Status::INTERNAL_ERROR, nullptr);
363 return Void();
364 }
365
366 if (device->isInitFailed()) {
367 ALOGE("%s: camera device %s init failed!", __FUNCTION__, cameraId.c_str());
368 device = nullptr;
369 _hidl_cb(Status::INTERNAL_ERROR, nullptr);
370 return Void();
371 }
372
373 _hidl_cb (Status::OK, device);
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -0800374 return Void();
375}
376
Yin-Chia Yeh9c6dbd52016-12-22 14:55:02 -0800377Return<void> CameraProvider::getCameraDeviceInterface_V3_x(
378 const hidl_string& cameraDeviceName, getCameraDeviceInterface_V3_x_cb _hidl_cb) {
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -0800379 std::smatch sm;
380 bool match = matchDeviceName(cameraDeviceName, sm);
381 if (!match) {
382 _hidl_cb(Status::ILLEGAL_ARGUMENT, nullptr);
383 return Void();
384 }
385
386 std::string cameraId = sm[2];
Yin-Chia Yeh9c6dbd52016-12-22 14:55:02 -0800387 std::string deviceVersion = sm[1];
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -0800388 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) {
Yin-Chia Yeh9c6dbd52016-12-22 14:55:02 -0800394 ALOGE("%s: cannot find camera %s!", __FUNCTION__, cameraId.c_str());
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -0800395 status = Status::ILLEGAL_ARGUMENT;
396 } else { // invalid version
Yin-Chia Yeh9c6dbd52016-12-22 14:55:02 -0800397 ALOGE("%s: camera device %s does not support version %s!",
398 __FUNCTION__, cameraId.c_str(), deviceVersion.c_str());
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -0800399 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 // TODO: we also need to keep a wp list of all generated devices to notify
412 // devices of device present status change, but then each device might
413 // need a sp<provider> to keep provider alive until all device closed?
414 // Problem: do we have external camera products to test this?
415 sp<android::hardware::camera::device::V3_2::implementation::CameraDevice> device =
416 new android::hardware::camera::device::V3_2::implementation::CameraDevice(
417 mModule, cameraId, mCameraDeviceNames);
418
419 if (device == nullptr) {
Yin-Chia Yeh9c6dbd52016-12-22 14:55:02 -0800420 ALOGE("%s: cannot allocate camera device for id %s", __FUNCTION__, cameraId.c_str());
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -0800421 _hidl_cb(Status::INTERNAL_ERROR, nullptr);
422 return Void();
423 }
424
425 if (device->isInitFailed()) {
Yin-Chia Yeh9c6dbd52016-12-22 14:55:02 -0800426 ALOGE("%s: camera device %s init failed!", __FUNCTION__, cameraId.c_str());
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -0800427 device = nullptr;
428 _hidl_cb(Status::INTERNAL_ERROR, nullptr);
429 return Void();
430 }
431
432 _hidl_cb (Status::OK, device);
433 return Void();
434}
435
436ICameraProvider* HIDL_FETCH_ICameraProvider(const char* name) {
437 if (strcmp(name, kLegacyProviderName) != 0) {
438 return nullptr;
439 }
440 CameraProvider* provider = new CameraProvider();
441 if (provider == nullptr) {
442 ALOGE("%s: cannot allocate camera provider!", __FUNCTION__);
443 return nullptr;
444 }
445 if (provider->isInitFailed()) {
446 ALOGE("%s: camera provider init failed!", __FUNCTION__);
447 delete provider;
448 return nullptr;
449 }
450 return provider;
451}
452
453} // namespace implementation
454} // namespace V2_4
455} // namespace provider
456} // namespace camera
457} // namespace hardware
458} // namespace android