blob: d9ac26168e105b74e6184eb3360b60481380278f [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
20#include <regex>
21
22#include "CameraProvider.h"
23#include "CameraDevice.h"
24#include <string.h>
25#include <utils/Trace.h>
26
27
28namespace android {
29namespace hardware {
30namespace camera {
31namespace provider {
32namespace V2_4 {
33namespace implementation {
34
35namespace {
36const char *kLegacyProviderName = "legacy/0";
37// "device@<version>/legacy/<id>"
38const std::regex kDeviceNameRE("device@([0-9]+\\.[0-9]+)/legacy/(.+)");
39const char *kHAL3_2 = "3.2";
40const char *kHAL1_0 = "1.0";
41const int kMaxCameraDeviceNameLen = 128;
42const int kMaxCameraIdLen = 16;
43
44} // anonymous namespace
45
46using ::android::hardware::camera::common::V1_0::CameraMetadataType;
47using ::android::hardware::camera::common::V1_0::Status;
48
49/**
50 * static callback forwarding methods from HAL to instance
51 */
52void CameraProvider::sCameraDeviceStatusChange(
53 const struct camera_module_callbacks* callbacks,
54 int camera_id,
55 int new_status) {
56 ALOGI("%s++", __FUNCTION__);
57 sp<CameraProvider> cp = const_cast<CameraProvider*>(
58 static_cast<const CameraProvider*>(callbacks));
59
60 if (cp == nullptr) {
61 ALOGE("%s: callback ops is null", __FUNCTION__);
62 return;
63 }
64
65 ALOGI("%s resolved provider %p", __FUNCTION__, cp.get());
66
67 Mutex::Autolock _l(cp->mCbLock);
68 char cameraId[kMaxCameraIdLen];
69 snprintf(cameraId, sizeof(cameraId), "%d", camera_id);
70 std::string cameraIdStr(cameraId);
71 cp->mCameraStatusMap[cameraIdStr] = (camera_device_status_t) new_status;
72 if (cp->mCallbacks != nullptr) {
73 CameraDeviceStatus status = (CameraDeviceStatus) new_status;
74 for (auto const& deviceNamePair : cp->mCameraDeviceNames) {
75 if (cameraIdStr.compare(deviceNamePair.first) == 0) {
76 cp->mCallbacks->cameraDeviceStatusChange(
77 deviceNamePair.second, status);
78 }
79 }
80 }
81 ALOGI("%s--", __FUNCTION__);
82}
83
84void CameraProvider::sTorchModeStatusChange(
85 const struct camera_module_callbacks* callbacks,
86 const char* camera_id,
87 int new_status) {
88 ALOGI("%s++", __FUNCTION__);
89 sp<CameraProvider> cp = const_cast<CameraProvider*>(
90 static_cast<const CameraProvider*>(callbacks));
91
92 if (cp == nullptr) {
93 ALOGE("%s: callback ops is null", __FUNCTION__);
94 return;
95 }
96
97 ALOGI("%s resolved provider %p", __FUNCTION__, cp.get());
98
99 Mutex::Autolock _l(cp->mCbLock);
100 if (cp->mCallbacks != nullptr) {
101 std::string cameraIdStr(camera_id);
102 TorchModeStatus status = (TorchModeStatus) new_status;
103 for (auto const& deviceNamePair : cp->mCameraDeviceNames) {
104 if (cameraIdStr.compare(getLegacyCameraId(deviceNamePair.first)) == 0) {
105 cp->mCallbacks->torchModeStatusChange(
106 deviceNamePair.second, status);
107 }
108 }
109 }
110 ALOGI("%s--", __FUNCTION__);
111}
112
113Status CameraProvider::getHidlStatus(int status) {
114 switch (status) {
115 case 0: return Status::OK;
116 case -ENODEV: return Status::INTERNAL_ERROR;
117 case -EINVAL: return Status::ILLEGAL_ARGUMENT;
118 default:
119 ALOGE("%s: unknown HAL status code %d", __FUNCTION__, status);
120 return Status::INTERNAL_ERROR;
121 }
122}
123
124bool CameraProvider::matchDeviceName(const hidl_string& deviceName, std::smatch& sm) {
125 std::string deviceNameStd(deviceName.c_str());
126 return std::regex_match(deviceNameStd, sm, kDeviceNameRE);
127}
128
129std::string CameraProvider::getLegacyCameraId(const hidl_string& deviceName) {
130 std::smatch sm;
131 bool match = matchDeviceName(deviceName, sm);
132 if (!match) {
133 return std::string("");
134 }
135 return sm[2];
136}
137
138int CameraProvider::getCameraDeviceVersion(const hidl_string& deviceName) {
139 std::smatch sm;
140 bool match = matchDeviceName(deviceName, sm);
141 if (!match) {
142 return -1;
143 }
144 if (sm[1].compare(kHAL3_2) == 0) {
145 // maybe switched to 3.4 or define the hidl version enumlater
146 return CAMERA_DEVICE_API_VERSION_3_2;
147 } else if (sm[1].compare(kHAL1_0) == 0) {
148 return CAMERA_DEVICE_API_VERSION_1_0;
149 }
150 return 0;
151}
152
153std::string CameraProvider::getHidlDeviceName(
154 std::string cameraId, int deviceVersion) {
155 // Maybe consider create a version check method and SortedVec to speed up?
156 if (deviceVersion != CAMERA_DEVICE_API_VERSION_1_0 &&
157 deviceVersion != CAMERA_DEVICE_API_VERSION_3_2 &&
158 deviceVersion != CAMERA_DEVICE_API_VERSION_3_3 &&
159 deviceVersion != CAMERA_DEVICE_API_VERSION_3_4 ) {
160 return hidl_string("");
161 }
162 const char* versionStr = (deviceVersion == CAMERA_DEVICE_API_VERSION_1_0) ? kHAL1_0 : kHAL3_2;
163 char deviceName[kMaxCameraDeviceNameLen];
164 snprintf(deviceName, sizeof(deviceName), "device@%s/legacy/%s",
165 versionStr, cameraId.c_str());
166 return deviceName;
167}
168
169CameraProvider::CameraProvider() :
170 camera_module_callbacks_t({sCameraDeviceStatusChange,
171 sTorchModeStatusChange}) {
172 mInitFailed = initialize();
173}
174
175CameraProvider::~CameraProvider() {}
176
177bool CameraProvider::initialize() {
178 camera_module_t *rawModule;
179 int err = hw_get_module(CAMERA_HARDWARE_MODULE_ID,
180 (const hw_module_t **)&rawModule);
181 if (err < 0) {
182 ALOGE("Could not load camera HAL module: %d (%s)", err, strerror(-err));
183 return true;
184 }
185
186 mModule = new CameraModule(rawModule);
187 err = mModule->init();
188 if (err != OK) {
189 ALOGE("Could not initialize camera HAL module: %d (%s)", err,
190 strerror(-err));
191 mModule.clear();
192 return true;
193 }
194 ALOGI("Loaded \"%s\" camera module", mModule->getModuleName());
195
196 mNumberOfLegacyCameras = mModule->getNumberOfCameras();
197 for (int i = 0; i < mNumberOfLegacyCameras; i++) {
198 char cameraId[kMaxCameraIdLen];
199 snprintf(cameraId, sizeof(cameraId), "%d", i);
200 std::string cameraIdStr(cameraId);
201 mCameraStatusMap[cameraIdStr] = CAMERA_DEVICE_STATUS_PRESENT;
202 mCameraIds.add(cameraIdStr);
203
204 // initialize mCameraDeviceNames and mOpenLegacySupported
205 mOpenLegacySupported[cameraIdStr] = false;
206 int deviceVersion = mModule->getDeviceVersion(i);
207 mCameraDeviceNames.add(
208 std::make_pair(cameraIdStr,
209 getHidlDeviceName(cameraIdStr, deviceVersion)));
210 if (deviceVersion >= CAMERA_DEVICE_API_VERSION_3_2 &&
211 mModule->isOpenLegacyDefined()) {
212 // try open_legacy to see if it actually works
213 struct hw_device_t* halDev = nullptr;
214 int ret = mModule->openLegacy(cameraId, CAMERA_DEVICE_API_VERSION_1_0, &halDev);
215 if (ret == 0) {
216 mOpenLegacySupported[cameraIdStr] = true;
217 halDev->close(halDev);
218 mCameraDeviceNames.add(
219 std::make_pair(cameraIdStr,
220 getHidlDeviceName(cameraIdStr, CAMERA_DEVICE_API_VERSION_1_0)));
221 } else if (ret == -EBUSY || ret == -EUSERS) {
222 // Looks like this provider instance is not initialized during
223 // system startup and there are other camera users already.
224 // Not a good sign but not fatal.
225 ALOGW("%s: open_legacy try failed!", __FUNCTION__);
226 }
227 }
228 }
229
230 // Setup vendor tags here so HAL can setup vendor keys in camera characteristics
231 VendorTagDescriptor::clearGlobalVendorTagDescriptor();
232 setUpVendorTags();
233 return false;
234}
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__);
243 return false;
244 }
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) {
294 {
295 Mutex::Autolock _l(mCbLock);
296 mCallbacks = callback;
297 } // release lock here because HAL might send callbacks in setCallbacks call
298 return getHidlStatus(mModule->setCallbacks(this));
299}
300
301Return<void> CameraProvider::getVendorTags(getVendorTags_cb _hidl_cb) {
302 _hidl_cb(Status::OK, mVendorTagSections);
303 return Void();
304}
305
306Return<void> CameraProvider::getCameraIdList(getCameraIdList_cb _hidl_cb) {
307 std::vector<hidl_string> deviceNameList;
308 for (auto const& deviceNamePair : mCameraDeviceNames) {
309 if (mCameraStatusMap[deviceNamePair.first] == CAMERA_DEVICE_STATUS_PRESENT) {
310 deviceNameList.push_back(deviceNamePair.second);
311 }
312 }
313 hidl_vec<hidl_string> hidlDeviceNameList(deviceNameList);
314 _hidl_cb (Status::OK, hidlDeviceNameList);
315 return Void();
316}
317
318Return<void> CameraProvider::isSetTorchModeSupported(isSetTorchModeSupported_cb _hidl_cb) {
319 bool support = mModule->isSetTorchModeSupported();
320 _hidl_cb (Status::OK, support);
321 return Void();
322}
323
324Return<void> CameraProvider::getCameraDeviceInterface_V1_x(const hidl_string& /*cameraDeviceName*/, getCameraDeviceInterface_V1_x_cb /*_hidl_cb*/) {
325 // TODO implement after device 1.0 is implemented
326 return Void();
327}
328
329Return<void> CameraProvider::getCameraDeviceInterface_V3_x(const hidl_string& cameraDeviceName, getCameraDeviceInterface_V3_x_cb _hidl_cb) {
330 std::smatch sm;
331 bool match = matchDeviceName(cameraDeviceName, sm);
332 if (!match) {
333 _hidl_cb(Status::ILLEGAL_ARGUMENT, nullptr);
334 return Void();
335 }
336
337 std::string cameraId = sm[2];
338 std::string deviceName(cameraDeviceName.c_str());
339 ssize_t index = mCameraDeviceNames.indexOf(std::make_pair(cameraId, deviceName));
340 if (index == NAME_NOT_FOUND) { // Either an illegal name or a device version mismatch
341 Status status = Status::OK;
342 ssize_t idx = mCameraIds.indexOf(cameraId);
343 if (idx == NAME_NOT_FOUND) {
344 status = Status::ILLEGAL_ARGUMENT;
345 } else { // invalid version
346 status = Status::OPERATION_NOT_SUPPORTED;
347 }
348 _hidl_cb(status, nullptr);
349 return Void();
350 }
351
352 if (mCameraStatusMap.count(cameraId) == 0 ||
353 mCameraStatusMap[cameraId] != CAMERA_DEVICE_STATUS_PRESENT) {
354 _hidl_cb(Status::ILLEGAL_ARGUMENT, nullptr);
355 return Void();
356 }
357
358 // TODO: we also need to keep a wp list of all generated devices to notify
359 // devices of device present status change, but then each device might
360 // need a sp<provider> to keep provider alive until all device closed?
361 // Problem: do we have external camera products to test this?
362 sp<android::hardware::camera::device::V3_2::implementation::CameraDevice> device =
363 new android::hardware::camera::device::V3_2::implementation::CameraDevice(
364 mModule, cameraId, mCameraDeviceNames);
365
366 if (device == nullptr) {
367 ALOGE("%s: cannot allocate camera device!", __FUNCTION__);
368 _hidl_cb(Status::INTERNAL_ERROR, nullptr);
369 return Void();
370 }
371
372 if (device->isInitFailed()) {
373 ALOGE("%s: camera device init failed!", __FUNCTION__);
374 device = nullptr;
375 _hidl_cb(Status::INTERNAL_ERROR, nullptr);
376 return Void();
377 }
378
379 _hidl_cb (Status::OK, device);
380 return Void();
381}
382
383ICameraProvider* HIDL_FETCH_ICameraProvider(const char* name) {
384 if (strcmp(name, kLegacyProviderName) != 0) {
385 return nullptr;
386 }
387 CameraProvider* provider = new CameraProvider();
388 if (provider == nullptr) {
389 ALOGE("%s: cannot allocate camera provider!", __FUNCTION__);
390 return nullptr;
391 }
392 if (provider->isInitFailed()) {
393 ALOGE("%s: camera provider init failed!", __FUNCTION__);
394 delete provider;
395 return nullptr;
396 }
397 return provider;
398}
399
400} // namespace implementation
401} // namespace V2_4
402} // namespace provider
403} // namespace camera
404} // namespace hardware
405} // namespace android