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