blob: 7f674bd7b8008aeeeef47499d429badc2358e2ac [file] [log] [blame]
Avichal Rakeshfcb78cb2022-10-27 15:45:54 -07001/*
2 * Copyright (C) 2022 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#define LOG_TAG "AidlCameraService"
18
19#include "AidlCameraService.h"
20#include <aidl/AidlCameraDeviceCallbacks.h>
21#include <aidl/AidlCameraDeviceUser.h>
22#include <aidl/AidlCameraServiceListener.h>
23#include <aidl/AidlUtils.h>
24#include <aidl/android/frameworks/cameraservice/common/CameraMetadataType.h>
25#include <android-base/properties.h>
26#include <android/binder_ibinder.h>
27#include <android/binder_manager.h>
28#include <binder/Status.h>
Biswarup Pal37a75182024-01-16 15:53:35 +000029#include <camera/CameraUtils.h>
Avichal Rakeshfcb78cb2022-10-27 15:45:54 -070030#include <hidl/HidlTransportSupport.h>
Austin Borger65e64642024-06-11 15:58:23 -070031#include <utils/AttributionAndPermissionUtils.h>
Avichal Rakesh74b5ae72023-12-27 16:56:45 -080032#include <utils/Utils.h>
Avichal Rakeshfcb78cb2022-10-27 15:45:54 -070033
34namespace android::frameworks::cameraservice::service::implementation {
35
36using ::android::frameworks::cameraservice::device::implementation::AidlCameraDeviceCallbacks;
37using ::android::frameworks::cameraservice::device::implementation::AidlCameraDeviceUser;
38using ::android::hardware::cameraservice::utils::conversion::aidl::areBindersEqual;
39using ::android::hardware::cameraservice::utils::conversion::aidl::cloneToAidl;
40using ::android::hardware::cameraservice::utils::conversion::aidl::convertToAidl;
41using ::android::hardware::cameraservice::utils::conversion::aidl::filterVndkKeys;
Jayant Chowdhary81d81b02024-02-15 19:13:39 +000042using hardware::BnCameraService::ROTATION_OVERRIDE_NONE;
Avichal Rakeshfcb78cb2022-10-27 15:45:54 -070043using ::ndk::ScopedAStatus;
44
45// VNDK classes
46using SCameraMetadataType = ::aidl::android::frameworks::cameraservice::common::CameraMetadataType;
47using SVendorTag = ::aidl::android::frameworks::cameraservice::common::VendorTag;
48using SVendorTagSection = ::aidl::android::frameworks::cameraservice::common::VendorTagSection;
49// NDK classes
50using UICameraService = ::android::hardware::ICameraService;
51using UStatus = ::android::binder::Status;
52
53namespace {
54inline ScopedAStatus fromSStatus(const SStatus& s) {
55 return s == SStatus::NO_ERROR ? ScopedAStatus::ok()
56 : ScopedAStatus::fromServiceSpecificError(
57 static_cast<int32_t>(s));
58}
59inline ScopedAStatus fromUStatus(const UStatus& s) {
60 return s.isOk() ? ScopedAStatus::ok() : fromSStatus(convertToAidl(s));
61}
62} // anonymous namespace
63
64std::shared_ptr<AidlCameraService> kCameraService;
65
66bool AidlCameraService::registerService(::android::CameraService* cameraService) {
67 kCameraService = SharedRefBase::make<AidlCameraService>(cameraService);
68 std::string serviceName = SBnCameraService::descriptor;
69 serviceName += "/default";
70 bool isDeclared = AServiceManager_isDeclared(serviceName.c_str());
71 if (!isDeclared) {
72 ALOGI("%s: AIDL vndk not declared.", __FUNCTION__);
73 return false;
74 }
75
76 binder_exception_t registered = AServiceManager_addService(
77 kCameraService->asBinder().get(), serviceName.c_str());
78 ALOGE_IF(registered != EX_NONE,
79 "%s: AIDL VNDK declared, but failed to register service: %d",
80 __FUNCTION__, registered);
81 return registered == EX_NONE;
82}
83
84AidlCameraService::AidlCameraService(::android::CameraService* cameraService):
85 mCameraService(cameraService) {
Avichal Rakesh74b5ae72023-12-27 16:56:45 -080086 mVndkVersion = getVNDKVersionFromProp(__ANDROID_API_FUTURE__);
Avichal Rakeshfcb78cb2022-10-27 15:45:54 -070087}
88ScopedAStatus AidlCameraService::getCameraCharacteristics(const std::string& in_cameraId,
89 SCameraMetadata* _aidl_return) {
90 if (_aidl_return == nullptr) { return fromSStatus(SStatus::ILLEGAL_ARGUMENT); }
91
92 ::android::CameraMetadata cameraMetadata;
Austin Borger65e64642024-06-11 15:58:23 -070093 AttributionSourceState clientAttribution =
94 AttributionAndPermissionUtils::buildAttributionSource(
95 hardware::ICameraService::USE_CALLING_PID,
96 hardware::ICameraService::USE_CALLING_UID,
97 kDefaultDeviceId);
Austin Borger71d8f672023-06-01 16:51:35 -070098 UStatus ret = mCameraService->getCameraCharacteristics(in_cameraId,
Avichal Rakeshfcb78cb2022-10-27 15:45:54 -070099 mVndkVersion,
Jayant Chowdhary81d81b02024-02-15 19:13:39 +0000100 ROTATION_OVERRIDE_NONE,
Austin Borger65e64642024-06-11 15:58:23 -0700101 clientAttribution,
Biswarup Pal37a75182024-01-16 15:53:35 +0000102 /* devicePolicy= */ 0,
Avichal Rakeshfcb78cb2022-10-27 15:45:54 -0700103 &cameraMetadata);
104 if (!ret.isOk()) {
105 if (ret.exceptionCode() != EX_SERVICE_SPECIFIC) {
106 ALOGE("%s: Transaction error when getting camera characteristics"
107 " from camera service: %d.",
108 __FUNCTION__ , ret.exceptionCode());
109 return fromUStatus(ret);
110 }
111 switch (ret.serviceSpecificErrorCode()) {
112 case UICameraService::ERROR_ILLEGAL_ARGUMENT:
113 ALOGE("%s: Camera ID %s does not exist!", __FUNCTION__, in_cameraId.c_str());
114 return fromSStatus(SStatus::ILLEGAL_ARGUMENT);
115 default:
116 ALOGE("Get camera characteristics from camera service failed: %s",
Tomasz Wasilczyk67b5ebc2023-08-30 17:45:57 +0000117 ret.toString8().c_str());
Avichal Rakeshfcb78cb2022-10-27 15:45:54 -0700118 return fromUStatus(ret);
119 }
120 }
121
122 if (filterVndkKeys(mVndkVersion, cameraMetadata) != OK) {
123 ALOGE("%s: Unable to filter vndk metadata keys for version %d",
124 __FUNCTION__, mVndkVersion);
125 return fromSStatus(SStatus::UNKNOWN_ERROR);
126 }
127
128 const camera_metadata_t* rawMetadata = cameraMetadata.getAndLock();
129 cloneToAidl(rawMetadata, _aidl_return);
130 cameraMetadata.unlock(rawMetadata);
131
132 return ScopedAStatus::ok();
133}
134ndk::ScopedAStatus AidlCameraService::connectDevice(
135 const std::shared_ptr<SICameraDeviceCallback>& in_callback,
136 const std::string& in_cameraId,
137 std::shared_ptr<SICameraDeviceUser>* _aidl_return) {
138 // Here, we first get NDK ICameraDeviceUser from mCameraService, then save
139 // that interface in the newly created AidlCameraDeviceUser impl class.
140 if (mCameraService == nullptr) {
141 return fromSStatus(SStatus::UNKNOWN_ERROR);
142 }
143 sp<hardware::camera2::ICameraDeviceUser> unstableDevice = nullptr;
144 // Create a hardware::camera2::ICameraDeviceCallback object which internally
145 // calls callback functions passed through hCallback.
146 sp<AidlCameraDeviceCallbacks> hybridCallbacks = new AidlCameraDeviceCallbacks(in_callback);
147 if (!hybridCallbacks->initializeLooper(mVndkVersion)) {
148 ALOGE("Unable to handle callbacks on device, cannot connect");
149 return fromSStatus(SStatus::UNKNOWN_ERROR);
150 }
151 sp<hardware::camera2::ICameraDeviceCallbacks> callbacks = hybridCallbacks;
Austin Borger65e64642024-06-11 15:58:23 -0700152 AttributionSourceState clientAttribution =
153 AttributionAndPermissionUtils::buildAttributionSource(
154 hardware::ICameraService::USE_CALLING_PID,
155 hardware::ICameraService::USE_CALLING_UID,
156 kDefaultDeviceId);
Austin Borgerd1ad6c62024-07-01 11:28:31 -0700157 clientAttribution.packageName = "";
158 clientAttribution.attributionTag = std::nullopt;
Avichal Rakeshfcb78cb2022-10-27 15:45:54 -0700159 binder::Status serviceRet = mCameraService->connectDevice(
160 callbacks,
Austin Borger71d8f672023-06-01 16:51:35 -0700161 in_cameraId,
Avichal Rakeshfcb78cb2022-10-27 15:45:54 -0700162 /* scoreOffset= */ 0,
163 /* targetSdkVersion= */ __ANDROID_API_FUTURE__,
Jayant Chowdhary81d81b02024-02-15 19:13:39 +0000164 ROTATION_OVERRIDE_NONE,
Austin Borger65e64642024-06-11 15:58:23 -0700165 clientAttribution,
Biswarup Pal37a75182024-01-16 15:53:35 +0000166 /* devicePolicy= */ 0,
Avichal Rakeshfcb78cb2022-10-27 15:45:54 -0700167 &unstableDevice);
168 if (!serviceRet.isOk()) {
169 ALOGE("%s: Unable to connect to camera device: %s", __FUNCTION__,
170 serviceRet.toString8().c_str());
171 return fromUStatus(serviceRet);
172 }
173
174 // Now we create a AidlCameraDeviceUser class, store the unstableDevice in it,
175 // and return that back. All calls on that interface will be forwarded to
176 // the NDK AIDL interface.
177 std::shared_ptr<AidlCameraDeviceUser> stableDevice =
178 ndk::SharedRefBase::make<AidlCameraDeviceUser>(unstableDevice);
179 if (!stableDevice->initStatus()) {
180 ALOGE("%s: Unable to initialize camera device AIDL wrapper", __FUNCTION__);
181 return fromSStatus(SStatus::UNKNOWN_ERROR);
182 }
183 hybridCallbacks->setCaptureResultMetadataQueue(
184 stableDevice->getCaptureResultMetadataQueue());
185 *_aidl_return = stableDevice;
186 return ScopedAStatus::ok();
187}
188void AidlCameraService::addToListenerCacheLocked(
189 std::shared_ptr<SICameraServiceListener> stableCsListener,
190 sp<UICameraServiceListener> csListener) {
191 mListeners.emplace_back(std::make_pair(stableCsListener, csListener));
192}
193sp<UICameraServiceListener> AidlCameraService::searchListenerCacheLocked(
194 const std::shared_ptr<SICameraServiceListener>& listener, bool removeIfFound) {
195 // Go through the mListeners list and compare the listener with the VNDK AIDL
196 // listener registered.
197 if (listener == nullptr) {
198 return nullptr;
199 }
200
201 auto it = mListeners.begin();
202 sp<UICameraServiceListener> csListener = nullptr;
203 for (;it != mListeners.end(); it++) {
204 if (areBindersEqual(listener->asBinder(), it->first->asBinder())) {
205 break;
206 }
207 }
208 if (it != mListeners.end()) {
209 csListener = it->second;
210 if (removeIfFound) {
211 mListeners.erase(it);
212 }
213 }
214 return csListener;
215}
216ndk::ScopedAStatus AidlCameraService::addListener(
217 const std::shared_ptr<SICameraServiceListener>& in_listener,
218 std::vector<SCameraStatusAndId>* _aidl_return) {
219 std::vector<hardware::CameraStatus> cameraStatusAndIds{};
220 SStatus status = addListenerInternal(
221 in_listener, &cameraStatusAndIds);
222 if (status != SStatus::NO_ERROR) {
223 return fromSStatus(status);
224 }
225
226 // Convert cameraStatusAndIds to VNDK AIDL
227 convertToAidl(cameraStatusAndIds, _aidl_return);
228 return ScopedAStatus::ok();
229}
230SStatus AidlCameraService::addListenerInternal(
231 const std::shared_ptr<SICameraServiceListener>& listener,
232 std::vector<hardware::CameraStatus>* cameraStatusAndIds) {
233 if (mCameraService == nullptr) {
234 return SStatus::UNKNOWN_ERROR;
235 }
236 if (listener == nullptr || cameraStatusAndIds == nullptr) {
237 ALOGE("%s listener and cameraStatusAndIds must not be NULL", __FUNCTION__);
238 return SStatus::ILLEGAL_ARGUMENT;
239 }
240 sp<UICameraServiceListener> csListener = nullptr;
241 // Check the cache for previously registered callbacks
242 {
243 Mutex::Autolock l(mListenerListLock);
244 csListener = searchListenerCacheLocked(listener);
245 if (csListener == nullptr) {
246 // Wrap a listener with AidlCameraServiceListener and pass it to
247 // CameraService.
248 csListener = sp<AidlCameraServiceListener>::make(listener);
249 // Add to cache
250 addToListenerCacheLocked(listener, csListener);
251 } else {
252 ALOGE("%s: Trying to add a listener %p already registered",
253 __FUNCTION__, listener.get());
254 return SStatus::ILLEGAL_ARGUMENT;
255 }
256 }
257 binder::Status serviceRet =
258 mCameraService->addListenerHelper(csListener, cameraStatusAndIds, true);
259 if (!serviceRet.isOk()) {
260 ALOGE("%s: Unable to add camera device status listener", __FUNCTION__);
261 return convertToAidl(serviceRet);
262 }
263
264 cameraStatusAndIds->erase(std::remove_if(cameraStatusAndIds->begin(),
265 cameraStatusAndIds->end(),
266 [this](const hardware::CameraStatus& s) {
267 bool supportsHAL3 = false;
268 binder::Status sRet =
Austin Borger71d8f672023-06-01 16:51:35 -0700269 mCameraService->supportsCameraApi(s.cameraId,
Avichal Rakeshfcb78cb2022-10-27 15:45:54 -0700270 UICameraService::API_VERSION_2, &supportsHAL3);
271 return !sRet.isOk() || !supportsHAL3;
272 }), cameraStatusAndIds->end());
273
274 return SStatus::NO_ERROR;
275}
276ndk::ScopedAStatus AidlCameraService::removeListener(
277 const std::shared_ptr<SICameraServiceListener>& in_listener) {
278 if (in_listener == nullptr) {
279 ALOGE("%s listener must not be NULL", __FUNCTION__);
280 return fromSStatus(SStatus::ILLEGAL_ARGUMENT);
281 }
282 sp<UICameraServiceListener> csListener = nullptr;
283 {
284 Mutex::Autolock l(mListenerListLock);
285 csListener = searchListenerCacheLocked(in_listener, /*removeIfFound*/true);
286 }
287 if (csListener != nullptr) {
288 mCameraService->removeListener(csListener);
289 } else {
290 ALOGE("%s Removing unregistered listener %p", __FUNCTION__, in_listener.get());
291 return fromSStatus(SStatus::ILLEGAL_ARGUMENT);
292 }
293 return ScopedAStatus::ok();
294}
295ndk::ScopedAStatus AidlCameraService::getCameraVendorTagSections(
296 std::vector<SProviderIdAndVendorTagSections>* _aidl_return) {
297 sp<VendorTagDescriptorCache> gCache = VendorTagDescriptorCache::getGlobalVendorTagCache();
298 if (gCache == nullptr) {
299 return fromSStatus(SStatus::UNKNOWN_ERROR);
300 }
301
302 const std::unordered_map<metadata_vendor_id_t, sp<android::VendorTagDescriptor>>
303 &vendorIdsAndTagDescs = gCache->getVendorIdsAndTagDescriptors();
304 if (vendorIdsAndTagDescs.empty()) {
305 return fromSStatus(SStatus::UNKNOWN_ERROR);
306 }
307
308 std::vector<SProviderIdAndVendorTagSections>& tagIdAndVendorTagSections = *_aidl_return;
309 tagIdAndVendorTagSections.resize(vendorIdsAndTagDescs.size());
310 size_t j = 0;
311 for (auto &vendorIdAndTagDescs : vendorIdsAndTagDescs) {
312 std::vector<SVendorTagSection> vendorTagSections;
313 sp<VendorTagDescriptor> desc = vendorIdAndTagDescs.second;
314 const SortedVector<String8>* sectionNames = desc->getAllSectionNames();
315 size_t numSections = sectionNames->size();
316 std::vector<std::vector<SVendorTag>> tagsBySection(numSections);
317 int tagCount = desc->getTagCount();
318 if (tagCount <= 0) {
319 continue;
320 }
321 std::vector<uint32_t> tags(tagCount);
322 desc->getTagArray(tags.data());
323 for (int i = 0; i < tagCount; i++) {
324 SVendorTag vt;
325 vt.tagId = tags[i];
326 vt.tagName = desc->getTagName(tags[i]);
327 vt.tagType = (SCameraMetadataType) desc->getTagType(tags[i]);
328 ssize_t sectionIdx = desc->getSectionIndex(tags[i]);
329 tagsBySection[sectionIdx].push_back(vt);
330 }
331 vendorTagSections.resize(numSections);
332 for (size_t s = 0; s < numSections; s++) {
Tomasz Wasilczyk67b5ebc2023-08-30 17:45:57 +0000333 vendorTagSections[s].sectionName = (*sectionNames)[s].c_str();
Avichal Rakeshfcb78cb2022-10-27 15:45:54 -0700334 vendorTagSections[s].tags = tagsBySection[s];
335 }
336 SProviderIdAndVendorTagSections & prvdrIdAndVendorTagSection =
337 tagIdAndVendorTagSections[j];
338 prvdrIdAndVendorTagSection.providerId = vendorIdAndTagDescs.first;
339 prvdrIdAndVendorTagSection.vendorTagSections = std::move(vendorTagSections);
340 j++;
341 }
342 return ScopedAStatus::ok();
343}
344
345} // namespace android::frameworks::cameraservice::service::implementation