blob: 1d5213dedc1125f169cd536c4bb815cf52538084 [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>
Avichal Rakeshfcb78cb2022-10-27 15:45:54 -070024#include <aidl/AidlUtils.h>
Jayant Chowdharybe543d42018-08-15 13:16:14 -070025
26#include <hidl/HidlTransportSupport.h>
27
28namespace android {
29namespace frameworks {
30namespace cameraservice {
31namespace service {
32namespace V2_0 {
33namespace implementation {
34
35using frameworks::cameraservice::service::V2_0::implementation::HidlCameraService;
36using hardware::hidl_vec;
37using hardware::cameraservice::utils::conversion::convertToHidl;
38using hardware::cameraservice::utils::conversion::B2HStatus;
39using hardware::Void;
Avichal Rakeshfcb78cb2022-10-27 15:45:54 -070040using hardware::cameraservice::utils::conversion::aidl::filterVndkKeys;
Jayant Chowdharybe543d42018-08-15 13:16:14 -070041
Jayant Chowdhary0c947272018-08-15 14:42:04 -070042using device::V2_0::implementation::H2BCameraDeviceCallbacks;
Shuzhen Wang316781a2020-08-18 18:11:01 -070043using device::V2_1::implementation::HidlCameraDeviceUser;
Jayant Chowdhary94f79a92018-08-15 13:57:17 -070044using service::V2_0::implementation::H2BCameraServiceListener;
Jayant Chowdhary8cf92922018-11-19 15:45:17 -080045using HCameraMetadataType = frameworks::cameraservice::common::V2_0::CameraMetadataType;
46using HVendorTag = frameworks::cameraservice::common::V2_0::VendorTag;
47using HVendorTagSection = frameworks::cameraservice::common::V2_0::VendorTagSection;
48using HProviderIdAndVendorTagSections =
49 frameworks::cameraservice::common::V2_0::ProviderIdAndVendorTagSections;
Jayant Chowdharybe543d42018-08-15 13:16:14 -070050
51sp<HidlCameraService> gHidlCameraService;
52
53sp<HidlCameraService> HidlCameraService::getInstance(android::CameraService *cs) {
54 gHidlCameraService = new HidlCameraService(cs);
55 return gHidlCameraService;
56}
57
Jayant Chowdhary2f686522022-05-09 14:52:16 +000058HidlCameraService::HidlCameraService(android::CameraService *cs) : mAidlICameraService(cs) {
59 mVndkVersion = base::GetIntProperty("ro.vndk.version", __ANDROID_API_FUTURE__);
60};
61
Jayant Chowdharybe543d42018-08-15 13:16:14 -070062Return<void>
63HidlCameraService::getCameraCharacteristics(const hidl_string& cameraId,
64 getCameraCharacteristics_cb _hidl_cb) {
65 android::CameraMetadata cameraMetadata;
66 HStatus status = HStatus::NO_ERROR;
67 binder::Status serviceRet =
Shuzhen Wangd4abdf72021-05-28 11:22:50 -070068 mAidlICameraService->getCameraCharacteristics(String16(cameraId.c_str()),
Austin Borger18b30a72022-10-27 12:20:29 -070069 /*targetSdkVersion*/__ANDROID_API_FUTURE__, /*overrideToPortrait*/true,
70 &cameraMetadata);
Jayant Chowdharybe543d42018-08-15 13:16:14 -070071 HCameraMetadata hidlMetadata;
72 if (!serviceRet.isOk()) {
73 switch(serviceRet.serviceSpecificErrorCode()) {
74 // No ERROR_CAMERA_DISCONNECTED since we're in the same process.
75 case hardware::ICameraService::ERROR_ILLEGAL_ARGUMENT:
76 ALOGE("%s: Camera ID %s does not exist!", __FUNCTION__, cameraId.c_str());
77 status = HStatus::ILLEGAL_ARGUMENT;
78 break;
79 default:
80 ALOGE("Get camera characteristics from camera service failed: %s",
81 serviceRet.toString8().string());
82 status = B2HStatus(serviceRet);
83 }
84 _hidl_cb(status, hidlMetadata);
85 return Void();
86 }
Jayant Chowdhary2f686522022-05-09 14:52:16 +000087 if (filterVndkKeys(mVndkVersion, cameraMetadata) != OK) {
88 ALOGE("%s: Unable to filter vndk metadata keys for version %d", __FUNCTION__, mVndkVersion);
89 _hidl_cb(HStatus::UNKNOWN_ERROR, hidlMetadata);
90 return Void();
91 }
Jayant Chowdharybe543d42018-08-15 13:16:14 -070092 const camera_metadata_t *rawMetadata = cameraMetadata.getAndLock();
93 convertToHidl(rawMetadata, &hidlMetadata);
94 _hidl_cb(status, hidlMetadata);
95 cameraMetadata.unlock(rawMetadata);
96 return Void();
97}
98
99Return<void> HidlCameraService::connectDevice(const sp<HCameraDeviceCallback>& hCallback,
100 const hidl_string& cameraId,
101 connectDevice_cb _hidl_cb) {
Jayant Chowdhary0c947272018-08-15 14:42:04 -0700102 // Here, we first get ICameraDeviceUser from mAidlICameraService, then save
103 // that interface in the newly created HidlCameraDeviceUser impl class.
104 if (mAidlICameraService == nullptr) {
105 _hidl_cb(HStatus::UNKNOWN_ERROR, nullptr);
106 return Void();
107 }
108 sp<hardware::camera2::ICameraDeviceUser> deviceRemote = nullptr;
109 // Create a hardware::camera2::ICameraDeviceCallback object which internally
110 // calls callback functions passed through hCallback.
111 sp<H2BCameraDeviceCallbacks> hybridCallbacks = new H2BCameraDeviceCallbacks(hCallback);
Jayant Chowdhary2f686522022-05-09 14:52:16 +0000112 if (!hybridCallbacks->initializeLooper(mVndkVersion)) {
Jayant Chowdhary0c947272018-08-15 14:42:04 -0700113 ALOGE("Unable to handle callbacks on device, cannot connect");
114 _hidl_cb(HStatus::UNKNOWN_ERROR, nullptr);
115 return Void();
116 }
117 sp<hardware::camera2::ICameraDeviceCallbacks> callbacks = hybridCallbacks;
118 binder::Status serviceRet = mAidlICameraService->connectDevice(
Jooyung Han3f9a3b42020-01-23 12:27:18 +0900119 callbacks, String16(cameraId.c_str()), String16(""), {},
Shuzhen Wangd4abdf72021-05-28 11:22:50 -0700120 hardware::ICameraService::USE_CALLING_UID, 0/*oomScoreOffset*/,
Austin Borger18b30a72022-10-27 12:20:29 -0700121 /*targetSdkVersion*/__ANDROID_API_FUTURE__, /*overrideToPortrait*/true,
122 /*out*/&deviceRemote);
Jayant Chowdhary0c947272018-08-15 14:42:04 -0700123 HStatus status = HStatus::NO_ERROR;
124 if (!serviceRet.isOk()) {
125 ALOGE("%s: Unable to connect to camera device", __FUNCTION__);
126 status = B2HStatus(serviceRet);
127 _hidl_cb(status, nullptr);
128 return Void();
129 }
130 // Now we create a HidlCameraDeviceUser class, store the deviceRemote in it,
131 // and return that back. All calls on that interface will be forwarded to
132 // the AIDL interface.
133 sp<HidlCameraDeviceUser> hDeviceRemote = new HidlCameraDeviceUser(deviceRemote);
134 if (!hDeviceRemote->initStatus()) {
135 ALOGE("%s: Unable to initialize camera device HIDL wrapper", __FUNCTION__);
136 _hidl_cb(HStatus::UNKNOWN_ERROR, nullptr);
137 return Void();
138 }
139 hybridCallbacks->setCaptureResultMetadataQueue(hDeviceRemote->getCaptureResultMetadataQueue());
140 _hidl_cb(status, hDeviceRemote);
Jayant Chowdharybe543d42018-08-15 13:16:14 -0700141 return Void();
142}
143
Jayant Chowdhary94f79a92018-08-15 13:57:17 -0700144void HidlCameraService::addToListenerCacheLocked(sp<HCameraServiceListener> hListener,
145 sp<hardware::ICameraServiceListener> csListener) {
146 mListeners.emplace_back(std::make_pair(hListener, csListener));
147}
148
149sp<hardware::ICameraServiceListener>
150HidlCameraService::searchListenerCacheLocked(sp<HCameraServiceListener> hListener,
151 bool shouldRemove) {
152 // Go through the mListeners list and compare the listener with the HIDL
153 // listener registered.
154 auto it = mListeners.begin();
155 sp<ICameraServiceListener> csListener = nullptr;
156 for (;it != mListeners.end(); it++) {
157 if (hardware::interfacesEqual(it->first, hListener)) {
158 break;
159 }
160 }
161 if (it != mListeners.end()) {
162 csListener = it->second;
163 if (shouldRemove) {
164 mListeners.erase(it);
165 }
166 }
167 return csListener;
168}
169
Jayant Chowdharybe543d42018-08-15 13:16:14 -0700170Return<void> HidlCameraService::addListener(const sp<HCameraServiceListener>& hCsListener,
171 addListener_cb _hidl_cb) {
Shuzhen Wang4fa28d22020-01-23 15:57:25 -0800172 std::vector<hardware::CameraStatus> cameraStatusAndIds{};
173 HStatus status = addListenerInternal<HCameraServiceListener>(
174 hCsListener, &cameraStatusAndIds);
175 if (status != HStatus::NO_ERROR) {
176 _hidl_cb(status, {});
Jayant Chowdhary94f79a92018-08-15 13:57:17 -0700177 return Void();
178 }
Shuzhen Wang4fa28d22020-01-23 15:57:25 -0800179
180 hidl_vec<HCameraStatusAndId> hCameraStatusAndIds;
181 //Convert cameraStatusAndIds to HIDL and call callback
182 convertToHidl(cameraStatusAndIds, &hCameraStatusAndIds);
183 _hidl_cb(status, hCameraStatusAndIds);
184
185 return Void();
186}
187
188Return<void> HidlCameraService::addListener_2_1(const sp<HCameraServiceListener2_1>& hCsListener,
189 addListener_2_1_cb _hidl_cb) {
190 std::vector<hardware::CameraStatus> cameraStatusAndIds{};
191 HStatus status = addListenerInternal<HCameraServiceListener2_1>(
192 hCsListener, &cameraStatusAndIds);
193 if (status != HStatus::NO_ERROR) {
194 _hidl_cb(status, {});
Jayant Chowdhary94f79a92018-08-15 13:57:17 -0700195 return Void();
196 }
Shuzhen Wang4fa28d22020-01-23 15:57:25 -0800197
198 hidl_vec<frameworks::cameraservice::service::V2_1::CameraStatusAndId> hCameraStatusAndIds;
199 //Convert cameraStatusAndIds to HIDL and call callback
200 convertToHidl(cameraStatusAndIds, &hCameraStatusAndIds);
201 _hidl_cb(status, hCameraStatusAndIds);
202
203 return Void();
204}
205
206template<class T>
207HStatus HidlCameraService::addListenerInternal(const sp<T>& hCsListener,
208 std::vector<hardware::CameraStatus>* cameraStatusAndIds) {
209 if (mAidlICameraService == nullptr) {
210 return HStatus::UNKNOWN_ERROR;
211 }
212 if (hCsListener == nullptr || cameraStatusAndIds == nullptr) {
213 ALOGE("%s listener and cameraStatusAndIds must not be NULL", __FUNCTION__);
214 return HStatus::ILLEGAL_ARGUMENT;
215 }
Jayant Chowdhary94f79a92018-08-15 13:57:17 -0700216 sp<hardware::ICameraServiceListener> csListener = nullptr;
217 // Check the cache for previously registered callbacks
218 {
219 Mutex::Autolock l(mListenerListLock);
220 csListener = searchListenerCacheLocked(hCsListener);
221 if (csListener == nullptr) {
222 // Wrap an hCsListener with AidlCameraServiceListener and pass it to
223 // CameraService.
224 csListener = new H2BCameraServiceListener(hCsListener);
225 // Add to cache
226 addToListenerCacheLocked(hCsListener, csListener);
227 } else {
228 ALOGE("%s: Trying to add a listener %p already registered",
229 __FUNCTION__, hCsListener.get());
Shuzhen Wang4fa28d22020-01-23 15:57:25 -0800230 return HStatus::ILLEGAL_ARGUMENT;
Jayant Chowdhary94f79a92018-08-15 13:57:17 -0700231 }
232 }
Jayant Chowdharyf949ddd2019-01-29 14:34:11 -0800233 binder::Status serviceRet =
Shuzhen Wang4fa28d22020-01-23 15:57:25 -0800234 mAidlICameraService->addListenerHelper(csListener, cameraStatusAndIds, true);
Jayant Chowdhary94f79a92018-08-15 13:57:17 -0700235 HStatus status = HStatus::NO_ERROR;
236 if (!serviceRet.isOk()) {
Shuzhen Wang4fa28d22020-01-23 15:57:25 -0800237 ALOGE("%s: Unable to add camera device status listener", __FUNCTION__);
238 status = B2HStatus(serviceRet);
239 return status;
Jayant Chowdhary94f79a92018-08-15 13:57:17 -0700240 }
Shuzhen Wang4fa28d22020-01-23 15:57:25 -0800241 cameraStatusAndIds->erase(std::remove_if(cameraStatusAndIds->begin(), cameraStatusAndIds->end(),
Jayant Chowdhary90e63692019-10-25 14:13:01 -0700242 [this](const hardware::CameraStatus& s) {
Shuzhen Wang4fa28d22020-01-23 15:57:25 -0800243 bool supportsHAL3 = false;
244 binder::Status sRet =
Jayant Chowdhary90e63692019-10-25 14:13:01 -0700245 mAidlICameraService->supportsCameraApi(String16(s.cameraId),
246 hardware::ICameraService::API_VERSION_2, &supportsHAL3);
Shuzhen Wang4fa28d22020-01-23 15:57:25 -0800247 return !sRet.isOk() || !supportsHAL3;
248 }), cameraStatusAndIds->end());
249
250 return HStatus::NO_ERROR;
Jayant Chowdharybe543d42018-08-15 13:16:14 -0700251}
252
253Return<HStatus> HidlCameraService::removeListener(const sp<HCameraServiceListener>& hCsListener) {
254 if (hCsListener == nullptr) {
255 ALOGE("%s listener must not be NULL", __FUNCTION__);
256 return HStatus::ILLEGAL_ARGUMENT;
257 }
Jayant Chowdhary94f79a92018-08-15 13:57:17 -0700258 sp<ICameraServiceListener> csListener = nullptr;
259 {
260 Mutex::Autolock l(mListenerListLock);
261 csListener = searchListenerCacheLocked(hCsListener, /*removeIfFound*/true);
262 }
263 if (csListener != nullptr) {
264 mAidlICameraService->removeListener(csListener);
265 } else {
266 ALOGE("%s Removing unregistered listener %p", __FUNCTION__, hCsListener.get());
267 return HStatus::ILLEGAL_ARGUMENT;
268 }
Jayant Chowdharybe543d42018-08-15 13:16:14 -0700269 return HStatus::NO_ERROR;
270}
271
272Return<void> HidlCameraService::getCameraVendorTagSections(getCameraVendorTagSections_cb _hidl_cb) {
Jayant Chowdhary8cf92922018-11-19 15:45:17 -0800273 sp<VendorTagDescriptorCache> gCache = VendorTagDescriptorCache::getGlobalVendorTagCache();
274 if (gCache == nullptr) {
275 _hidl_cb(HStatus::UNKNOWN_ERROR, {});
276 return Void();
277 }
278 const std::unordered_map<metadata_vendor_id_t, sp<android::VendorTagDescriptor>>
279 &vendorIdsAndTagDescs = gCache->getVendorIdsAndTagDescriptors();
280 if (vendorIdsAndTagDescs.size() == 0) {
281 _hidl_cb(HStatus::UNKNOWN_ERROR, {});
Jayant Chowdharybe543d42018-08-15 13:16:14 -0700282 return Void();
283 }
284
Jayant Chowdhary8cf92922018-11-19 15:45:17 -0800285 hidl_vec<HProviderIdAndVendorTagSections> hTagIdsAndVendorTagSections;
286 hTagIdsAndVendorTagSections.resize(vendorIdsAndTagDescs.size());
287 size_t j = 0;
288 for (auto &vendorIdAndTagDescs : vendorIdsAndTagDescs) {
289 hidl_vec<HVendorTagSection> hVendorTagSections;
290 sp<VendorTagDescriptor> desc = vendorIdAndTagDescs.second;
291 const SortedVector<String8>* sectionNames = desc->getAllSectionNames();
292 size_t numSections = sectionNames->size();
293 std::vector<std::vector<HVendorTag>> tagsBySection(numSections);
294 int tagCount = desc->getTagCount();
Jayant Chowdhary925a27f2021-09-13 16:25:07 -0700295 if (tagCount <= 0) {
296 continue;
297 }
Jayant Chowdhary8cf92922018-11-19 15:45:17 -0800298 std::vector<uint32_t> tags(tagCount);
299 desc->getTagArray(tags.data());
300 for (int i = 0; i < tagCount; i++) {
301 HVendorTag vt;
302 vt.tagId = tags[i];
303 vt.tagName = desc->getTagName(tags[i]);
304 vt.tagType = (HCameraMetadataType) desc->getTagType(tags[i]);
305 ssize_t sectionIdx = desc->getSectionIndex(tags[i]);
306 tagsBySection[sectionIdx].push_back(vt);
307 }
308 hVendorTagSections.resize(numSections);
309 for (size_t s = 0; s < numSections; s++) {
310 hVendorTagSections[s].sectionName = (*sectionNames)[s].string();
311 hVendorTagSections[s].tags = tagsBySection[s];
312 }
313 HProviderIdAndVendorTagSections &hProviderIdAndVendorTagSections =
314 hTagIdsAndVendorTagSections[j];
315 hProviderIdAndVendorTagSections.providerId = vendorIdAndTagDescs.first;
316 hProviderIdAndVendorTagSections.vendorTagSections = std::move(hVendorTagSections);
317 j++;
Jayant Chowdharybe543d42018-08-15 13:16:14 -0700318 }
Jayant Chowdhary8cf92922018-11-19 15:45:17 -0800319 _hidl_cb(HStatus::NO_ERROR, hTagIdsAndVendorTagSections);
Jayant Chowdharybe543d42018-08-15 13:16:14 -0700320 return Void();
321}
322
323} // implementation
324} // V2_0
325} // service
326} // cameraservice
327} // frameworks
328} // android
329