blob: 7d1b3cf0ad0a068b273c23842cbd807ccb72f3f8 [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 Chowdhary0c947272018-08-15 14:42:04 -070020
21#include <hidl/HidlCameraDeviceUser.h>
22#include <hidl/AidlCameraDeviceCallbacks.h>
Jayant Chowdhary94f79a92018-08-15 13:57:17 -070023#include <hidl/AidlCameraServiceListener.h>
Jayant Chowdharybe543d42018-08-15 13:16:14 -070024
25#include <hidl/HidlTransportSupport.h>
26
27namespace android {
28namespace frameworks {
29namespace cameraservice {
30namespace service {
31namespace V2_0 {
32namespace implementation {
33
34using frameworks::cameraservice::service::V2_0::implementation::HidlCameraService;
35using hardware::hidl_vec;
36using hardware::cameraservice::utils::conversion::convertToHidl;
37using hardware::cameraservice::utils::conversion::B2HStatus;
38using hardware::Void;
39
Jayant Chowdhary0c947272018-08-15 14:42:04 -070040using device::V2_0::implementation::H2BCameraDeviceCallbacks;
Shuzhen Wang316781a2020-08-18 18:11:01 -070041using device::V2_1::implementation::HidlCameraDeviceUser;
Jayant Chowdhary94f79a92018-08-15 13:57:17 -070042using service::V2_0::implementation::H2BCameraServiceListener;
Jayant Chowdhary8cf92922018-11-19 15:45:17 -080043using HCameraMetadataType = frameworks::cameraservice::common::V2_0::CameraMetadataType;
44using HVendorTag = frameworks::cameraservice::common::V2_0::VendorTag;
45using HVendorTagSection = frameworks::cameraservice::common::V2_0::VendorTagSection;
46using HProviderIdAndVendorTagSections =
47 frameworks::cameraservice::common::V2_0::ProviderIdAndVendorTagSections;
Jayant Chowdharybe543d42018-08-15 13:16:14 -070048
49sp<HidlCameraService> gHidlCameraService;
50
51sp<HidlCameraService> HidlCameraService::getInstance(android::CameraService *cs) {
52 gHidlCameraService = new HidlCameraService(cs);
53 return gHidlCameraService;
54}
55
56Return<void>
57HidlCameraService::getCameraCharacteristics(const hidl_string& cameraId,
58 getCameraCharacteristics_cb _hidl_cb) {
59 android::CameraMetadata cameraMetadata;
60 HStatus status = HStatus::NO_ERROR;
61 binder::Status serviceRet =
Shuzhen Wangd4abdf72021-05-28 11:22:50 -070062 mAidlICameraService->getCameraCharacteristics(String16(cameraId.c_str()),
63 /*targetSdkVersion*/__ANDROID_API_FUTURE__, &cameraMetadata);
Jayant Chowdharybe543d42018-08-15 13:16:14 -070064 HCameraMetadata hidlMetadata;
65 if (!serviceRet.isOk()) {
66 switch(serviceRet.serviceSpecificErrorCode()) {
67 // No ERROR_CAMERA_DISCONNECTED since we're in the same process.
68 case hardware::ICameraService::ERROR_ILLEGAL_ARGUMENT:
69 ALOGE("%s: Camera ID %s does not exist!", __FUNCTION__, cameraId.c_str());
70 status = HStatus::ILLEGAL_ARGUMENT;
71 break;
72 default:
73 ALOGE("Get camera characteristics from camera service failed: %s",
74 serviceRet.toString8().string());
75 status = B2HStatus(serviceRet);
76 }
77 _hidl_cb(status, hidlMetadata);
78 return Void();
79 }
80 const camera_metadata_t *rawMetadata = cameraMetadata.getAndLock();
81 convertToHidl(rawMetadata, &hidlMetadata);
82 _hidl_cb(status, hidlMetadata);
83 cameraMetadata.unlock(rawMetadata);
84 return Void();
85}
86
87Return<void> HidlCameraService::connectDevice(const sp<HCameraDeviceCallback>& hCallback,
88 const hidl_string& cameraId,
89 connectDevice_cb _hidl_cb) {
Jayant Chowdhary0c947272018-08-15 14:42:04 -070090 // Here, we first get ICameraDeviceUser from mAidlICameraService, then save
91 // that interface in the newly created HidlCameraDeviceUser impl class.
92 if (mAidlICameraService == nullptr) {
93 _hidl_cb(HStatus::UNKNOWN_ERROR, nullptr);
94 return Void();
95 }
96 sp<hardware::camera2::ICameraDeviceUser> deviceRemote = nullptr;
97 // Create a hardware::camera2::ICameraDeviceCallback object which internally
98 // calls callback functions passed through hCallback.
99 sp<H2BCameraDeviceCallbacks> hybridCallbacks = new H2BCameraDeviceCallbacks(hCallback);
100 if (!hybridCallbacks->initializeLooper()) {
101 ALOGE("Unable to handle callbacks on device, cannot connect");
102 _hidl_cb(HStatus::UNKNOWN_ERROR, nullptr);
103 return Void();
104 }
105 sp<hardware::camera2::ICameraDeviceCallbacks> callbacks = hybridCallbacks;
106 binder::Status serviceRet = mAidlICameraService->connectDevice(
Jooyung Han3f9a3b42020-01-23 12:27:18 +0900107 callbacks, String16(cameraId.c_str()), String16(""), {},
Shuzhen Wangd4abdf72021-05-28 11:22:50 -0700108 hardware::ICameraService::USE_CALLING_UID, 0/*oomScoreOffset*/,
109 /*targetSdkVersion*/__ANDROID_API_FUTURE__, /*out*/&deviceRemote);
Jayant Chowdhary0c947272018-08-15 14:42:04 -0700110 HStatus status = HStatus::NO_ERROR;
111 if (!serviceRet.isOk()) {
112 ALOGE("%s: Unable to connect to camera device", __FUNCTION__);
113 status = B2HStatus(serviceRet);
114 _hidl_cb(status, nullptr);
115 return Void();
116 }
117 // Now we create a HidlCameraDeviceUser class, store the deviceRemote in it,
118 // and return that back. All calls on that interface will be forwarded to
119 // the AIDL interface.
120 sp<HidlCameraDeviceUser> hDeviceRemote = new HidlCameraDeviceUser(deviceRemote);
121 if (!hDeviceRemote->initStatus()) {
122 ALOGE("%s: Unable to initialize camera device HIDL wrapper", __FUNCTION__);
123 _hidl_cb(HStatus::UNKNOWN_ERROR, nullptr);
124 return Void();
125 }
126 hybridCallbacks->setCaptureResultMetadataQueue(hDeviceRemote->getCaptureResultMetadataQueue());
127 _hidl_cb(status, hDeviceRemote);
Jayant Chowdharybe543d42018-08-15 13:16:14 -0700128 return Void();
129}
130
Jayant Chowdhary94f79a92018-08-15 13:57:17 -0700131void HidlCameraService::addToListenerCacheLocked(sp<HCameraServiceListener> hListener,
132 sp<hardware::ICameraServiceListener> csListener) {
133 mListeners.emplace_back(std::make_pair(hListener, csListener));
134}
135
136sp<hardware::ICameraServiceListener>
137HidlCameraService::searchListenerCacheLocked(sp<HCameraServiceListener> hListener,
138 bool shouldRemove) {
139 // Go through the mListeners list and compare the listener with the HIDL
140 // listener registered.
141 auto it = mListeners.begin();
142 sp<ICameraServiceListener> csListener = nullptr;
143 for (;it != mListeners.end(); it++) {
144 if (hardware::interfacesEqual(it->first, hListener)) {
145 break;
146 }
147 }
148 if (it != mListeners.end()) {
149 csListener = it->second;
150 if (shouldRemove) {
151 mListeners.erase(it);
152 }
153 }
154 return csListener;
155}
156
Jayant Chowdharybe543d42018-08-15 13:16:14 -0700157Return<void> HidlCameraService::addListener(const sp<HCameraServiceListener>& hCsListener,
158 addListener_cb _hidl_cb) {
Shuzhen Wang4fa28d22020-01-23 15:57:25 -0800159 std::vector<hardware::CameraStatus> cameraStatusAndIds{};
160 HStatus status = addListenerInternal<HCameraServiceListener>(
161 hCsListener, &cameraStatusAndIds);
162 if (status != HStatus::NO_ERROR) {
163 _hidl_cb(status, {});
Jayant Chowdhary94f79a92018-08-15 13:57:17 -0700164 return Void();
165 }
Shuzhen Wang4fa28d22020-01-23 15:57:25 -0800166
167 hidl_vec<HCameraStatusAndId> hCameraStatusAndIds;
168 //Convert cameraStatusAndIds to HIDL and call callback
169 convertToHidl(cameraStatusAndIds, &hCameraStatusAndIds);
170 _hidl_cb(status, hCameraStatusAndIds);
171
172 return Void();
173}
174
175Return<void> HidlCameraService::addListener_2_1(const sp<HCameraServiceListener2_1>& hCsListener,
176 addListener_2_1_cb _hidl_cb) {
177 std::vector<hardware::CameraStatus> cameraStatusAndIds{};
178 HStatus status = addListenerInternal<HCameraServiceListener2_1>(
179 hCsListener, &cameraStatusAndIds);
180 if (status != HStatus::NO_ERROR) {
181 _hidl_cb(status, {});
Jayant Chowdhary94f79a92018-08-15 13:57:17 -0700182 return Void();
183 }
Shuzhen Wang4fa28d22020-01-23 15:57:25 -0800184
185 hidl_vec<frameworks::cameraservice::service::V2_1::CameraStatusAndId> hCameraStatusAndIds;
186 //Convert cameraStatusAndIds to HIDL and call callback
187 convertToHidl(cameraStatusAndIds, &hCameraStatusAndIds);
188 _hidl_cb(status, hCameraStatusAndIds);
189
190 return Void();
191}
192
193template<class T>
194HStatus HidlCameraService::addListenerInternal(const sp<T>& hCsListener,
195 std::vector<hardware::CameraStatus>* cameraStatusAndIds) {
196 if (mAidlICameraService == nullptr) {
197 return HStatus::UNKNOWN_ERROR;
198 }
199 if (hCsListener == nullptr || cameraStatusAndIds == nullptr) {
200 ALOGE("%s listener and cameraStatusAndIds must not be NULL", __FUNCTION__);
201 return HStatus::ILLEGAL_ARGUMENT;
202 }
Jayant Chowdhary94f79a92018-08-15 13:57:17 -0700203 sp<hardware::ICameraServiceListener> csListener = nullptr;
204 // Check the cache for previously registered callbacks
205 {
206 Mutex::Autolock l(mListenerListLock);
207 csListener = searchListenerCacheLocked(hCsListener);
208 if (csListener == nullptr) {
209 // Wrap an hCsListener with AidlCameraServiceListener and pass it to
210 // CameraService.
211 csListener = new H2BCameraServiceListener(hCsListener);
212 // Add to cache
213 addToListenerCacheLocked(hCsListener, csListener);
214 } else {
215 ALOGE("%s: Trying to add a listener %p already registered",
216 __FUNCTION__, hCsListener.get());
Shuzhen Wang4fa28d22020-01-23 15:57:25 -0800217 return HStatus::ILLEGAL_ARGUMENT;
Jayant Chowdhary94f79a92018-08-15 13:57:17 -0700218 }
219 }
Jayant Chowdharyf949ddd2019-01-29 14:34:11 -0800220 binder::Status serviceRet =
Shuzhen Wang4fa28d22020-01-23 15:57:25 -0800221 mAidlICameraService->addListenerHelper(csListener, cameraStatusAndIds, true);
Jayant Chowdhary94f79a92018-08-15 13:57:17 -0700222 HStatus status = HStatus::NO_ERROR;
223 if (!serviceRet.isOk()) {
Shuzhen Wang4fa28d22020-01-23 15:57:25 -0800224 ALOGE("%s: Unable to add camera device status listener", __FUNCTION__);
225 status = B2HStatus(serviceRet);
226 return status;
Jayant Chowdhary94f79a92018-08-15 13:57:17 -0700227 }
Shuzhen Wang4fa28d22020-01-23 15:57:25 -0800228 cameraStatusAndIds->erase(std::remove_if(cameraStatusAndIds->begin(), cameraStatusAndIds->end(),
Jayant Chowdhary90e63692019-10-25 14:13:01 -0700229 [this](const hardware::CameraStatus& s) {
Shuzhen Wang4fa28d22020-01-23 15:57:25 -0800230 bool supportsHAL3 = false;
231 binder::Status sRet =
Jayant Chowdhary90e63692019-10-25 14:13:01 -0700232 mAidlICameraService->supportsCameraApi(String16(s.cameraId),
233 hardware::ICameraService::API_VERSION_2, &supportsHAL3);
Shuzhen Wang4fa28d22020-01-23 15:57:25 -0800234 return !sRet.isOk() || !supportsHAL3;
235 }), cameraStatusAndIds->end());
236
237 return HStatus::NO_ERROR;
Jayant Chowdharybe543d42018-08-15 13:16:14 -0700238}
239
240Return<HStatus> HidlCameraService::removeListener(const sp<HCameraServiceListener>& hCsListener) {
241 if (hCsListener == nullptr) {
242 ALOGE("%s listener must not be NULL", __FUNCTION__);
243 return HStatus::ILLEGAL_ARGUMENT;
244 }
Jayant Chowdhary94f79a92018-08-15 13:57:17 -0700245 sp<ICameraServiceListener> csListener = nullptr;
246 {
247 Mutex::Autolock l(mListenerListLock);
248 csListener = searchListenerCacheLocked(hCsListener, /*removeIfFound*/true);
249 }
250 if (csListener != nullptr) {
251 mAidlICameraService->removeListener(csListener);
252 } else {
253 ALOGE("%s Removing unregistered listener %p", __FUNCTION__, hCsListener.get());
254 return HStatus::ILLEGAL_ARGUMENT;
255 }
Jayant Chowdharybe543d42018-08-15 13:16:14 -0700256 return HStatus::NO_ERROR;
257}
258
259Return<void> HidlCameraService::getCameraVendorTagSections(getCameraVendorTagSections_cb _hidl_cb) {
Jayant Chowdhary8cf92922018-11-19 15:45:17 -0800260 sp<VendorTagDescriptorCache> gCache = VendorTagDescriptorCache::getGlobalVendorTagCache();
261 if (gCache == nullptr) {
262 _hidl_cb(HStatus::UNKNOWN_ERROR, {});
263 return Void();
264 }
265 const std::unordered_map<metadata_vendor_id_t, sp<android::VendorTagDescriptor>>
266 &vendorIdsAndTagDescs = gCache->getVendorIdsAndTagDescriptors();
267 if (vendorIdsAndTagDescs.size() == 0) {
268 _hidl_cb(HStatus::UNKNOWN_ERROR, {});
Jayant Chowdharybe543d42018-08-15 13:16:14 -0700269 return Void();
270 }
271
Jayant Chowdhary8cf92922018-11-19 15:45:17 -0800272 hidl_vec<HProviderIdAndVendorTagSections> hTagIdsAndVendorTagSections;
273 hTagIdsAndVendorTagSections.resize(vendorIdsAndTagDescs.size());
274 size_t j = 0;
275 for (auto &vendorIdAndTagDescs : vendorIdsAndTagDescs) {
276 hidl_vec<HVendorTagSection> hVendorTagSections;
277 sp<VendorTagDescriptor> desc = vendorIdAndTagDescs.second;
278 const SortedVector<String8>* sectionNames = desc->getAllSectionNames();
279 size_t numSections = sectionNames->size();
280 std::vector<std::vector<HVendorTag>> tagsBySection(numSections);
281 int tagCount = desc->getTagCount();
282 std::vector<uint32_t> tags(tagCount);
283 desc->getTagArray(tags.data());
284 for (int i = 0; i < tagCount; i++) {
285 HVendorTag vt;
286 vt.tagId = tags[i];
287 vt.tagName = desc->getTagName(tags[i]);
288 vt.tagType = (HCameraMetadataType) desc->getTagType(tags[i]);
289 ssize_t sectionIdx = desc->getSectionIndex(tags[i]);
290 tagsBySection[sectionIdx].push_back(vt);
291 }
292 hVendorTagSections.resize(numSections);
293 for (size_t s = 0; s < numSections; s++) {
294 hVendorTagSections[s].sectionName = (*sectionNames)[s].string();
295 hVendorTagSections[s].tags = tagsBySection[s];
296 }
297 HProviderIdAndVendorTagSections &hProviderIdAndVendorTagSections =
298 hTagIdsAndVendorTagSections[j];
299 hProviderIdAndVendorTagSections.providerId = vendorIdAndTagDescs.first;
300 hProviderIdAndVendorTagSections.vendorTagSections = std::move(hVendorTagSections);
301 j++;
Jayant Chowdharybe543d42018-08-15 13:16:14 -0700302 }
Jayant Chowdhary8cf92922018-11-19 15:45:17 -0800303 _hidl_cb(HStatus::NO_ERROR, hTagIdsAndVendorTagSections);
Jayant Chowdharybe543d42018-08-15 13:16:14 -0700304 return Void();
305}
306
307} // implementation
308} // V2_0
309} // service
310} // cameraservice
311} // frameworks
312} // android
313