blob: 1a34aa63e908e1d2f3b8649c0bbc6350cac43a4f [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) {
187 ALOGE("Could not initialize camera HAL module: %d (%s)", err,
188 strerror(-err));
189 mModule.clear();
190 return true;
191 }
192 ALOGI("Loaded \"%s\" camera module", mModule->getModuleName());
193
194 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();
Yin-Chia Yeh9c6dbd52016-12-22 14:55:02 -0800230 bool setupSucceed = setUpVendorTags();
231 return !setupSucceed; // return flag here is mInitFailed
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -0800232}
233
234bool CameraProvider::setUpVendorTags() {
235 ATRACE_CALL();
236 vendor_tag_ops_t vOps = vendor_tag_ops_t();
237
238 // Check if vendor operations have been implemented
239 if (!mModule->isVendorTagDefined()) {
240 ALOGI("%s: No vendor tags defined for this device.", __FUNCTION__);
241 return false;
242 }
243
244 mModule->getVendorTagOps(&vOps);
245
246 // Ensure all vendor operations are present
247 if (vOps.get_tag_count == nullptr || vOps.get_all_tags == nullptr ||
248 vOps.get_section_name == nullptr || vOps.get_tag_name == nullptr ||
249 vOps.get_tag_type == nullptr) {
250 ALOGE("%s: Vendor tag operations not fully defined. Ignoring definitions."
251 , __FUNCTION__);
252 return false;
253 }
254
255 // Read all vendor tag definitions into a descriptor
256 sp<VendorTagDescriptor> desc;
257 status_t res;
258 if ((res = VendorTagDescriptor::createDescriptorFromOps(&vOps, /*out*/desc))
259 != OK) {
260 ALOGE("%s: Could not generate descriptor from vendor tag operations,"
261 "received error %s (%d). Camera clients will not be able to use"
262 "vendor tags", __FUNCTION__, strerror(res), res);
263 return false;
264 }
265
266 // Set the global descriptor to use with camera metadata
267 VendorTagDescriptor::setAsGlobalVendorTagDescriptor(desc);
268 const SortedVector<String8>* sectionNames = desc->getAllSectionNames();
269 size_t numSections = sectionNames->size();
270 std::vector<std::vector<VendorTag>> tagsBySection(numSections);
271 int tagCount = desc->getTagCount();
272 std::vector<uint32_t> tags(tagCount);
273 desc->getTagArray(tags.data());
274 for (int i = 0; i < tagCount; i++) {
275 VendorTag vt;
276 vt.tagId = tags[i];
277 vt.tagName = desc->getTagName(tags[i]);
278 vt.tagType = (CameraMetadataType) desc->getTagType(tags[i]);
279 ssize_t sectionIdx = desc->getSectionIndex(tags[i]);
280 tagsBySection[sectionIdx].push_back(vt);
281 }
282 mVendorTagSections.resize(numSections);
283 for (size_t s = 0; s < numSections; s++) {
284 mVendorTagSections[s].sectionName = (*sectionNames)[s].string();
285 mVendorTagSections[s].tags = tagsBySection[s];
286 }
287 return true;
288}
289
290// Methods from ::android::hardware::camera::provider::V2_4::ICameraProvider follow.
291Return<Status> CameraProvider::setCallback(const sp<ICameraProviderCallback>& callback) {
292 {
293 Mutex::Autolock _l(mCbLock);
294 mCallbacks = callback;
295 } // release lock here because HAL might send callbacks in setCallbacks call
296 return getHidlStatus(mModule->setCallbacks(this));
297}
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(
323 const hidl_string& /*cameraDeviceName*/, getCameraDeviceInterface_V1_x_cb /*_hidl_cb*/) {
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -0800324 // TODO implement after device 1.0 is implemented
325 return Void();
326}
327
Yin-Chia Yeh9c6dbd52016-12-22 14:55:02 -0800328Return<void> CameraProvider::getCameraDeviceInterface_V3_x(
329 const hidl_string& cameraDeviceName, getCameraDeviceInterface_V3_x_cb _hidl_cb) {
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -0800330 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];
Yin-Chia Yeh9c6dbd52016-12-22 14:55:02 -0800338 std::string deviceVersion = sm[1];
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -0800339 std::string deviceName(cameraDeviceName.c_str());
340 ssize_t index = mCameraDeviceNames.indexOf(std::make_pair(cameraId, deviceName));
341 if (index == NAME_NOT_FOUND) { // Either an illegal name or a device version mismatch
342 Status status = Status::OK;
343 ssize_t idx = mCameraIds.indexOf(cameraId);
344 if (idx == NAME_NOT_FOUND) {
Yin-Chia Yeh9c6dbd52016-12-22 14:55:02 -0800345 ALOGE("%s: cannot find camera %s!", __FUNCTION__, cameraId.c_str());
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -0800346 status = Status::ILLEGAL_ARGUMENT;
347 } else { // invalid version
Yin-Chia Yeh9c6dbd52016-12-22 14:55:02 -0800348 ALOGE("%s: camera device %s does not support version %s!",
349 __FUNCTION__, cameraId.c_str(), deviceVersion.c_str());
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -0800350 status = Status::OPERATION_NOT_SUPPORTED;
351 }
352 _hidl_cb(status, nullptr);
353 return Void();
354 }
355
356 if (mCameraStatusMap.count(cameraId) == 0 ||
357 mCameraStatusMap[cameraId] != CAMERA_DEVICE_STATUS_PRESENT) {
358 _hidl_cb(Status::ILLEGAL_ARGUMENT, nullptr);
359 return Void();
360 }
361
362 // TODO: we also need to keep a wp list of all generated devices to notify
363 // devices of device present status change, but then each device might
364 // need a sp<provider> to keep provider alive until all device closed?
365 // Problem: do we have external camera products to test this?
366 sp<android::hardware::camera::device::V3_2::implementation::CameraDevice> device =
367 new android::hardware::camera::device::V3_2::implementation::CameraDevice(
368 mModule, cameraId, mCameraDeviceNames);
369
370 if (device == nullptr) {
Yin-Chia Yeh9c6dbd52016-12-22 14:55:02 -0800371 ALOGE("%s: cannot allocate camera device for id %s", __FUNCTION__, cameraId.c_str());
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -0800372 _hidl_cb(Status::INTERNAL_ERROR, nullptr);
373 return Void();
374 }
375
376 if (device->isInitFailed()) {
Yin-Chia Yeh9c6dbd52016-12-22 14:55:02 -0800377 ALOGE("%s: camera device %s init failed!", __FUNCTION__, cameraId.c_str());
Yin-Chia Yehf906b3b2016-12-14 19:13:15 -0800378 device = nullptr;
379 _hidl_cb(Status::INTERNAL_ERROR, nullptr);
380 return Void();
381 }
382
383 _hidl_cb (Status::OK, device);
384 return Void();
385}
386
387ICameraProvider* HIDL_FETCH_ICameraProvider(const char* name) {
388 if (strcmp(name, kLegacyProviderName) != 0) {
389 return nullptr;
390 }
391 CameraProvider* provider = new CameraProvider();
392 if (provider == nullptr) {
393 ALOGE("%s: cannot allocate camera provider!", __FUNCTION__);
394 return nullptr;
395 }
396 if (provider->isInitFailed()) {
397 ALOGE("%s: camera provider init failed!", __FUNCTION__);
398 delete provider;
399 return nullptr;
400 }
401 return provider;
402}
403
404} // namespace implementation
405} // namespace V2_4
406} // namespace provider
407} // namespace camera
408} // namespace hardware
409} // namespace android