blob: f34f903bb221194923250451b8bb5812de0fa687 [file] [log] [blame]
Jayant Chowdharybe543d42018-08-15 13:16:14 -07001/*
2 * Copyright (C) 2018 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#include <hidl/Convert.h>
18
19#include <hidl/HidlCameraService.h>
Jayant Chowdhary94f79a92018-08-15 13:57:17 -070020#include <hidl/AidlCameraServiceListener.h>
Jayant Chowdharybe543d42018-08-15 13:16:14 -070021
22#include <hidl/HidlTransportSupport.h>
23
24namespace android {
25namespace frameworks {
26namespace cameraservice {
27namespace service {
28namespace V2_0 {
29namespace implementation {
30
31using frameworks::cameraservice::service::V2_0::implementation::HidlCameraService;
32using hardware::hidl_vec;
33using hardware::cameraservice::utils::conversion::convertToHidl;
34using hardware::cameraservice::utils::conversion::B2HStatus;
35using hardware::Void;
36
Jayant Chowdhary94f79a92018-08-15 13:57:17 -070037using service::V2_0::implementation::H2BCameraServiceListener;
Jayant Chowdharybe543d42018-08-15 13:16:14 -070038using HCameraMetadataType = android::frameworks::cameraservice::common::V2_0::CameraMetadataType;
39using HVendorTag = android::frameworks::cameraservice::common::V2_0::VendorTag;
40using HVendorTagSection = android::frameworks::cameraservice::common::V2_0::VendorTagSection;
41
42sp<HidlCameraService> gHidlCameraService;
43
44sp<HidlCameraService> HidlCameraService::getInstance(android::CameraService *cs) {
45 gHidlCameraService = new HidlCameraService(cs);
46 return gHidlCameraService;
47}
48
49Return<void>
50HidlCameraService::getCameraCharacteristics(const hidl_string& cameraId,
51 getCameraCharacteristics_cb _hidl_cb) {
52 android::CameraMetadata cameraMetadata;
53 HStatus status = HStatus::NO_ERROR;
54 binder::Status serviceRet =
55 mAidlICameraService->getCameraCharacteristics(String16(cameraId.c_str()), &cameraMetadata);
56 HCameraMetadata hidlMetadata;
57 if (!serviceRet.isOk()) {
58 switch(serviceRet.serviceSpecificErrorCode()) {
59 // No ERROR_CAMERA_DISCONNECTED since we're in the same process.
60 case hardware::ICameraService::ERROR_ILLEGAL_ARGUMENT:
61 ALOGE("%s: Camera ID %s does not exist!", __FUNCTION__, cameraId.c_str());
62 status = HStatus::ILLEGAL_ARGUMENT;
63 break;
64 default:
65 ALOGE("Get camera characteristics from camera service failed: %s",
66 serviceRet.toString8().string());
67 status = B2HStatus(serviceRet);
68 }
69 _hidl_cb(status, hidlMetadata);
70 return Void();
71 }
72 const camera_metadata_t *rawMetadata = cameraMetadata.getAndLock();
73 convertToHidl(rawMetadata, &hidlMetadata);
74 _hidl_cb(status, hidlMetadata);
75 cameraMetadata.unlock(rawMetadata);
76 return Void();
77}
78
79Return<void> HidlCameraService::connectDevice(const sp<HCameraDeviceCallback>& hCallback,
80 const hidl_string& cameraId,
81 connectDevice_cb _hidl_cb) {
82 // To silence Wunused-parameter.
83 (void)hCallback;
84 (void)cameraId;
85 (void)_hidl_cb;
86
87 return Void();
88}
89
Jayant Chowdhary94f79a92018-08-15 13:57:17 -070090void HidlCameraService::addToListenerCacheLocked(sp<HCameraServiceListener> hListener,
91 sp<hardware::ICameraServiceListener> csListener) {
92 mListeners.emplace_back(std::make_pair(hListener, csListener));
93}
94
95sp<hardware::ICameraServiceListener>
96HidlCameraService::searchListenerCacheLocked(sp<HCameraServiceListener> hListener,
97 bool shouldRemove) {
98 // Go through the mListeners list and compare the listener with the HIDL
99 // listener registered.
100 auto it = mListeners.begin();
101 sp<ICameraServiceListener> csListener = nullptr;
102 for (;it != mListeners.end(); it++) {
103 if (hardware::interfacesEqual(it->first, hListener)) {
104 break;
105 }
106 }
107 if (it != mListeners.end()) {
108 csListener = it->second;
109 if (shouldRemove) {
110 mListeners.erase(it);
111 }
112 }
113 return csListener;
114}
115
Jayant Chowdharybe543d42018-08-15 13:16:14 -0700116Return<void> HidlCameraService::addListener(const sp<HCameraServiceListener>& hCsListener,
117 addListener_cb _hidl_cb) {
Jayant Chowdhary94f79a92018-08-15 13:57:17 -0700118 if (mAidlICameraService == nullptr) {
119 _hidl_cb(HStatus::UNKNOWN_ERROR, {});
120 return Void();
121 }
122 if (hCsListener == nullptr) {
123 ALOGE("%s listener must not be NULL", __FUNCTION__);
124 _hidl_cb(HStatus::ILLEGAL_ARGUMENT, {});
125 return Void();
126 }
127 sp<hardware::ICameraServiceListener> csListener = nullptr;
128 // Check the cache for previously registered callbacks
129 {
130 Mutex::Autolock l(mListenerListLock);
131 csListener = searchListenerCacheLocked(hCsListener);
132 if (csListener == nullptr) {
133 // Wrap an hCsListener with AidlCameraServiceListener and pass it to
134 // CameraService.
135 csListener = new H2BCameraServiceListener(hCsListener);
136 // Add to cache
137 addToListenerCacheLocked(hCsListener, csListener);
138 } else {
139 ALOGE("%s: Trying to add a listener %p already registered",
140 __FUNCTION__, hCsListener.get());
141 _hidl_cb(HStatus::ILLEGAL_ARGUMENT, {});
142 return Void();
143 }
144 }
145 std::vector<hardware::CameraStatus> cameraStatusAndIds{};
146 binder::Status serviceRet = mAidlICameraService->addListener(csListener, &cameraStatusAndIds);
147 HStatus status = HStatus::NO_ERROR;
148 if (!serviceRet.isOk()) {
149 ALOGE("%s: Unable to add camera device status listener", __FUNCTION__);
150 status = B2HStatus(serviceRet);
151 _hidl_cb(status, {});
152 return Void();
153 }
154 hidl_vec<HCameraStatusAndId> hCameraStatusAndIds;
155 //Convert cameraStatusAndIds to HIDL and call callback
156 convertToHidl(cameraStatusAndIds, &hCameraStatusAndIds);
157 _hidl_cb(status, hCameraStatusAndIds);
Jayant Chowdharybe543d42018-08-15 13:16:14 -0700158 return Void();
159}
160
161Return<HStatus> HidlCameraService::removeListener(const sp<HCameraServiceListener>& hCsListener) {
162 if (hCsListener == nullptr) {
163 ALOGE("%s listener must not be NULL", __FUNCTION__);
164 return HStatus::ILLEGAL_ARGUMENT;
165 }
Jayant Chowdhary94f79a92018-08-15 13:57:17 -0700166 sp<ICameraServiceListener> csListener = nullptr;
167 {
168 Mutex::Autolock l(mListenerListLock);
169 csListener = searchListenerCacheLocked(hCsListener, /*removeIfFound*/true);
170 }
171 if (csListener != nullptr) {
172 mAidlICameraService->removeListener(csListener);
173 } else {
174 ALOGE("%s Removing unregistered listener %p", __FUNCTION__, hCsListener.get());
175 return HStatus::ILLEGAL_ARGUMENT;
176 }
Jayant Chowdharybe543d42018-08-15 13:16:14 -0700177 return HStatus::NO_ERROR;
178}
179
180Return<void> HidlCameraService::getCameraVendorTagSections(getCameraVendorTagSections_cb _hidl_cb) {
181 hidl_vec<HVendorTagSection> hVendorTagSections;
182 // TODO: Could this be just created on the stack since we don't set it to
183 // global cache or anything ?
184 HStatus hStatus = HStatus::NO_ERROR;
185 sp<VendorTagDescriptor> desc = new VendorTagDescriptor();
186 binder::Status serviceRet = mAidlICameraService->getCameraVendorTagDescriptor(desc.get());
187
188 if (!serviceRet.isOk()) {
189 ALOGE("%s: Failed to get VendorTagDescriptor", __FUNCTION__);
190 _hidl_cb(B2HStatus(serviceRet), hVendorTagSections);
191 return Void();
192 }
193
194 const SortedVector<String8>* sectionNames = desc->getAllSectionNames();
195 size_t numSections = sectionNames->size();
196 std::vector<std::vector<HVendorTag>> tagsBySection(numSections);
197 int tagCount = desc->getTagCount();
198 std::vector<uint32_t> tags(tagCount);
199 desc->getTagArray(tags.data());
200 for (int i = 0; i < tagCount; i++) {
201 HVendorTag vt;
202 vt.tagId = tags[i];
203 vt.tagName = desc->getTagName(tags[i]);
204 vt.tagType = (HCameraMetadataType) desc->getTagType(tags[i]);
205 ssize_t sectionIdx = desc->getSectionIndex(tags[i]);
206 tagsBySection[sectionIdx].push_back(vt);
207 }
208 hVendorTagSections.resize(numSections);
209 for (size_t s = 0; s < numSections; s++) {
210 hVendorTagSections[s].sectionName = (*sectionNames)[s].string();
211 hVendorTagSections[s].tags = tagsBySection[s];
212 }
213 _hidl_cb(hStatus, hVendorTagSections);
214 return Void();
215}
216
217} // implementation
218} // V2_0
219} // service
220} // cameraservice
221} // frameworks
222} // android
223