• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
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 
31 namespace android::frameworks::cameraservice::service::implementation {
32 
33 using ::android::frameworks::cameraservice::device::implementation::AidlCameraDeviceCallbacks;
34 using ::android::frameworks::cameraservice::device::implementation::AidlCameraDeviceUser;
35 using ::android::hardware::cameraservice::utils::conversion::aidl::areBindersEqual;
36 using ::android::hardware::cameraservice::utils::conversion::aidl::cloneToAidl;
37 using ::android::hardware::cameraservice::utils::conversion::aidl::convertToAidl;
38 using ::android::hardware::cameraservice::utils::conversion::aidl::filterVndkKeys;
39 using ::ndk::ScopedAStatus;
40 
41 // VNDK classes
42 using SCameraMetadataType = ::aidl::android::frameworks::cameraservice::common::CameraMetadataType;
43 using SVendorTag = ::aidl::android::frameworks::cameraservice::common::VendorTag;
44 using SVendorTagSection = ::aidl::android::frameworks::cameraservice::common::VendorTagSection;
45 // NDK classes
46 using UICameraService = ::android::hardware::ICameraService;
47 using UStatus = ::android::binder::Status;
48 
49 namespace {
fromSStatus(const SStatus & s)50 inline ScopedAStatus fromSStatus(const SStatus& s) {
51     return s == SStatus::NO_ERROR ? ScopedAStatus::ok()
52                                   : ScopedAStatus::fromServiceSpecificError(
53                                             static_cast<int32_t>(s));
54 }
fromUStatus(const UStatus & s)55 inline ScopedAStatus fromUStatus(const UStatus& s) {
56     return s.isOk() ? ScopedAStatus::ok() : fromSStatus(convertToAidl(s));
57 }
58 } // anonymous namespace
59 
60 std::shared_ptr<AidlCameraService> kCameraService;
61 
registerService(::android::CameraService * cameraService)62 bool 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 
AidlCameraService(::android::CameraService * cameraService)80 AidlCameraService::AidlCameraService(::android::CameraService* cameraService):
81       mCameraService(cameraService) {
82     mVndkVersion = base::GetIntProperty("ro.vndk.version", __ANDROID_API_FUTURE__);
83 }
getCameraCharacteristics(const std::string & in_cameraId,SCameraMetadata * _aidl_return)84 ScopedAStatus 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 }
connectDevice(const std::shared_ptr<SICameraDeviceCallback> & in_callback,const std::string & in_cameraId,std::shared_ptr<SICameraDeviceUser> * _aidl_return)123 ndk::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 }
addToListenerCacheLocked(std::shared_ptr<SICameraServiceListener> stableCsListener,sp<UICameraServiceListener> csListener)171 void AidlCameraService::addToListenerCacheLocked(
172         std::shared_ptr<SICameraServiceListener> stableCsListener,
173         sp<UICameraServiceListener> csListener) {
174     mListeners.emplace_back(std::make_pair(stableCsListener, csListener));
175 }
searchListenerCacheLocked(const std::shared_ptr<SICameraServiceListener> & listener,bool removeIfFound)176 sp<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 }
addListener(const std::shared_ptr<SICameraServiceListener> & in_listener,std::vector<SCameraStatusAndId> * _aidl_return)199 ndk::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 }
addListenerInternal(const std::shared_ptr<SICameraServiceListener> & listener,std::vector<hardware::CameraStatus> * cameraStatusAndIds)213 SStatus 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 }
removeListener(const std::shared_ptr<SICameraServiceListener> & in_listener)259 ndk::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 }
getCameraVendorTagSections(std::vector<SProviderIdAndVendorTagSections> * _aidl_return)278 ndk::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
329