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