blob: 1a5a6b97a147f25cbda7f1eb5e49796ea02bd709 [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
Avichal Rakesh74b5ae72023-12-27 16:56:45 -080028#include <utils/Utils.h>
29
Jayant Chowdharybe543d42018-08-15 13:16:14 -070030namespace android {
31namespace frameworks {
32namespace cameraservice {
33namespace service {
34namespace V2_0 {
35namespace implementation {
36
37using frameworks::cameraservice::service::V2_0::implementation::HidlCameraService;
38using hardware::hidl_vec;
39using hardware::cameraservice::utils::conversion::convertToHidl;
40using hardware::cameraservice::utils::conversion::B2HStatus;
41using hardware::Void;
Avichal Rakeshfcb78cb2022-10-27 15:45:54 -070042using hardware::cameraservice::utils::conversion::aidl::filterVndkKeys;
Jayant Chowdharybe543d42018-08-15 13:16:14 -070043
Jayant Chowdhary0c947272018-08-15 14:42:04 -070044using device::V2_0::implementation::H2BCameraDeviceCallbacks;
Shuzhen Wang316781a2020-08-18 18:11:01 -070045using device::V2_1::implementation::HidlCameraDeviceUser;
Jayant Chowdhary94f79a92018-08-15 13:57:17 -070046using service::V2_0::implementation::H2BCameraServiceListener;
Jayant Chowdhary8cf92922018-11-19 15:45:17 -080047using HCameraMetadataType = frameworks::cameraservice::common::V2_0::CameraMetadataType;
48using HVendorTag = frameworks::cameraservice::common::V2_0::VendorTag;
49using HVendorTagSection = frameworks::cameraservice::common::V2_0::VendorTagSection;
50using HProviderIdAndVendorTagSections =
51 frameworks::cameraservice::common::V2_0::ProviderIdAndVendorTagSections;
Jayant Chowdharybe543d42018-08-15 13:16:14 -070052
53sp<HidlCameraService> gHidlCameraService;
54
55sp<HidlCameraService> HidlCameraService::getInstance(android::CameraService *cs) {
56 gHidlCameraService = new HidlCameraService(cs);
57 return gHidlCameraService;
58}
59
Jayant Chowdhary2f686522022-05-09 14:52:16 +000060HidlCameraService::HidlCameraService(android::CameraService *cs) : mAidlICameraService(cs) {
Avichal Rakesh74b5ae72023-12-27 16:56:45 -080061 mVndkVersion = getVNDKVersionFromProp(__ANDROID_API_FUTURE__);
62}
Jayant Chowdhary2f686522022-05-09 14:52:16 +000063
Jayant Chowdharybe543d42018-08-15 13:16:14 -070064Return<void>
65HidlCameraService::getCameraCharacteristics(const hidl_string& cameraId,
66 getCameraCharacteristics_cb _hidl_cb) {
67 android::CameraMetadata cameraMetadata;
68 HStatus status = HStatus::NO_ERROR;
69 binder::Status serviceRet =
Austin Borger71d8f672023-06-01 16:51:35 -070070 mAidlICameraService->getCameraCharacteristics(cameraId,
Austin Borger7b14d5e2023-03-16 10:29:20 -070071 /*targetSdkVersion*/__ANDROID_API_FUTURE__, /*overrideToPortrait*/false,
Austin Borger18b30a72022-10-27 12:20:29 -070072 &cameraMetadata);
Jayant Chowdharybe543d42018-08-15 13:16:14 -070073 HCameraMetadata hidlMetadata;
74 if (!serviceRet.isOk()) {
75 switch(serviceRet.serviceSpecificErrorCode()) {
76 // No ERROR_CAMERA_DISCONNECTED since we're in the same process.
77 case hardware::ICameraService::ERROR_ILLEGAL_ARGUMENT:
78 ALOGE("%s: Camera ID %s does not exist!", __FUNCTION__, cameraId.c_str());
79 status = HStatus::ILLEGAL_ARGUMENT;
80 break;
81 default:
82 ALOGE("Get camera characteristics from camera service failed: %s",
Tomasz Wasilczyk12b04a52023-08-11 15:52:22 +000083 serviceRet.toString8().c_str());
Jayant Chowdharybe543d42018-08-15 13:16:14 -070084 status = B2HStatus(serviceRet);
85 }
86 _hidl_cb(status, hidlMetadata);
87 return Void();
88 }
Jayant Chowdhary2f686522022-05-09 14:52:16 +000089 if (filterVndkKeys(mVndkVersion, cameraMetadata) != OK) {
90 ALOGE("%s: Unable to filter vndk metadata keys for version %d", __FUNCTION__, mVndkVersion);
91 _hidl_cb(HStatus::UNKNOWN_ERROR, hidlMetadata);
92 return Void();
93 }
Jayant Chowdharybe543d42018-08-15 13:16:14 -070094 const camera_metadata_t *rawMetadata = cameraMetadata.getAndLock();
95 convertToHidl(rawMetadata, &hidlMetadata);
96 _hidl_cb(status, hidlMetadata);
97 cameraMetadata.unlock(rawMetadata);
98 return Void();
99}
100
101Return<void> HidlCameraService::connectDevice(const sp<HCameraDeviceCallback>& hCallback,
102 const hidl_string& cameraId,
103 connectDevice_cb _hidl_cb) {
Jayant Chowdhary0c947272018-08-15 14:42:04 -0700104 // Here, we first get ICameraDeviceUser from mAidlICameraService, then save
105 // that interface in the newly created HidlCameraDeviceUser impl class.
106 if (mAidlICameraService == nullptr) {
107 _hidl_cb(HStatus::UNKNOWN_ERROR, nullptr);
108 return Void();
109 }
110 sp<hardware::camera2::ICameraDeviceUser> deviceRemote = nullptr;
111 // Create a hardware::camera2::ICameraDeviceCallback object which internally
112 // calls callback functions passed through hCallback.
113 sp<H2BCameraDeviceCallbacks> hybridCallbacks = new H2BCameraDeviceCallbacks(hCallback);
Jayant Chowdhary2f686522022-05-09 14:52:16 +0000114 if (!hybridCallbacks->initializeLooper(mVndkVersion)) {
Jayant Chowdhary0c947272018-08-15 14:42:04 -0700115 ALOGE("Unable to handle callbacks on device, cannot connect");
116 _hidl_cb(HStatus::UNKNOWN_ERROR, nullptr);
117 return Void();
118 }
119 sp<hardware::camera2::ICameraDeviceCallbacks> callbacks = hybridCallbacks;
120 binder::Status serviceRet = mAidlICameraService->connectDevice(
Austin Borger71d8f672023-06-01 16:51:35 -0700121 callbacks, cameraId, std::string(), {},
Shuzhen Wangd4abdf72021-05-28 11:22:50 -0700122 hardware::ICameraService::USE_CALLING_UID, 0/*oomScoreOffset*/,
Austin Borger7b14d5e2023-03-16 10:29:20 -0700123 /*targetSdkVersion*/__ANDROID_API_FUTURE__, /*overrideToPortrait*/false,
Austin Borger18b30a72022-10-27 12:20:29 -0700124 /*out*/&deviceRemote);
Jayant Chowdhary0c947272018-08-15 14:42:04 -0700125 HStatus status = HStatus::NO_ERROR;
126 if (!serviceRet.isOk()) {
127 ALOGE("%s: Unable to connect to camera device", __FUNCTION__);
128 status = B2HStatus(serviceRet);
129 _hidl_cb(status, nullptr);
130 return Void();
131 }
132 // Now we create a HidlCameraDeviceUser class, store the deviceRemote in it,
133 // and return that back. All calls on that interface will be forwarded to
134 // the AIDL interface.
135 sp<HidlCameraDeviceUser> hDeviceRemote = new HidlCameraDeviceUser(deviceRemote);
136 if (!hDeviceRemote->initStatus()) {
137 ALOGE("%s: Unable to initialize camera device HIDL wrapper", __FUNCTION__);
138 _hidl_cb(HStatus::UNKNOWN_ERROR, nullptr);
139 return Void();
140 }
141 hybridCallbacks->setCaptureResultMetadataQueue(hDeviceRemote->getCaptureResultMetadataQueue());
142 _hidl_cb(status, hDeviceRemote);
Jayant Chowdharybe543d42018-08-15 13:16:14 -0700143 return Void();
144}
145
Jayant Chowdhary94f79a92018-08-15 13:57:17 -0700146void HidlCameraService::addToListenerCacheLocked(sp<HCameraServiceListener> hListener,
147 sp<hardware::ICameraServiceListener> csListener) {
148 mListeners.emplace_back(std::make_pair(hListener, csListener));
149}
150
151sp<hardware::ICameraServiceListener>
152HidlCameraService::searchListenerCacheLocked(sp<HCameraServiceListener> hListener,
153 bool shouldRemove) {
154 // Go through the mListeners list and compare the listener with the HIDL
155 // listener registered.
156 auto it = mListeners.begin();
157 sp<ICameraServiceListener> csListener = nullptr;
158 for (;it != mListeners.end(); it++) {
159 if (hardware::interfacesEqual(it->first, hListener)) {
160 break;
161 }
162 }
163 if (it != mListeners.end()) {
164 csListener = it->second;
165 if (shouldRemove) {
166 mListeners.erase(it);
167 }
168 }
169 return csListener;
170}
171
Jayant Chowdharybe543d42018-08-15 13:16:14 -0700172Return<void> HidlCameraService::addListener(const sp<HCameraServiceListener>& hCsListener,
173 addListener_cb _hidl_cb) {
Shuzhen Wang4fa28d22020-01-23 15:57:25 -0800174 std::vector<hardware::CameraStatus> cameraStatusAndIds{};
175 HStatus status = addListenerInternal<HCameraServiceListener>(
176 hCsListener, &cameraStatusAndIds);
177 if (status != HStatus::NO_ERROR) {
178 _hidl_cb(status, {});
Jayant Chowdhary94f79a92018-08-15 13:57:17 -0700179 return Void();
180 }
Shuzhen Wang4fa28d22020-01-23 15:57:25 -0800181
182 hidl_vec<HCameraStatusAndId> hCameraStatusAndIds;
183 //Convert cameraStatusAndIds to HIDL and call callback
184 convertToHidl(cameraStatusAndIds, &hCameraStatusAndIds);
185 _hidl_cb(status, hCameraStatusAndIds);
186
187 return Void();
188}
189
190Return<void> HidlCameraService::addListener_2_1(const sp<HCameraServiceListener2_1>& hCsListener,
191 addListener_2_1_cb _hidl_cb) {
192 std::vector<hardware::CameraStatus> cameraStatusAndIds{};
193 HStatus status = addListenerInternal<HCameraServiceListener2_1>(
194 hCsListener, &cameraStatusAndIds);
195 if (status != HStatus::NO_ERROR) {
196 _hidl_cb(status, {});
Jayant Chowdhary94f79a92018-08-15 13:57:17 -0700197 return Void();
198 }
Shuzhen Wang4fa28d22020-01-23 15:57:25 -0800199
200 hidl_vec<frameworks::cameraservice::service::V2_1::CameraStatusAndId> hCameraStatusAndIds;
201 //Convert cameraStatusAndIds to HIDL and call callback
202 convertToHidl(cameraStatusAndIds, &hCameraStatusAndIds);
203 _hidl_cb(status, hCameraStatusAndIds);
204
205 return Void();
206}
207
208template<class T>
209HStatus HidlCameraService::addListenerInternal(const sp<T>& hCsListener,
210 std::vector<hardware::CameraStatus>* cameraStatusAndIds) {
211 if (mAidlICameraService == nullptr) {
212 return HStatus::UNKNOWN_ERROR;
213 }
214 if (hCsListener == nullptr || cameraStatusAndIds == nullptr) {
215 ALOGE("%s listener and cameraStatusAndIds must not be NULL", __FUNCTION__);
216 return HStatus::ILLEGAL_ARGUMENT;
217 }
Jayant Chowdhary94f79a92018-08-15 13:57:17 -0700218 sp<hardware::ICameraServiceListener> csListener = nullptr;
219 // Check the cache for previously registered callbacks
220 {
221 Mutex::Autolock l(mListenerListLock);
222 csListener = searchListenerCacheLocked(hCsListener);
223 if (csListener == nullptr) {
224 // Wrap an hCsListener with AidlCameraServiceListener and pass it to
225 // CameraService.
226 csListener = new H2BCameraServiceListener(hCsListener);
227 // Add to cache
228 addToListenerCacheLocked(hCsListener, csListener);
229 } else {
230 ALOGE("%s: Trying to add a listener %p already registered",
231 __FUNCTION__, hCsListener.get());
Shuzhen Wang4fa28d22020-01-23 15:57:25 -0800232 return HStatus::ILLEGAL_ARGUMENT;
Jayant Chowdhary94f79a92018-08-15 13:57:17 -0700233 }
234 }
Jayant Chowdharyf949ddd2019-01-29 14:34:11 -0800235 binder::Status serviceRet =
Shuzhen Wang4fa28d22020-01-23 15:57:25 -0800236 mAidlICameraService->addListenerHelper(csListener, cameraStatusAndIds, true);
Jayant Chowdhary94f79a92018-08-15 13:57:17 -0700237 HStatus status = HStatus::NO_ERROR;
238 if (!serviceRet.isOk()) {
Shuzhen Wang4fa28d22020-01-23 15:57:25 -0800239 ALOGE("%s: Unable to add camera device status listener", __FUNCTION__);
240 status = B2HStatus(serviceRet);
241 return status;
Jayant Chowdhary94f79a92018-08-15 13:57:17 -0700242 }
Shuzhen Wang4fa28d22020-01-23 15:57:25 -0800243 cameraStatusAndIds->erase(std::remove_if(cameraStatusAndIds->begin(), cameraStatusAndIds->end(),
Jayant Chowdhary90e63692019-10-25 14:13:01 -0700244 [this](const hardware::CameraStatus& s) {
Shuzhen Wang4fa28d22020-01-23 15:57:25 -0800245 bool supportsHAL3 = false;
246 binder::Status sRet =
Austin Borger71d8f672023-06-01 16:51:35 -0700247 mAidlICameraService->supportsCameraApi(s.cameraId,
Jayant Chowdhary90e63692019-10-25 14:13:01 -0700248 hardware::ICameraService::API_VERSION_2, &supportsHAL3);
Shuzhen Wang4fa28d22020-01-23 15:57:25 -0800249 return !sRet.isOk() || !supportsHAL3;
250 }), cameraStatusAndIds->end());
251
252 return HStatus::NO_ERROR;
Jayant Chowdharybe543d42018-08-15 13:16:14 -0700253}
254
255Return<HStatus> HidlCameraService::removeListener(const sp<HCameraServiceListener>& hCsListener) {
256 if (hCsListener == nullptr) {
257 ALOGE("%s listener must not be NULL", __FUNCTION__);
258 return HStatus::ILLEGAL_ARGUMENT;
259 }
Jayant Chowdhary94f79a92018-08-15 13:57:17 -0700260 sp<ICameraServiceListener> csListener = nullptr;
261 {
262 Mutex::Autolock l(mListenerListLock);
263 csListener = searchListenerCacheLocked(hCsListener, /*removeIfFound*/true);
264 }
265 if (csListener != nullptr) {
266 mAidlICameraService->removeListener(csListener);
267 } else {
268 ALOGE("%s Removing unregistered listener %p", __FUNCTION__, hCsListener.get());
269 return HStatus::ILLEGAL_ARGUMENT;
270 }
Jayant Chowdharybe543d42018-08-15 13:16:14 -0700271 return HStatus::NO_ERROR;
272}
273
274Return<void> HidlCameraService::getCameraVendorTagSections(getCameraVendorTagSections_cb _hidl_cb) {
Jayant Chowdhary8cf92922018-11-19 15:45:17 -0800275 sp<VendorTagDescriptorCache> gCache = VendorTagDescriptorCache::getGlobalVendorTagCache();
276 if (gCache == nullptr) {
277 _hidl_cb(HStatus::UNKNOWN_ERROR, {});
278 return Void();
279 }
280 const std::unordered_map<metadata_vendor_id_t, sp<android::VendorTagDescriptor>>
281 &vendorIdsAndTagDescs = gCache->getVendorIdsAndTagDescriptors();
282 if (vendorIdsAndTagDescs.size() == 0) {
283 _hidl_cb(HStatus::UNKNOWN_ERROR, {});
Jayant Chowdharybe543d42018-08-15 13:16:14 -0700284 return Void();
285 }
286
Jayant Chowdhary8cf92922018-11-19 15:45:17 -0800287 hidl_vec<HProviderIdAndVendorTagSections> hTagIdsAndVendorTagSections;
288 hTagIdsAndVendorTagSections.resize(vendorIdsAndTagDescs.size());
289 size_t j = 0;
290 for (auto &vendorIdAndTagDescs : vendorIdsAndTagDescs) {
291 hidl_vec<HVendorTagSection> hVendorTagSections;
292 sp<VendorTagDescriptor> desc = vendorIdAndTagDescs.second;
293 const SortedVector<String8>* sectionNames = desc->getAllSectionNames();
294 size_t numSections = sectionNames->size();
295 std::vector<std::vector<HVendorTag>> tagsBySection(numSections);
296 int tagCount = desc->getTagCount();
Jayant Chowdhary925a27f2021-09-13 16:25:07 -0700297 if (tagCount <= 0) {
298 continue;
299 }
Jayant Chowdhary8cf92922018-11-19 15:45:17 -0800300 std::vector<uint32_t> tags(tagCount);
301 desc->getTagArray(tags.data());
302 for (int i = 0; i < tagCount; i++) {
303 HVendorTag vt;
304 vt.tagId = tags[i];
305 vt.tagName = desc->getTagName(tags[i]);
306 vt.tagType = (HCameraMetadataType) desc->getTagType(tags[i]);
307 ssize_t sectionIdx = desc->getSectionIndex(tags[i]);
308 tagsBySection[sectionIdx].push_back(vt);
309 }
310 hVendorTagSections.resize(numSections);
311 for (size_t s = 0; s < numSections; s++) {
Tomasz Wasilczyk12b04a52023-08-11 15:52:22 +0000312 hVendorTagSections[s].sectionName = (*sectionNames)[s].c_str();
Jayant Chowdhary8cf92922018-11-19 15:45:17 -0800313 hVendorTagSections[s].tags = tagsBySection[s];
314 }
315 HProviderIdAndVendorTagSections &hProviderIdAndVendorTagSections =
316 hTagIdsAndVendorTagSections[j];
317 hProviderIdAndVendorTagSections.providerId = vendorIdAndTagDescs.first;
318 hProviderIdAndVendorTagSections.vendorTagSections = std::move(hVendorTagSections);
319 j++;
Jayant Chowdharybe543d42018-08-15 13:16:14 -0700320 }
Jayant Chowdhary8cf92922018-11-19 15:45:17 -0800321 _hidl_cb(HStatus::NO_ERROR, hTagIdsAndVendorTagSections);
Jayant Chowdharybe543d42018-08-15 13:16:14 -0700322 return Void();
323}
324
325} // implementation
326} // V2_0
327} // service
328} // cameraservice
329} // frameworks
330} // android
331