1 /*
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 "CameraProvider.h"
21 #include "CameraDevice_1_0.h"
22 #include "CameraDevice_3_2.h"
23 #include <string.h>
24 #include <utils/Trace.h>
25 
26 
27 namespace android {
28 namespace hardware {
29 namespace camera {
30 namespace provider {
31 namespace V2_4 {
32 namespace implementation {
33 
34 namespace {
35 const char *kLegacyProviderName = "legacy/0";
36 // "device@<version>/legacy/<id>"
37 const std::regex kDeviceNameRE("device@([0-9]+\\.[0-9]+)/legacy/(.+)");
38 const char *kHAL3_2 = "3.2";
39 const char *kHAL1_0 = "1.0";
40 const int kMaxCameraDeviceNameLen = 128;
41 const int kMaxCameraIdLen = 16;
42 
matchDeviceName(const hidl_string & deviceName,std::string * deviceVersion,std::string * cameraId)43 bool matchDeviceName(const hidl_string& deviceName, std::string* deviceVersion,
44                      std::string* cameraId) {
45     std::string deviceNameStd(deviceName.c_str());
46     std::smatch sm;
47     if (std::regex_match(deviceNameStd, sm, kDeviceNameRE)) {
48         if (deviceVersion != nullptr) {
49             *deviceVersion = sm[1];
50         }
51         if (cameraId != nullptr) {
52             *cameraId = sm[2];
53         }
54         return true;
55     }
56     return false;
57 }
58 
59 } // anonymous namespace
60 
61 using ::android::hardware::camera::common::V1_0::CameraMetadataType;
62 using ::android::hardware::camera::common::V1_0::Status;
63 
64 /**
65  * static callback forwarding methods from HAL to instance
66  */
sCameraDeviceStatusChange(const struct camera_module_callbacks * callbacks,int camera_id,int new_status)67 void CameraProvider::sCameraDeviceStatusChange(
68         const struct camera_module_callbacks* callbacks,
69         int camera_id,
70         int new_status) {
71     CameraProvider* cp = const_cast<CameraProvider*>(
72             static_cast<const CameraProvider*>(callbacks));
73 
74     if (cp == nullptr) {
75         ALOGE("%s: callback ops is null", __FUNCTION__);
76         return;
77     }
78 
79     Mutex::Autolock _l(cp->mCbLock);
80     char cameraId[kMaxCameraIdLen];
81     snprintf(cameraId, sizeof(cameraId), "%d", camera_id);
82     std::string cameraIdStr(cameraId);
83     cp->mCameraStatusMap[cameraIdStr] = (camera_device_status_t) new_status;
84     if (cp->mCallbacks != nullptr) {
85         CameraDeviceStatus status = (CameraDeviceStatus) new_status;
86         for (auto const& deviceNamePair : cp->mCameraDeviceNames) {
87             if (cameraIdStr.compare(deviceNamePair.first) == 0) {
88                 cp->mCallbacks->cameraDeviceStatusChange(
89                         deviceNamePair.second, status);
90             }
91         }
92     }
93 }
94 
sTorchModeStatusChange(const struct camera_module_callbacks * callbacks,const char * camera_id,int new_status)95 void CameraProvider::sTorchModeStatusChange(
96         const struct camera_module_callbacks* callbacks,
97         const char* camera_id,
98         int new_status) {
99     CameraProvider* cp = const_cast<CameraProvider*>(
100             static_cast<const CameraProvider*>(callbacks));
101 
102     if (cp == nullptr) {
103         ALOGE("%s: callback ops is null", __FUNCTION__);
104         return;
105     }
106 
107     Mutex::Autolock _l(cp->mCbLock);
108     if (cp->mCallbacks != nullptr) {
109         std::string cameraIdStr(camera_id);
110         TorchModeStatus status = (TorchModeStatus) new_status;
111         for (auto const& deviceNamePair : cp->mCameraDeviceNames) {
112             if (cameraIdStr.compare(deviceNamePair.first) == 0) {
113                 cp->mCallbacks->torchModeStatusChange(
114                         deviceNamePair.second, status);
115             }
116         }
117     }
118 }
119 
getHidlStatus(int status)120 Status CameraProvider::getHidlStatus(int status) {
121     switch (status) {
122         case 0: return Status::OK;
123         case -ENODEV: return Status::INTERNAL_ERROR;
124         case -EINVAL: return Status::ILLEGAL_ARGUMENT;
125         default:
126             ALOGE("%s: unknown HAL status code %d", __FUNCTION__, status);
127             return Status::INTERNAL_ERROR;
128     }
129 }
130 
getLegacyCameraId(const hidl_string & deviceName)131 std::string CameraProvider::getLegacyCameraId(const hidl_string& deviceName) {
132     std::string cameraId;
133     matchDeviceName(deviceName, nullptr, &cameraId);
134     return cameraId;
135 }
136 
getCameraDeviceVersion(const hidl_string & deviceName)137 int CameraProvider::getCameraDeviceVersion(const hidl_string& deviceName) {
138     std::string deviceVersion;
139     bool match = matchDeviceName(deviceName, &deviceVersion, nullptr);
140     if (!match) {
141         return -1;
142     }
143     if (deviceVersion == kHAL3_2) {
144         // maybe switched to 3.4 or define the hidl version enum later
145         return CAMERA_DEVICE_API_VERSION_3_2;
146     } else if (deviceVersion == kHAL1_0) {
147         return CAMERA_DEVICE_API_VERSION_1_0;
148     }
149     return 0;
150 }
151 
getHidlDeviceName(std::string cameraId,int deviceVersion)152 std::string CameraProvider::getHidlDeviceName(
153         std::string cameraId, int deviceVersion) {
154     // Maybe consider create a version check method and SortedVec to speed up?
155     if (deviceVersion != CAMERA_DEVICE_API_VERSION_1_0 &&
156             deviceVersion != CAMERA_DEVICE_API_VERSION_3_2 &&
157             deviceVersion != CAMERA_DEVICE_API_VERSION_3_3 &&
158             deviceVersion != CAMERA_DEVICE_API_VERSION_3_4 ) {
159         return hidl_string("");
160     }
161     const char* versionStr = (deviceVersion == CAMERA_DEVICE_API_VERSION_1_0) ? kHAL1_0 : kHAL3_2;
162     char deviceName[kMaxCameraDeviceNameLen];
163     snprintf(deviceName, sizeof(deviceName), "device@%s/legacy/%s",
164             versionStr, cameraId.c_str());
165     return deviceName;
166 }
167 
CameraProvider()168 CameraProvider::CameraProvider() :
169         camera_module_callbacks_t({sCameraDeviceStatusChange,
170                                    sTorchModeStatusChange}) {
171     mInitFailed = initialize();
172 }
173 
~CameraProvider()174 CameraProvider::~CameraProvider() {}
175 
initialize()176 bool CameraProvider::initialize() {
177     camera_module_t *rawModule;
178     int err = hw_get_module(CAMERA_HARDWARE_MODULE_ID,
179             (const hw_module_t **)&rawModule);
180     if (err < 0) {
181         ALOGE("Could not load camera HAL module: %d (%s)", err, strerror(-err));
182         return true;
183     }
184 
185     mModule = new CameraModule(rawModule);
186     err = mModule->init();
187     if (err != OK) {
188         ALOGE("Could not initialize camera HAL module: %d (%s)", err, strerror(-err));
189         mModule.clear();
190         return true;
191     }
192     ALOGI("Loaded \"%s\" camera module", mModule->getModuleName());
193 
194     // Setup vendor tags here so HAL can setup vendor keys in camera characteristics
195     VendorTagDescriptor::clearGlobalVendorTagDescriptor();
196     if (!setUpVendorTags()) {
197         ALOGE("%s: Vendor tag setup failed, will not be available.", __FUNCTION__);
198     }
199 
200     // Setup callback now because we are going to try openLegacy next
201     err = mModule->setCallbacks(this);
202     if (err != OK) {
203         ALOGE("Could not set camera module callback: %d (%s)", err, strerror(-err));
204         mModule.clear();
205         return true;
206     }
207 
208     mNumberOfLegacyCameras = mModule->getNumberOfCameras();
209     for (int i = 0; i < mNumberOfLegacyCameras; i++) {
210         struct camera_info info;
211         auto rc = mModule->getCameraInfo(i, &info);
212         if (rc != NO_ERROR) {
213             ALOGE("%s: Camera info query failed!", __func__);
214             mModule.clear();
215             return true;
216         }
217 
218         if (checkCameraVersion(i, info) != OK) {
219             ALOGE("%s: Camera version check failed!", __func__);
220             mModule.clear();
221             return true;
222         }
223 
224         char cameraId[kMaxCameraIdLen];
225         snprintf(cameraId, sizeof(cameraId), "%d", i);
226         std::string cameraIdStr(cameraId);
227         mCameraStatusMap[cameraIdStr] = CAMERA_DEVICE_STATUS_PRESENT;
228         mCameraIds.add(cameraIdStr);
229 
230         // initialize mCameraDeviceNames and mOpenLegacySupported
231         mOpenLegacySupported[cameraIdStr] = false;
232         int deviceVersion = mModule->getDeviceVersion(i);
233         mCameraDeviceNames.add(
234                 std::make_pair(cameraIdStr,
235                                getHidlDeviceName(cameraIdStr, deviceVersion)));
236         if (deviceVersion >= CAMERA_DEVICE_API_VERSION_3_2 &&
237                 mModule->isOpenLegacyDefined()) {
238             // try open_legacy to see if it actually works
239             struct hw_device_t* halDev = nullptr;
240             int ret = mModule->openLegacy(cameraId, CAMERA_DEVICE_API_VERSION_1_0, &halDev);
241             if (ret == 0) {
242                 mOpenLegacySupported[cameraIdStr] = true;
243                 halDev->close(halDev);
244                 mCameraDeviceNames.add(
245                         std::make_pair(cameraIdStr,
246                                 getHidlDeviceName(cameraIdStr, CAMERA_DEVICE_API_VERSION_1_0)));
247             } else if (ret == -EBUSY || ret == -EUSERS) {
248                 // Looks like this provider instance is not initialized during
249                 // system startup and there are other camera users already.
250                 // Not a good sign but not fatal.
251                 ALOGW("%s: open_legacy try failed!", __FUNCTION__);
252             }
253         }
254     }
255 
256     return false; // mInitFailed
257 }
258 
259 /**
260  * Check that the device HAL version is still in supported.
261  */
checkCameraVersion(int id,camera_info info)262 int CameraProvider::checkCameraVersion(int id, camera_info info) {
263     if (mModule == nullptr) {
264         return NO_INIT;
265     }
266 
267     // device_version undefined in CAMERA_MODULE_API_VERSION_1_0,
268     // All CAMERA_MODULE_API_VERSION_1_0 devices are backward-compatible
269     if (mModule->getModuleApiVersion() >= CAMERA_MODULE_API_VERSION_2_0) {
270         // Verify the device version is in the supported range
271         switch (info.device_version) {
272             case CAMERA_DEVICE_API_VERSION_1_0:
273             case CAMERA_DEVICE_API_VERSION_3_2:
274             case CAMERA_DEVICE_API_VERSION_3_3:
275             case CAMERA_DEVICE_API_VERSION_3_4:
276                 // in support
277                 break;
278             case CAMERA_DEVICE_API_VERSION_2_0:
279             case CAMERA_DEVICE_API_VERSION_2_1:
280             case CAMERA_DEVICE_API_VERSION_3_0:
281             case CAMERA_DEVICE_API_VERSION_3_1:
282                 // no longer supported
283             default:
284                 ALOGE("%s: Device %d has HAL version %x, which is not supported",
285                         __FUNCTION__, id, info.device_version);
286                 return NO_INIT;
287         }
288     }
289 
290     return OK;
291 }
292 
setUpVendorTags()293 bool CameraProvider::setUpVendorTags() {
294     ATRACE_CALL();
295     vendor_tag_ops_t vOps = vendor_tag_ops_t();
296 
297     // Check if vendor operations have been implemented
298     if (!mModule->isVendorTagDefined()) {
299         ALOGI("%s: No vendor tags defined for this device.", __FUNCTION__);
300         return true;
301     }
302 
303     mModule->getVendorTagOps(&vOps);
304 
305     // Ensure all vendor operations are present
306     if (vOps.get_tag_count == nullptr || vOps.get_all_tags == nullptr ||
307             vOps.get_section_name == nullptr || vOps.get_tag_name == nullptr ||
308             vOps.get_tag_type == nullptr) {
309         ALOGE("%s: Vendor tag operations not fully defined. Ignoring definitions."
310                , __FUNCTION__);
311         return false;
312     }
313 
314     // Read all vendor tag definitions into a descriptor
315     sp<VendorTagDescriptor> desc;
316     status_t res;
317     if ((res = VendorTagDescriptor::createDescriptorFromOps(&vOps, /*out*/desc))
318             != OK) {
319         ALOGE("%s: Could not generate descriptor from vendor tag operations,"
320               "received error %s (%d). Camera clients will not be able to use"
321               "vendor tags", __FUNCTION__, strerror(res), res);
322         return false;
323     }
324 
325     // Set the global descriptor to use with camera metadata
326     VendorTagDescriptor::setAsGlobalVendorTagDescriptor(desc);
327     const SortedVector<String8>* sectionNames = desc->getAllSectionNames();
328     size_t numSections = sectionNames->size();
329     std::vector<std::vector<VendorTag>> tagsBySection(numSections);
330     int tagCount = desc->getTagCount();
331     std::vector<uint32_t> tags(tagCount);
332     desc->getTagArray(tags.data());
333     for (int i = 0; i < tagCount; i++) {
334         VendorTag vt;
335         vt.tagId = tags[i];
336         vt.tagName = desc->getTagName(tags[i]);
337         vt.tagType = (CameraMetadataType) desc->getTagType(tags[i]);
338         ssize_t sectionIdx = desc->getSectionIndex(tags[i]);
339         tagsBySection[sectionIdx].push_back(vt);
340     }
341     mVendorTagSections.resize(numSections);
342     for (size_t s = 0; s < numSections; s++) {
343         mVendorTagSections[s].sectionName = (*sectionNames)[s].string();
344         mVendorTagSections[s].tags = tagsBySection[s];
345     }
346     return true;
347 }
348 
349 // Methods from ::android::hardware::camera::provider::V2_4::ICameraProvider follow.
setCallback(const sp<ICameraProviderCallback> & callback)350 Return<Status> CameraProvider::setCallback(const sp<ICameraProviderCallback>& callback)  {
351     Mutex::Autolock _l(mCbLock);
352     mCallbacks = callback;
353     return Status::OK;
354 }
355 
getVendorTags(getVendorTags_cb _hidl_cb)356 Return<void> CameraProvider::getVendorTags(getVendorTags_cb _hidl_cb)  {
357     _hidl_cb(Status::OK, mVendorTagSections);
358     return Void();
359 }
360 
getCameraIdList(getCameraIdList_cb _hidl_cb)361 Return<void> CameraProvider::getCameraIdList(getCameraIdList_cb _hidl_cb)  {
362     std::vector<hidl_string> deviceNameList;
363     for (auto const& deviceNamePair : mCameraDeviceNames) {
364         if (mCameraStatusMap[deviceNamePair.first] == CAMERA_DEVICE_STATUS_PRESENT) {
365             deviceNameList.push_back(deviceNamePair.second);
366         }
367     }
368     hidl_vec<hidl_string> hidlDeviceNameList(deviceNameList);
369     _hidl_cb(Status::OK, hidlDeviceNameList);
370     return Void();
371 }
372 
isSetTorchModeSupported(isSetTorchModeSupported_cb _hidl_cb)373 Return<void> CameraProvider::isSetTorchModeSupported(isSetTorchModeSupported_cb _hidl_cb) {
374     bool support = mModule->isSetTorchModeSupported();
375     _hidl_cb (Status::OK, support);
376     return Void();
377 }
378 
getCameraDeviceInterface_V1_x(const hidl_string & cameraDeviceName,getCameraDeviceInterface_V1_x_cb _hidl_cb)379 Return<void> CameraProvider::getCameraDeviceInterface_V1_x(
380         const hidl_string& cameraDeviceName, getCameraDeviceInterface_V1_x_cb _hidl_cb)  {
381     std::string cameraId, deviceVersion;
382     bool match = matchDeviceName(cameraDeviceName, &deviceVersion, &cameraId);
383     if (!match) {
384         _hidl_cb(Status::ILLEGAL_ARGUMENT, nullptr);
385         return Void();
386     }
387 
388     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) {
394             ALOGE("%s: cannot find camera %s!", __FUNCTION__, cameraId.c_str());
395             status = Status::ILLEGAL_ARGUMENT;
396         } else { // invalid version
397             ALOGE("%s: camera device %s does not support version %s!",
398                     __FUNCTION__, cameraId.c_str(), deviceVersion.c_str());
399             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     sp<android::hardware::camera::device::V1_0::implementation::CameraDevice> device =
412             new android::hardware::camera::device::V1_0::implementation::CameraDevice(
413                     mModule, cameraId, mCameraDeviceNames);
414 
415     if (device == nullptr) {
416         ALOGE("%s: cannot allocate camera device for id %s", __FUNCTION__, cameraId.c_str());
417         _hidl_cb(Status::INTERNAL_ERROR, nullptr);
418         return Void();
419     }
420 
421     if (device->isInitFailed()) {
422         ALOGE("%s: camera device %s init failed!", __FUNCTION__, cameraId.c_str());
423         device = nullptr;
424         _hidl_cb(Status::INTERNAL_ERROR, nullptr);
425         return Void();
426     }
427 
428     _hidl_cb (Status::OK, device);
429     return Void();
430 }
431 
getCameraDeviceInterface_V3_x(const hidl_string & cameraDeviceName,getCameraDeviceInterface_V3_x_cb _hidl_cb)432 Return<void> CameraProvider::getCameraDeviceInterface_V3_x(
433         const hidl_string& cameraDeviceName, getCameraDeviceInterface_V3_x_cb _hidl_cb)  {
434     std::string cameraId, deviceVersion;
435     bool match = matchDeviceName(cameraDeviceName, &deviceVersion, &cameraId);
436     if (!match) {
437         _hidl_cb(Status::ILLEGAL_ARGUMENT, nullptr);
438         return Void();
439     }
440 
441     std::string deviceName(cameraDeviceName.c_str());
442     ssize_t index = mCameraDeviceNames.indexOf(std::make_pair(cameraId, deviceName));
443     if (index == NAME_NOT_FOUND) { // Either an illegal name or a device version mismatch
444         Status status = Status::OK;
445         ssize_t idx = mCameraIds.indexOf(cameraId);
446         if (idx == NAME_NOT_FOUND) {
447             ALOGE("%s: cannot find camera %s!", __FUNCTION__, cameraId.c_str());
448             status = Status::ILLEGAL_ARGUMENT;
449         } else { // invalid version
450             ALOGE("%s: camera device %s does not support version %s!",
451                     __FUNCTION__, cameraId.c_str(), deviceVersion.c_str());
452             status = Status::OPERATION_NOT_SUPPORTED;
453         }
454         _hidl_cb(status, nullptr);
455         return Void();
456     }
457 
458     if (mCameraStatusMap.count(cameraId) == 0 ||
459             mCameraStatusMap[cameraId] != CAMERA_DEVICE_STATUS_PRESENT) {
460         _hidl_cb(Status::ILLEGAL_ARGUMENT, nullptr);
461         return Void();
462     }
463 
464     sp<android::hardware::camera::device::V3_2::implementation::CameraDevice> device =
465             new android::hardware::camera::device::V3_2::implementation::CameraDevice(
466                     mModule, cameraId, mCameraDeviceNames);
467 
468     if (device == nullptr) {
469         ALOGE("%s: cannot allocate camera device for id %s", __FUNCTION__, cameraId.c_str());
470         _hidl_cb(Status::INTERNAL_ERROR, nullptr);
471         return Void();
472     }
473 
474     if (device->isInitFailed()) {
475         ALOGE("%s: camera device %s init failed!", __FUNCTION__, cameraId.c_str());
476         device = nullptr;
477         _hidl_cb(Status::INTERNAL_ERROR, nullptr);
478         return Void();
479     }
480 
481     _hidl_cb (Status::OK, device);
482     return Void();
483 }
484 
HIDL_FETCH_ICameraProvider(const char * name)485 ICameraProvider* HIDL_FETCH_ICameraProvider(const char* name) {
486     if (strcmp(name, kLegacyProviderName) != 0) {
487         return nullptr;
488     }
489     CameraProvider* provider = new CameraProvider();
490     if (provider == nullptr) {
491         ALOGE("%s: cannot allocate camera provider!", __FUNCTION__);
492         return nullptr;
493     }
494     if (provider->isInitFailed()) {
495         ALOGE("%s: camera provider init failed!", __FUNCTION__);
496         delete provider;
497         return nullptr;
498     }
499     return provider;
500 }
501 
502 } // namespace implementation
503 }  // namespace V2_4
504 }  // namespace provider
505 }  // namespace camera
506 }  // namespace hardware
507 }  // namespace android
508