blob: 65a03001a3b89bb4828c36d6c443a58fa50c5bdc [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
Jayant Chowdhary2f686522022-05-09 14:52:16 +000017#include <android-base/properties.h>
Jayant Chowdharybe543d42018-08-15 13:16:14 -070018
Jayant Chowdhary0c947272018-08-15 14:42:04 -070019#include <hidl/AidlCameraDeviceCallbacks.h>
Jayant Chowdhary94f79a92018-08-15 13:57:17 -070020#include <hidl/AidlCameraServiceListener.h>
Jayant Chowdhary2f686522022-05-09 14:52:16 +000021#include <hidl/HidlCameraService.h>
22#include <hidl/HidlCameraDeviceUser.h>
23#include <hidl/Utils.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;
Jayant Chowdhary2f686522022-05-09 14:52:16 +000037using hardware::cameraservice::utils::conversion::filterVndkKeys;
Jayant Chowdharybe543d42018-08-15 13:16:14 -070038using hardware::cameraservice::utils::conversion::B2HStatus;
39using hardware::Void;
40
Jayant Chowdhary0c947272018-08-15 14:42:04 -070041using device::V2_0::implementation::H2BCameraDeviceCallbacks;
Shuzhen Wang316781a2020-08-18 18:11:01 -070042using device::V2_1::implementation::HidlCameraDeviceUser;
Jayant Chowdhary94f79a92018-08-15 13:57:17 -070043using service::V2_0::implementation::H2BCameraServiceListener;
Jayant Chowdhary8cf92922018-11-19 15:45:17 -080044using HCameraMetadataType = frameworks::cameraservice::common::V2_0::CameraMetadataType;
45using HVendorTag = frameworks::cameraservice::common::V2_0::VendorTag;
46using HVendorTagSection = frameworks::cameraservice::common::V2_0::VendorTagSection;
47using HProviderIdAndVendorTagSections =
48 frameworks::cameraservice::common::V2_0::ProviderIdAndVendorTagSections;
Jayant Chowdharybe543d42018-08-15 13:16:14 -070049
50sp<HidlCameraService> gHidlCameraService;
51
52sp<HidlCameraService> HidlCameraService::getInstance(android::CameraService *cs) {
53 gHidlCameraService = new HidlCameraService(cs);
54 return gHidlCameraService;
55}
56
Jayant Chowdhary2f686522022-05-09 14:52:16 +000057HidlCameraService::HidlCameraService(android::CameraService *cs) : mAidlICameraService(cs) {
58 mVndkVersion = base::GetIntProperty("ro.vndk.version", __ANDROID_API_FUTURE__);
59};
60
Jayant Chowdharybe543d42018-08-15 13:16:14 -070061Return<void>
62HidlCameraService::getCameraCharacteristics(const hidl_string& cameraId,
63 getCameraCharacteristics_cb _hidl_cb) {
64 android::CameraMetadata cameraMetadata;
65 HStatus status = HStatus::NO_ERROR;
66 binder::Status serviceRet =
Shuzhen Wangd4abdf72021-05-28 11:22:50 -070067 mAidlICameraService->getCameraCharacteristics(String16(cameraId.c_str()),
68 /*targetSdkVersion*/__ANDROID_API_FUTURE__, &cameraMetadata);
Jayant Chowdharybe543d42018-08-15 13:16:14 -070069 HCameraMetadata hidlMetadata;
70 if (!serviceRet.isOk()) {
71 switch(serviceRet.serviceSpecificErrorCode()) {
72 // No ERROR_CAMERA_DISCONNECTED since we're in the same process.
73 case hardware::ICameraService::ERROR_ILLEGAL_ARGUMENT:
74 ALOGE("%s: Camera ID %s does not exist!", __FUNCTION__, cameraId.c_str());
75 status = HStatus::ILLEGAL_ARGUMENT;
76 break;
77 default:
78 ALOGE("Get camera characteristics from camera service failed: %s",
79 serviceRet.toString8().string());
80 status = B2HStatus(serviceRet);
81 }
82 _hidl_cb(status, hidlMetadata);
83 return Void();
84 }
Jayant Chowdhary2f686522022-05-09 14:52:16 +000085 if (filterVndkKeys(mVndkVersion, cameraMetadata) != OK) {
86 ALOGE("%s: Unable to filter vndk metadata keys for version %d", __FUNCTION__, mVndkVersion);
87 _hidl_cb(HStatus::UNKNOWN_ERROR, hidlMetadata);
88 return Void();
89 }
Jayant Chowdharybe543d42018-08-15 13:16:14 -070090 const camera_metadata_t *rawMetadata = cameraMetadata.getAndLock();
91 convertToHidl(rawMetadata, &hidlMetadata);
92 _hidl_cb(status, hidlMetadata);
93 cameraMetadata.unlock(rawMetadata);
94 return Void();
95}
96
97Return<void> HidlCameraService::connectDevice(const sp<HCameraDeviceCallback>& hCallback,
98 const hidl_string& cameraId,
99 connectDevice_cb _hidl_cb) {
Jayant Chowdhary0c947272018-08-15 14:42:04 -0700100 // Here, we first get ICameraDeviceUser from mAidlICameraService, then save
101 // that interface in the newly created HidlCameraDeviceUser impl class.
102 if (mAidlICameraService == nullptr) {
103 _hidl_cb(HStatus::UNKNOWN_ERROR, nullptr);
104 return Void();
105 }
106 sp<hardware::camera2::ICameraDeviceUser> deviceRemote = nullptr;
107 // Create a hardware::camera2::ICameraDeviceCallback object which internally
108 // calls callback functions passed through hCallback.
109 sp<H2BCameraDeviceCallbacks> hybridCallbacks = new H2BCameraDeviceCallbacks(hCallback);
Jayant Chowdhary2f686522022-05-09 14:52:16 +0000110 if (!hybridCallbacks->initializeLooper(mVndkVersion)) {
Jayant Chowdhary0c947272018-08-15 14:42:04 -0700111 ALOGE("Unable to handle callbacks on device, cannot connect");
112 _hidl_cb(HStatus::UNKNOWN_ERROR, nullptr);
113 return Void();
114 }
115 sp<hardware::camera2::ICameraDeviceCallbacks> callbacks = hybridCallbacks;
116 binder::Status serviceRet = mAidlICameraService->connectDevice(
Jooyung Han3f9a3b42020-01-23 12:27:18 +0900117 callbacks, String16(cameraId.c_str()), String16(""), {},
Shuzhen Wangd4abdf72021-05-28 11:22:50 -0700118 hardware::ICameraService::USE_CALLING_UID, 0/*oomScoreOffset*/,
119 /*targetSdkVersion*/__ANDROID_API_FUTURE__, /*out*/&deviceRemote);
Jayant Chowdhary0c947272018-08-15 14:42:04 -0700120 HStatus status = HStatus::NO_ERROR;
121 if (!serviceRet.isOk()) {
122 ALOGE("%s: Unable to connect to camera device", __FUNCTION__);
123 status = B2HStatus(serviceRet);
124 _hidl_cb(status, nullptr);
125 return Void();
126 }
127 // Now we create a HidlCameraDeviceUser class, store the deviceRemote in it,
128 // and return that back. All calls on that interface will be forwarded to
129 // the AIDL interface.
130 sp<HidlCameraDeviceUser> hDeviceRemote = new HidlCameraDeviceUser(deviceRemote);
131 if (!hDeviceRemote->initStatus()) {
132 ALOGE("%s: Unable to initialize camera device HIDL wrapper", __FUNCTION__);
133 _hidl_cb(HStatus::UNKNOWN_ERROR, nullptr);
134 return Void();
135 }
136 hybridCallbacks->setCaptureResultMetadataQueue(hDeviceRemote->getCaptureResultMetadataQueue());
137 _hidl_cb(status, hDeviceRemote);
Jayant Chowdharybe543d42018-08-15 13:16:14 -0700138 return Void();
139}
140
Jayant Chowdhary94f79a92018-08-15 13:57:17 -0700141void HidlCameraService::addToListenerCacheLocked(sp<HCameraServiceListener> hListener,
142 sp<hardware::ICameraServiceListener> csListener) {
143 mListeners.emplace_back(std::make_pair(hListener, csListener));
144}
145
146sp<hardware::ICameraServiceListener>
147HidlCameraService::searchListenerCacheLocked(sp<HCameraServiceListener> hListener,
148 bool shouldRemove) {
149 // Go through the mListeners list and compare the listener with the HIDL
150 // listener registered.
151 auto it = mListeners.begin();
152 sp<ICameraServiceListener> csListener = nullptr;
153 for (;it != mListeners.end(); it++) {
154 if (hardware::interfacesEqual(it->first, hListener)) {
155 break;
156 }
157 }
158 if (it != mListeners.end()) {
159 csListener = it->second;
160 if (shouldRemove) {
161 mListeners.erase(it);
162 }
163 }
164 return csListener;
165}
166
Jayant Chowdharybe543d42018-08-15 13:16:14 -0700167Return<void> HidlCameraService::addListener(const sp<HCameraServiceListener>& hCsListener,
168 addListener_cb _hidl_cb) {
Shuzhen Wang4fa28d22020-01-23 15:57:25 -0800169 std::vector<hardware::CameraStatus> cameraStatusAndIds{};
170 HStatus status = addListenerInternal<HCameraServiceListener>(
171 hCsListener, &cameraStatusAndIds);
172 if (status != HStatus::NO_ERROR) {
173 _hidl_cb(status, {});
Jayant Chowdhary94f79a92018-08-15 13:57:17 -0700174 return Void();
175 }
Shuzhen Wang4fa28d22020-01-23 15:57:25 -0800176
177 hidl_vec<HCameraStatusAndId> hCameraStatusAndIds;
178 //Convert cameraStatusAndIds to HIDL and call callback
179 convertToHidl(cameraStatusAndIds, &hCameraStatusAndIds);
180 _hidl_cb(status, hCameraStatusAndIds);
181
182 return Void();
183}
184
185Return<void> HidlCameraService::addListener_2_1(const sp<HCameraServiceListener2_1>& hCsListener,
186 addListener_2_1_cb _hidl_cb) {
187 std::vector<hardware::CameraStatus> cameraStatusAndIds{};
188 HStatus status = addListenerInternal<HCameraServiceListener2_1>(
189 hCsListener, &cameraStatusAndIds);
190 if (status != HStatus::NO_ERROR) {
191 _hidl_cb(status, {});
Jayant Chowdhary94f79a92018-08-15 13:57:17 -0700192 return Void();
193 }
Shuzhen Wang4fa28d22020-01-23 15:57:25 -0800194
195 hidl_vec<frameworks::cameraservice::service::V2_1::CameraStatusAndId> hCameraStatusAndIds;
196 //Convert cameraStatusAndIds to HIDL and call callback
197 convertToHidl(cameraStatusAndIds, &hCameraStatusAndIds);
198 _hidl_cb(status, hCameraStatusAndIds);
199
200 return Void();
201}
202
203template<class T>
204HStatus HidlCameraService::addListenerInternal(const sp<T>& hCsListener,
205 std::vector<hardware::CameraStatus>* cameraStatusAndIds) {
206 if (mAidlICameraService == nullptr) {
207 return HStatus::UNKNOWN_ERROR;
208 }
209 if (hCsListener == nullptr || cameraStatusAndIds == nullptr) {
210 ALOGE("%s listener and cameraStatusAndIds must not be NULL", __FUNCTION__);
211 return HStatus::ILLEGAL_ARGUMENT;
212 }
Jayant Chowdhary94f79a92018-08-15 13:57:17 -0700213 sp<hardware::ICameraServiceListener> csListener = nullptr;
214 // Check the cache for previously registered callbacks
215 {
216 Mutex::Autolock l(mListenerListLock);
217 csListener = searchListenerCacheLocked(hCsListener);
218 if (csListener == nullptr) {
219 // Wrap an hCsListener with AidlCameraServiceListener and pass it to
220 // CameraService.
221 csListener = new H2BCameraServiceListener(hCsListener);
222 // Add to cache
223 addToListenerCacheLocked(hCsListener, csListener);
224 } else {
225 ALOGE("%s: Trying to add a listener %p already registered",
226 __FUNCTION__, hCsListener.get());
Shuzhen Wang4fa28d22020-01-23 15:57:25 -0800227 return HStatus::ILLEGAL_ARGUMENT;
Jayant Chowdhary94f79a92018-08-15 13:57:17 -0700228 }
229 }
Jayant Chowdharyf949ddd2019-01-29 14:34:11 -0800230 binder::Status serviceRet =
Shuzhen Wang4fa28d22020-01-23 15:57:25 -0800231 mAidlICameraService->addListenerHelper(csListener, cameraStatusAndIds, true);
Jayant Chowdhary94f79a92018-08-15 13:57:17 -0700232 HStatus status = HStatus::NO_ERROR;
233 if (!serviceRet.isOk()) {
Shuzhen Wang4fa28d22020-01-23 15:57:25 -0800234 ALOGE("%s: Unable to add camera device status listener", __FUNCTION__);
235 status = B2HStatus(serviceRet);
236 return status;
Jayant Chowdhary94f79a92018-08-15 13:57:17 -0700237 }
Shuzhen Wang4fa28d22020-01-23 15:57:25 -0800238 cameraStatusAndIds->erase(std::remove_if(cameraStatusAndIds->begin(), cameraStatusAndIds->end(),
Jayant Chowdhary90e63692019-10-25 14:13:01 -0700239 [this](const hardware::CameraStatus& s) {
Shuzhen Wang4fa28d22020-01-23 15:57:25 -0800240 bool supportsHAL3 = false;
241 binder::Status sRet =
Jayant Chowdhary90e63692019-10-25 14:13:01 -0700242 mAidlICameraService->supportsCameraApi(String16(s.cameraId),
243 hardware::ICameraService::API_VERSION_2, &supportsHAL3);
Shuzhen Wang4fa28d22020-01-23 15:57:25 -0800244 return !sRet.isOk() || !supportsHAL3;
245 }), cameraStatusAndIds->end());
246
247 return HStatus::NO_ERROR;
Jayant Chowdharybe543d42018-08-15 13:16:14 -0700248}
249
250Return<HStatus> HidlCameraService::removeListener(const sp<HCameraServiceListener>& hCsListener) {
251 if (hCsListener == nullptr) {
252 ALOGE("%s listener must not be NULL", __FUNCTION__);
253 return HStatus::ILLEGAL_ARGUMENT;
254 }
Jayant Chowdhary94f79a92018-08-15 13:57:17 -0700255 sp<ICameraServiceListener> csListener = nullptr;
256 {
257 Mutex::Autolock l(mListenerListLock);
258 csListener = searchListenerCacheLocked(hCsListener, /*removeIfFound*/true);
259 }
260 if (csListener != nullptr) {
261 mAidlICameraService->removeListener(csListener);
262 } else {
263 ALOGE("%s Removing unregistered listener %p", __FUNCTION__, hCsListener.get());
264 return HStatus::ILLEGAL_ARGUMENT;
265 }
Jayant Chowdharybe543d42018-08-15 13:16:14 -0700266 return HStatus::NO_ERROR;
267}
268
269Return<void> HidlCameraService::getCameraVendorTagSections(getCameraVendorTagSections_cb _hidl_cb) {
Jayant Chowdhary8cf92922018-11-19 15:45:17 -0800270 sp<VendorTagDescriptorCache> gCache = VendorTagDescriptorCache::getGlobalVendorTagCache();
271 if (gCache == nullptr) {
272 _hidl_cb(HStatus::UNKNOWN_ERROR, {});
273 return Void();
274 }
275 const std::unordered_map<metadata_vendor_id_t, sp<android::VendorTagDescriptor>>
276 &vendorIdsAndTagDescs = gCache->getVendorIdsAndTagDescriptors();
277 if (vendorIdsAndTagDescs.size() == 0) {
278 _hidl_cb(HStatus::UNKNOWN_ERROR, {});
Jayant Chowdharybe543d42018-08-15 13:16:14 -0700279 return Void();
280 }
281
Jayant Chowdhary8cf92922018-11-19 15:45:17 -0800282 hidl_vec<HProviderIdAndVendorTagSections> hTagIdsAndVendorTagSections;
283 hTagIdsAndVendorTagSections.resize(vendorIdsAndTagDescs.size());
284 size_t j = 0;
285 for (auto &vendorIdAndTagDescs : vendorIdsAndTagDescs) {
286 hidl_vec<HVendorTagSection> hVendorTagSections;
287 sp<VendorTagDescriptor> desc = vendorIdAndTagDescs.second;
288 const SortedVector<String8>* sectionNames = desc->getAllSectionNames();
289 size_t numSections = sectionNames->size();
290 std::vector<std::vector<HVendorTag>> tagsBySection(numSections);
291 int tagCount = desc->getTagCount();
Jayant Chowdhary925a27f2021-09-13 16:25:07 -0700292 if (tagCount <= 0) {
293 continue;
294 }
Jayant Chowdhary8cf92922018-11-19 15:45:17 -0800295 std::vector<uint32_t> tags(tagCount);
296 desc->getTagArray(tags.data());
297 for (int i = 0; i < tagCount; i++) {
298 HVendorTag vt;
299 vt.tagId = tags[i];
300 vt.tagName = desc->getTagName(tags[i]);
301 vt.tagType = (HCameraMetadataType) desc->getTagType(tags[i]);
302 ssize_t sectionIdx = desc->getSectionIndex(tags[i]);
303 tagsBySection[sectionIdx].push_back(vt);
304 }
305 hVendorTagSections.resize(numSections);
306 for (size_t s = 0; s < numSections; s++) {
307 hVendorTagSections[s].sectionName = (*sectionNames)[s].string();
308 hVendorTagSections[s].tags = tagsBySection[s];
309 }
310 HProviderIdAndVendorTagSections &hProviderIdAndVendorTagSections =
311 hTagIdsAndVendorTagSections[j];
312 hProviderIdAndVendorTagSections.providerId = vendorIdAndTagDescs.first;
313 hProviderIdAndVendorTagSections.vendorTagSections = std::move(hVendorTagSections);
314 j++;
Jayant Chowdharybe543d42018-08-15 13:16:14 -0700315 }
Jayant Chowdhary8cf92922018-11-19 15:45:17 -0800316 _hidl_cb(HStatus::NO_ERROR, hTagIdsAndVendorTagSections);
Jayant Chowdharybe543d42018-08-15 13:16:14 -0700317 return Void();
318}
319
320} // implementation
321} // V2_0
322} // service
323} // cameraservice
324} // frameworks
325} // android
326