blob: f1a66a815fbf93f7aa7c9f0fdbbb46a0fc7f5770 [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"
21#include "CameraDevice.h"
22#include <string.h>
23#include <utils/Trace.h>
24
25
26namespace android {
27namespace hardware {
28namespace camera {
29namespace provider {
30namespace V2_4 {
31namespace implementation {
32
33namespace {
34const char *kLegacyProviderName = "legacy/0";
35// "device@<version>/legacy/<id>"
36const std::regex kDeviceNameRE("device@([0-9]+\\.[0-9]+)/legacy/(.+)");
37const char *kHAL3_2 = "3.2";
38const char *kHAL1_0 = "1.0";
39const int kMaxCameraDeviceNameLen = 128;
40const int kMaxCameraIdLen = 16;
41
42} // anonymous namespace
43
44using ::android::hardware::camera::common::V1_0::CameraMetadataType;
45using ::android::hardware::camera::common::V1_0::Status;
46
47/**
48 * static callback forwarding methods from HAL to instance
49 */
50void CameraProvider::sCameraDeviceStatusChange(
51 const struct camera_module_callbacks* callbacks,
52 int camera_id,
53 int new_status) {
54 ALOGI("%s++", __FUNCTION__);
55 sp<CameraProvider> cp = const_cast<CameraProvider*>(
56 static_cast<const CameraProvider*>(callbacks));
57
58 if (cp == nullptr) {
59 ALOGE("%s: callback ops is null", __FUNCTION__);
60 return;
61 }
62
63 ALOGI("%s resolved provider %p", __FUNCTION__, cp.get());
64
65 Mutex::Autolock _l(cp->mCbLock);
66 char cameraId[kMaxCameraIdLen];
67 snprintf(cameraId, sizeof(cameraId), "%d", camera_id);
68 std::string cameraIdStr(cameraId);
69 cp->mCameraStatusMap[cameraIdStr] = (camera_device_status_t) new_status;
70 if (cp->mCallbacks != nullptr) {
71 CameraDeviceStatus status = (CameraDeviceStatus) new_status;
72 for (auto const& deviceNamePair : cp->mCameraDeviceNames) {
73 if (cameraIdStr.compare(deviceNamePair.first) == 0) {
74 cp->mCallbacks->cameraDeviceStatusChange(
75 deviceNamePair.second, status);
76 }
77 }
78 }
79 ALOGI("%s--", __FUNCTION__);
80}
81
82void CameraProvider::sTorchModeStatusChange(
83 const struct camera_module_callbacks* callbacks,
84 const char* camera_id,
85 int new_status) {
86 ALOGI("%s++", __FUNCTION__);
87 sp<CameraProvider> cp = const_cast<CameraProvider*>(
88 static_cast<const CameraProvider*>(callbacks));
89
90 if (cp == nullptr) {
91 ALOGE("%s: callback ops is null", __FUNCTION__);
92 return;
93 }
94
95 ALOGI("%s resolved provider %p", __FUNCTION__, cp.get());
96
97 Mutex::Autolock _l(cp->mCbLock);
98 if (cp->mCallbacks != nullptr) {
99 std::string cameraIdStr(camera_id);
100 TorchModeStatus status = (TorchModeStatus) new_status;
101 for (auto const& deviceNamePair : cp->mCameraDeviceNames) {
Yin-Chia Yeh9c6dbd52016-12-22 14:55:02 -0800102 if (cameraIdStr.compare(deviceNamePair.first) == 0) {
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -0800103 cp->mCallbacks->torchModeStatusChange(
104 deviceNamePair.second, status);
105 }
106 }
107 }
108 ALOGI("%s--", __FUNCTION__);
109}
110
111Status CameraProvider::getHidlStatus(int status) {
112 switch (status) {
113 case 0: return Status::OK;
114 case -ENODEV: return Status::INTERNAL_ERROR;
115 case -EINVAL: return Status::ILLEGAL_ARGUMENT;
116 default:
117 ALOGE("%s: unknown HAL status code %d", __FUNCTION__, status);
118 return Status::INTERNAL_ERROR;
119 }
120}
121
122bool CameraProvider::matchDeviceName(const hidl_string& deviceName, std::smatch& sm) {
123 std::string deviceNameStd(deviceName.c_str());
124 return std::regex_match(deviceNameStd, sm, kDeviceNameRE);
125}
126
127std::string CameraProvider::getLegacyCameraId(const hidl_string& deviceName) {
128 std::smatch sm;
129 bool match = matchDeviceName(deviceName, sm);
130 if (!match) {
131 return std::string("");
132 }
133 return sm[2];
134}
135
136int CameraProvider::getCameraDeviceVersion(const hidl_string& deviceName) {
137 std::smatch sm;
138 bool match = matchDeviceName(deviceName, sm);
139 if (!match) {
140 return -1;
141 }
142 if (sm[1].compare(kHAL3_2) == 0) {
Yin-Chia Yeh9c6dbd52016-12-22 14:55:02 -0800143 // maybe switched to 3.4 or define the hidl version enum later
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -0800144 return CAMERA_DEVICE_API_VERSION_3_2;
145 } else if (sm[1].compare(kHAL1_0) == 0) {
146 return CAMERA_DEVICE_API_VERSION_1_0;
147 }
148 return 0;
149}
150
151std::string CameraProvider::getHidlDeviceName(
152 std::string cameraId, int deviceVersion) {
153 // Maybe consider create a version check method and SortedVec to speed up?
154 if (deviceVersion != CAMERA_DEVICE_API_VERSION_1_0 &&
155 deviceVersion != CAMERA_DEVICE_API_VERSION_3_2 &&
156 deviceVersion != CAMERA_DEVICE_API_VERSION_3_3 &&
157 deviceVersion != CAMERA_DEVICE_API_VERSION_3_4 ) {
158 return hidl_string("");
159 }
160 const char* versionStr = (deviceVersion == CAMERA_DEVICE_API_VERSION_1_0) ? kHAL1_0 : kHAL3_2;
161 char deviceName[kMaxCameraDeviceNameLen];
162 snprintf(deviceName, sizeof(deviceName), "device@%s/legacy/%s",
163 versionStr, cameraId.c_str());
164 return deviceName;
165}
166
167CameraProvider::CameraProvider() :
168 camera_module_callbacks_t({sCameraDeviceStatusChange,
169 sTorchModeStatusChange}) {
170 mInitFailed = initialize();
171}
172
173CameraProvider::~CameraProvider() {}
174
175bool CameraProvider::initialize() {
176 camera_module_t *rawModule;
177 int err = hw_get_module(CAMERA_HARDWARE_MODULE_ID,
178 (const hw_module_t **)&rawModule);
179 if (err < 0) {
180 ALOGE("Could not load camera HAL module: %d (%s)", err, strerror(-err));
181 return true;
182 }
183
184 mModule = new CameraModule(rawModule);
185 err = mModule->init();
186 if (err != OK) {
Yin-Chia Yehfca2e742017-01-31 16:00:20 -0800187 ALOGE("Could not initialize camera HAL module: %d (%s)", err, strerror(-err));
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -0800188 mModule.clear();
189 return true;
190 }
191 ALOGI("Loaded \"%s\" camera module", mModule->getModuleName());
192
Yin-Chia Yehfca2e742017-01-31 16:00:20 -0800193 // Setup callback now because we are going to try openLegacy next
194 err = mModule->setCallbacks(this);
195 if (err != OK) {
196 ALOGE("Could not set camera module callback: %d (%s)", err, strerror(-err));
197 mModule.clear();
198 return true;
199 }
200
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -0800201 mNumberOfLegacyCameras = mModule->getNumberOfCameras();
202 for (int i = 0; i < mNumberOfLegacyCameras; i++) {
203 char cameraId[kMaxCameraIdLen];
204 snprintf(cameraId, sizeof(cameraId), "%d", i);
205 std::string cameraIdStr(cameraId);
206 mCameraStatusMap[cameraIdStr] = CAMERA_DEVICE_STATUS_PRESENT;
207 mCameraIds.add(cameraIdStr);
208
209 // initialize mCameraDeviceNames and mOpenLegacySupported
210 mOpenLegacySupported[cameraIdStr] = false;
211 int deviceVersion = mModule->getDeviceVersion(i);
212 mCameraDeviceNames.add(
213 std::make_pair(cameraIdStr,
214 getHidlDeviceName(cameraIdStr, deviceVersion)));
215 if (deviceVersion >= CAMERA_DEVICE_API_VERSION_3_2 &&
216 mModule->isOpenLegacyDefined()) {
217 // try open_legacy to see if it actually works
218 struct hw_device_t* halDev = nullptr;
219 int ret = mModule->openLegacy(cameraId, CAMERA_DEVICE_API_VERSION_1_0, &halDev);
220 if (ret == 0) {
221 mOpenLegacySupported[cameraIdStr] = true;
222 halDev->close(halDev);
223 mCameraDeviceNames.add(
224 std::make_pair(cameraIdStr,
225 getHidlDeviceName(cameraIdStr, CAMERA_DEVICE_API_VERSION_1_0)));
226 } else if (ret == -EBUSY || ret == -EUSERS) {
227 // Looks like this provider instance is not initialized during
228 // system startup and there are other camera users already.
229 // Not a good sign but not fatal.
230 ALOGW("%s: open_legacy try failed!", __FUNCTION__);
231 }
232 }
233 }
234
235 // Setup vendor tags here so HAL can setup vendor keys in camera characteristics
236 VendorTagDescriptor::clearGlobalVendorTagDescriptor();
Yin-Chia Yeh9c6dbd52016-12-22 14:55:02 -0800237 bool setupSucceed = setUpVendorTags();
238 return !setupSucceed; // return flag here is mInitFailed
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -0800239}
240
241bool CameraProvider::setUpVendorTags() {
242 ATRACE_CALL();
243 vendor_tag_ops_t vOps = vendor_tag_ops_t();
244
245 // Check if vendor operations have been implemented
246 if (!mModule->isVendorTagDefined()) {
247 ALOGI("%s: No vendor tags defined for this device.", __FUNCTION__);
248 return false;
249 }
250
251 mModule->getVendorTagOps(&vOps);
252
253 // Ensure all vendor operations are present
254 if (vOps.get_tag_count == nullptr || vOps.get_all_tags == nullptr ||
255 vOps.get_section_name == nullptr || vOps.get_tag_name == nullptr ||
256 vOps.get_tag_type == nullptr) {
257 ALOGE("%s: Vendor tag operations not fully defined. Ignoring definitions."
258 , __FUNCTION__);
259 return false;
260 }
261
262 // Read all vendor tag definitions into a descriptor
263 sp<VendorTagDescriptor> desc;
264 status_t res;
265 if ((res = VendorTagDescriptor::createDescriptorFromOps(&vOps, /*out*/desc))
266 != OK) {
267 ALOGE("%s: Could not generate descriptor from vendor tag operations,"
268 "received error %s (%d). Camera clients will not be able to use"
269 "vendor tags", __FUNCTION__, strerror(res), res);
270 return false;
271 }
272
273 // Set the global descriptor to use with camera metadata
274 VendorTagDescriptor::setAsGlobalVendorTagDescriptor(desc);
275 const SortedVector<String8>* sectionNames = desc->getAllSectionNames();
276 size_t numSections = sectionNames->size();
277 std::vector<std::vector<VendorTag>> tagsBySection(numSections);
278 int tagCount = desc->getTagCount();
279 std::vector<uint32_t> tags(tagCount);
280 desc->getTagArray(tags.data());
281 for (int i = 0; i < tagCount; i++) {
282 VendorTag vt;
283 vt.tagId = tags[i];
284 vt.tagName = desc->getTagName(tags[i]);
285 vt.tagType = (CameraMetadataType) desc->getTagType(tags[i]);
286 ssize_t sectionIdx = desc->getSectionIndex(tags[i]);
287 tagsBySection[sectionIdx].push_back(vt);
288 }
289 mVendorTagSections.resize(numSections);
290 for (size_t s = 0; s < numSections; s++) {
291 mVendorTagSections[s].sectionName = (*sectionNames)[s].string();
292 mVendorTagSections[s].tags = tagsBySection[s];
293 }
294 return true;
295}
296
297// Methods from ::android::hardware::camera::provider::V2_4::ICameraProvider follow.
298Return<Status> CameraProvider::setCallback(const sp<ICameraProviderCallback>& callback) {
Yin-Chia Yehfca2e742017-01-31 16:00:20 -0800299 Mutex::Autolock _l(mCbLock);
300 mCallbacks = callback;
301 return Status::OK;
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -0800302}
303
304Return<void> CameraProvider::getVendorTags(getVendorTags_cb _hidl_cb) {
305 _hidl_cb(Status::OK, mVendorTagSections);
306 return Void();
307}
308
309Return<void> CameraProvider::getCameraIdList(getCameraIdList_cb _hidl_cb) {
310 std::vector<hidl_string> deviceNameList;
311 for (auto const& deviceNamePair : mCameraDeviceNames) {
312 if (mCameraStatusMap[deviceNamePair.first] == CAMERA_DEVICE_STATUS_PRESENT) {
313 deviceNameList.push_back(deviceNamePair.second);
314 }
315 }
316 hidl_vec<hidl_string> hidlDeviceNameList(deviceNameList);
Yin-Chia Yeh9c6dbd52016-12-22 14:55:02 -0800317 _hidl_cb(Status::OK, hidlDeviceNameList);
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -0800318 return Void();
319}
320
321Return<void> CameraProvider::isSetTorchModeSupported(isSetTorchModeSupported_cb _hidl_cb) {
322 bool support = mModule->isSetTorchModeSupported();
323 _hidl_cb (Status::OK, support);
324 return Void();
325}
326
Yin-Chia Yeh9c6dbd52016-12-22 14:55:02 -0800327Return<void> CameraProvider::getCameraDeviceInterface_V1_x(
Yin-Chia Yehff0bc022017-01-30 15:57:45 -0800328 const hidl_string& /*cameraDeviceName*/, getCameraDeviceInterface_V1_x_cb _hidl_cb) {
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -0800329 // TODO implement after device 1.0 is implemented
Yin-Chia Yehff0bc022017-01-30 15:57:45 -0800330 _hidl_cb(Status::INTERNAL_ERROR, nullptr);
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -0800331 return Void();
332}
333
Yin-Chia Yeh9c6dbd52016-12-22 14:55:02 -0800334Return<void> CameraProvider::getCameraDeviceInterface_V3_x(
335 const hidl_string& cameraDeviceName, getCameraDeviceInterface_V3_x_cb _hidl_cb) {
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -0800336 std::smatch sm;
337 bool match = matchDeviceName(cameraDeviceName, sm);
338 if (!match) {
339 _hidl_cb(Status::ILLEGAL_ARGUMENT, nullptr);
340 return Void();
341 }
342
343 std::string cameraId = sm[2];
Yin-Chia Yeh9c6dbd52016-12-22 14:55:02 -0800344 std::string deviceVersion = sm[1];
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -0800345 std::string deviceName(cameraDeviceName.c_str());
346 ssize_t index = mCameraDeviceNames.indexOf(std::make_pair(cameraId, deviceName));
347 if (index == NAME_NOT_FOUND) { // Either an illegal name or a device version mismatch
348 Status status = Status::OK;
349 ssize_t idx = mCameraIds.indexOf(cameraId);
350 if (idx == NAME_NOT_FOUND) {
Yin-Chia Yeh9c6dbd52016-12-22 14:55:02 -0800351 ALOGE("%s: cannot find camera %s!", __FUNCTION__, cameraId.c_str());
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -0800352 status = Status::ILLEGAL_ARGUMENT;
353 } else { // invalid version
Yin-Chia Yeh9c6dbd52016-12-22 14:55:02 -0800354 ALOGE("%s: camera device %s does not support version %s!",
355 __FUNCTION__, cameraId.c_str(), deviceVersion.c_str());
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -0800356 status = Status::OPERATION_NOT_SUPPORTED;
357 }
358 _hidl_cb(status, nullptr);
359 return Void();
360 }
361
362 if (mCameraStatusMap.count(cameraId) == 0 ||
363 mCameraStatusMap[cameraId] != CAMERA_DEVICE_STATUS_PRESENT) {
364 _hidl_cb(Status::ILLEGAL_ARGUMENT, nullptr);
365 return Void();
366 }
367
368 // TODO: we also need to keep a wp list of all generated devices to notify
369 // devices of device present status change, but then each device might
370 // need a sp<provider> to keep provider alive until all device closed?
371 // Problem: do we have external camera products to test this?
372 sp<android::hardware::camera::device::V3_2::implementation::CameraDevice> device =
373 new android::hardware::camera::device::V3_2::implementation::CameraDevice(
374 mModule, cameraId, mCameraDeviceNames);
375
376 if (device == nullptr) {
Yin-Chia Yeh9c6dbd52016-12-22 14:55:02 -0800377 ALOGE("%s: cannot allocate camera device for id %s", __FUNCTION__, cameraId.c_str());
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -0800378 _hidl_cb(Status::INTERNAL_ERROR, nullptr);
379 return Void();
380 }
381
382 if (device->isInitFailed()) {
Yin-Chia Yeh9c6dbd52016-12-22 14:55:02 -0800383 ALOGE("%s: camera device %s init failed!", __FUNCTION__, cameraId.c_str());
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -0800384 device = nullptr;
385 _hidl_cb(Status::INTERNAL_ERROR, nullptr);
386 return Void();
387 }
388
389 _hidl_cb (Status::OK, device);
390 return Void();
391}
392
393ICameraProvider* HIDL_FETCH_ICameraProvider(const char* name) {
394 if (strcmp(name, kLegacyProviderName) != 0) {
395 return nullptr;
396 }
397 CameraProvider* provider = new CameraProvider();
398 if (provider == nullptr) {
399 ALOGE("%s: cannot allocate camera provider!", __FUNCTION__);
400 return nullptr;
401 }
402 if (provider->isInitFailed()) {
403 ALOGE("%s: camera provider init failed!", __FUNCTION__);
404 delete provider;
405 return nullptr;
406 }
407 return provider;
408}
409
410} // namespace implementation
411} // namespace V2_4
412} // namespace provider
413} // namespace camera
414} // namespace hardware
415} // namespace android