1 /*
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>
20
21 #include <hidl/HidlCameraDeviceUser.h>
22 #include <hidl/AidlCameraDeviceCallbacks.h>
23 #include <hidl/AidlCameraServiceListener.h>
24
25 #include <hidl/HidlTransportSupport.h>
26
27 namespace android {
28 namespace frameworks {
29 namespace cameraservice {
30 namespace service {
31 namespace V2_0 {
32 namespace implementation {
33
34 using frameworks::cameraservice::service::V2_0::implementation::HidlCameraService;
35 using hardware::hidl_vec;
36 using hardware::cameraservice::utils::conversion::convertToHidl;
37 using hardware::cameraservice::utils::conversion::B2HStatus;
38 using hardware::Void;
39
40 using device::V2_0::implementation::H2BCameraDeviceCallbacks;
41 using device::V2_0::implementation::HidlCameraDeviceUser;
42 using service::V2_0::implementation::H2BCameraServiceListener;
43 using HCameraMetadataType = frameworks::cameraservice::common::V2_0::CameraMetadataType;
44 using HVendorTag = frameworks::cameraservice::common::V2_0::VendorTag;
45 using HVendorTagSection = frameworks::cameraservice::common::V2_0::VendorTagSection;
46 using HProviderIdAndVendorTagSections =
47 frameworks::cameraservice::common::V2_0::ProviderIdAndVendorTagSections;
48
49 sp<HidlCameraService> gHidlCameraService;
50
getInstance(android::CameraService * cs)51 sp<HidlCameraService> HidlCameraService::getInstance(android::CameraService *cs) {
52 gHidlCameraService = new HidlCameraService(cs);
53 return gHidlCameraService;
54 }
55
56 Return<void>
getCameraCharacteristics(const hidl_string & cameraId,getCameraCharacteristics_cb _hidl_cb)57 HidlCameraService::getCameraCharacteristics(const hidl_string& cameraId,
58 getCameraCharacteristics_cb _hidl_cb) {
59 android::CameraMetadata cameraMetadata;
60 HStatus status = HStatus::NO_ERROR;
61 binder::Status serviceRet =
62 mAidlICameraService->getCameraCharacteristics(String16(cameraId.c_str()), &cameraMetadata);
63 HCameraMetadata hidlMetadata;
64 if (!serviceRet.isOk()) {
65 switch(serviceRet.serviceSpecificErrorCode()) {
66 // No ERROR_CAMERA_DISCONNECTED since we're in the same process.
67 case hardware::ICameraService::ERROR_ILLEGAL_ARGUMENT:
68 ALOGE("%s: Camera ID %s does not exist!", __FUNCTION__, cameraId.c_str());
69 status = HStatus::ILLEGAL_ARGUMENT;
70 break;
71 default:
72 ALOGE("Get camera characteristics from camera service failed: %s",
73 serviceRet.toString8().string());
74 status = B2HStatus(serviceRet);
75 }
76 _hidl_cb(status, hidlMetadata);
77 return Void();
78 }
79 const camera_metadata_t *rawMetadata = cameraMetadata.getAndLock();
80 convertToHidl(rawMetadata, &hidlMetadata);
81 _hidl_cb(status, hidlMetadata);
82 cameraMetadata.unlock(rawMetadata);
83 return Void();
84 }
85
connectDevice(const sp<HCameraDeviceCallback> & hCallback,const hidl_string & cameraId,connectDevice_cb _hidl_cb)86 Return<void> HidlCameraService::connectDevice(const sp<HCameraDeviceCallback>& hCallback,
87 const hidl_string& cameraId,
88 connectDevice_cb _hidl_cb) {
89 // Here, we first get ICameraDeviceUser from mAidlICameraService, then save
90 // that interface in the newly created HidlCameraDeviceUser impl class.
91 if (mAidlICameraService == nullptr) {
92 _hidl_cb(HStatus::UNKNOWN_ERROR, nullptr);
93 return Void();
94 }
95 sp<hardware::camera2::ICameraDeviceUser> deviceRemote = nullptr;
96 // Create a hardware::camera2::ICameraDeviceCallback object which internally
97 // calls callback functions passed through hCallback.
98 sp<H2BCameraDeviceCallbacks> hybridCallbacks = new H2BCameraDeviceCallbacks(hCallback);
99 if (!hybridCallbacks->initializeLooper()) {
100 ALOGE("Unable to handle callbacks on device, cannot connect");
101 _hidl_cb(HStatus::UNKNOWN_ERROR, nullptr);
102 return Void();
103 }
104 sp<hardware::camera2::ICameraDeviceCallbacks> callbacks = hybridCallbacks;
105 binder::Status serviceRet = mAidlICameraService->connectDevice(
106 callbacks, String16(cameraId.c_str()), String16(""),
107 hardware::ICameraService::USE_CALLING_UID, /*out*/&deviceRemote);
108 HStatus status = HStatus::NO_ERROR;
109 if (!serviceRet.isOk()) {
110 ALOGE("%s: Unable to connect to camera device", __FUNCTION__);
111 status = B2HStatus(serviceRet);
112 _hidl_cb(status, nullptr);
113 return Void();
114 }
115 // Now we create a HidlCameraDeviceUser class, store the deviceRemote in it,
116 // and return that back. All calls on that interface will be forwarded to
117 // the AIDL interface.
118 sp<HidlCameraDeviceUser> hDeviceRemote = new HidlCameraDeviceUser(deviceRemote);
119 if (!hDeviceRemote->initStatus()) {
120 ALOGE("%s: Unable to initialize camera device HIDL wrapper", __FUNCTION__);
121 _hidl_cb(HStatus::UNKNOWN_ERROR, nullptr);
122 return Void();
123 }
124 hybridCallbacks->setCaptureResultMetadataQueue(hDeviceRemote->getCaptureResultMetadataQueue());
125 _hidl_cb(status, hDeviceRemote);
126 return Void();
127 }
128
addToListenerCacheLocked(sp<HCameraServiceListener> hListener,sp<hardware::ICameraServiceListener> csListener)129 void HidlCameraService::addToListenerCacheLocked(sp<HCameraServiceListener> hListener,
130 sp<hardware::ICameraServiceListener> csListener) {
131 mListeners.emplace_back(std::make_pair(hListener, csListener));
132 }
133
134 sp<hardware::ICameraServiceListener>
searchListenerCacheLocked(sp<HCameraServiceListener> hListener,bool shouldRemove)135 HidlCameraService::searchListenerCacheLocked(sp<HCameraServiceListener> hListener,
136 bool shouldRemove) {
137 // Go through the mListeners list and compare the listener with the HIDL
138 // listener registered.
139 auto it = mListeners.begin();
140 sp<ICameraServiceListener> csListener = nullptr;
141 for (;it != mListeners.end(); it++) {
142 if (hardware::interfacesEqual(it->first, hListener)) {
143 break;
144 }
145 }
146 if (it != mListeners.end()) {
147 csListener = it->second;
148 if (shouldRemove) {
149 mListeners.erase(it);
150 }
151 }
152 return csListener;
153 }
154
addListener(const sp<HCameraServiceListener> & hCsListener,addListener_cb _hidl_cb)155 Return<void> HidlCameraService::addListener(const sp<HCameraServiceListener>& hCsListener,
156 addListener_cb _hidl_cb) {
157 if (mAidlICameraService == nullptr) {
158 _hidl_cb(HStatus::UNKNOWN_ERROR, {});
159 return Void();
160 }
161 if (hCsListener == nullptr) {
162 ALOGE("%s listener must not be NULL", __FUNCTION__);
163 _hidl_cb(HStatus::ILLEGAL_ARGUMENT, {});
164 return Void();
165 }
166 sp<hardware::ICameraServiceListener> csListener = nullptr;
167 // Check the cache for previously registered callbacks
168 {
169 Mutex::Autolock l(mListenerListLock);
170 csListener = searchListenerCacheLocked(hCsListener);
171 if (csListener == nullptr) {
172 // Wrap an hCsListener with AidlCameraServiceListener and pass it to
173 // CameraService.
174 csListener = new H2BCameraServiceListener(hCsListener);
175 // Add to cache
176 addToListenerCacheLocked(hCsListener, csListener);
177 } else {
178 ALOGE("%s: Trying to add a listener %p already registered",
179 __FUNCTION__, hCsListener.get());
180 _hidl_cb(HStatus::ILLEGAL_ARGUMENT, {});
181 return Void();
182 }
183 }
184 std::vector<hardware::CameraStatus> cameraStatusAndIds{};
185 binder::Status serviceRet =
186 mAidlICameraService->addListenerHelper(csListener, &cameraStatusAndIds, true);
187 HStatus status = HStatus::NO_ERROR;
188 if (!serviceRet.isOk()) {
189 ALOGE("%s: Unable to add camera device status listener", __FUNCTION__);
190 status = B2HStatus(serviceRet);
191 _hidl_cb(status, {});
192 return Void();
193 }
194 hidl_vec<HCameraStatusAndId> hCameraStatusAndIds;
195 //Convert cameraStatusAndIds to HIDL and call callback
196 convertToHidl(cameraStatusAndIds, &hCameraStatusAndIds);
197 _hidl_cb(status, hCameraStatusAndIds);
198 return Void();
199 }
200
removeListener(const sp<HCameraServiceListener> & hCsListener)201 Return<HStatus> HidlCameraService::removeListener(const sp<HCameraServiceListener>& hCsListener) {
202 if (hCsListener == nullptr) {
203 ALOGE("%s listener must not be NULL", __FUNCTION__);
204 return HStatus::ILLEGAL_ARGUMENT;
205 }
206 sp<ICameraServiceListener> csListener = nullptr;
207 {
208 Mutex::Autolock l(mListenerListLock);
209 csListener = searchListenerCacheLocked(hCsListener, /*removeIfFound*/true);
210 }
211 if (csListener != nullptr) {
212 mAidlICameraService->removeListener(csListener);
213 } else {
214 ALOGE("%s Removing unregistered listener %p", __FUNCTION__, hCsListener.get());
215 return HStatus::ILLEGAL_ARGUMENT;
216 }
217 return HStatus::NO_ERROR;
218 }
219
getCameraVendorTagSections(getCameraVendorTagSections_cb _hidl_cb)220 Return<void> HidlCameraService::getCameraVendorTagSections(getCameraVendorTagSections_cb _hidl_cb) {
221 sp<VendorTagDescriptorCache> gCache = VendorTagDescriptorCache::getGlobalVendorTagCache();
222 if (gCache == nullptr) {
223 _hidl_cb(HStatus::UNKNOWN_ERROR, {});
224 return Void();
225 }
226 const std::unordered_map<metadata_vendor_id_t, sp<android::VendorTagDescriptor>>
227 &vendorIdsAndTagDescs = gCache->getVendorIdsAndTagDescriptors();
228 if (vendorIdsAndTagDescs.size() == 0) {
229 _hidl_cb(HStatus::UNKNOWN_ERROR, {});
230 return Void();
231 }
232
233 hidl_vec<HProviderIdAndVendorTagSections> hTagIdsAndVendorTagSections;
234 hTagIdsAndVendorTagSections.resize(vendorIdsAndTagDescs.size());
235 size_t j = 0;
236 for (auto &vendorIdAndTagDescs : vendorIdsAndTagDescs) {
237 hidl_vec<HVendorTagSection> hVendorTagSections;
238 sp<VendorTagDescriptor> desc = vendorIdAndTagDescs.second;
239 const SortedVector<String8>* sectionNames = desc->getAllSectionNames();
240 size_t numSections = sectionNames->size();
241 std::vector<std::vector<HVendorTag>> tagsBySection(numSections);
242 int tagCount = desc->getTagCount();
243 std::vector<uint32_t> tags(tagCount);
244 desc->getTagArray(tags.data());
245 for (int i = 0; i < tagCount; i++) {
246 HVendorTag vt;
247 vt.tagId = tags[i];
248 vt.tagName = desc->getTagName(tags[i]);
249 vt.tagType = (HCameraMetadataType) desc->getTagType(tags[i]);
250 ssize_t sectionIdx = desc->getSectionIndex(tags[i]);
251 tagsBySection[sectionIdx].push_back(vt);
252 }
253 hVendorTagSections.resize(numSections);
254 for (size_t s = 0; s < numSections; s++) {
255 hVendorTagSections[s].sectionName = (*sectionNames)[s].string();
256 hVendorTagSections[s].tags = tagsBySection[s];
257 }
258 HProviderIdAndVendorTagSections &hProviderIdAndVendorTagSections =
259 hTagIdsAndVendorTagSections[j];
260 hProviderIdAndVendorTagSections.providerId = vendorIdAndTagDescs.first;
261 hProviderIdAndVendorTagSections.vendorTagSections = std::move(hVendorTagSections);
262 j++;
263 }
264 _hidl_cb(HStatus::NO_ERROR, hTagIdsAndVendorTagSections);
265 return Void();
266 }
267
268 } // implementation
269 } // V2_0
270 } // service
271 } // cameraservice
272 } // frameworks
273 } // android
274
275