• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
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 
17 #include <android-base/properties.h>
18 
19 #include <hidl/AidlCameraDeviceCallbacks.h>
20 #include <hidl/AidlCameraServiceListener.h>
21 #include <hidl/HidlCameraService.h>
22 #include <hidl/HidlCameraDeviceUser.h>
23 #include <hidl/Utils.h>
24 #include <aidl/AidlUtils.h>
25 
26 #include <hidl/HidlTransportSupport.h>
27 
28 namespace android {
29 namespace frameworks {
30 namespace cameraservice {
31 namespace service {
32 namespace V2_0 {
33 namespace implementation {
34 
35 using frameworks::cameraservice::service::V2_0::implementation::HidlCameraService;
36 using hardware::hidl_vec;
37 using hardware::cameraservice::utils::conversion::convertToHidl;
38 using hardware::cameraservice::utils::conversion::B2HStatus;
39 using hardware::Void;
40 using hardware::cameraservice::utils::conversion::aidl::filterVndkKeys;
41 
42 using device::V2_0::implementation::H2BCameraDeviceCallbacks;
43 using device::V2_1::implementation::HidlCameraDeviceUser;
44 using service::V2_0::implementation::H2BCameraServiceListener;
45 using HCameraMetadataType = frameworks::cameraservice::common::V2_0::CameraMetadataType;
46 using HVendorTag = frameworks::cameraservice::common::V2_0::VendorTag;
47 using HVendorTagSection = frameworks::cameraservice::common::V2_0::VendorTagSection;
48 using HProviderIdAndVendorTagSections =
49         frameworks::cameraservice::common::V2_0::ProviderIdAndVendorTagSections;
50 
51 sp<HidlCameraService> gHidlCameraService;
52 
getInstance(android::CameraService * cs)53 sp<HidlCameraService> HidlCameraService::getInstance(android::CameraService *cs) {
54     gHidlCameraService = new HidlCameraService(cs);
55     return gHidlCameraService;
56 }
57 
HidlCameraService(android::CameraService * cs)58 HidlCameraService::HidlCameraService(android::CameraService *cs) : mAidlICameraService(cs) {
59     mVndkVersion = base::GetIntProperty("ro.vndk.version", __ANDROID_API_FUTURE__);
60 };
61 
62 Return<void>
getCameraCharacteristics(const hidl_string & cameraId,getCameraCharacteristics_cb _hidl_cb)63 HidlCameraService::getCameraCharacteristics(const hidl_string& cameraId,
64                                             getCameraCharacteristics_cb _hidl_cb) {
65     android::CameraMetadata cameraMetadata;
66     HStatus status = HStatus::NO_ERROR;
67     binder::Status serviceRet =
68         mAidlICameraService->getCameraCharacteristics(String16(cameraId.c_str()),
69                 /*targetSdkVersion*/__ANDROID_API_FUTURE__, /*overrideToPortrait*/false,
70                 &cameraMetadata);
71     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     }
87     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     }
92     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 
connectDevice(const sp<HCameraDeviceCallback> & hCallback,const hidl_string & cameraId,connectDevice_cb _hidl_cb)99 Return<void> HidlCameraService::connectDevice(const sp<HCameraDeviceCallback>& hCallback,
100                                               const hidl_string& cameraId,
101                                               connectDevice_cb _hidl_cb) {
102     // 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);
112     if (!hybridCallbacks->initializeLooper(mVndkVersion)) {
113         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(
119             callbacks, String16(cameraId.c_str()), String16(""), {},
120             hardware::ICameraService::USE_CALLING_UID, 0/*oomScoreOffset*/,
121             /*targetSdkVersion*/__ANDROID_API_FUTURE__, /*overrideToPortrait*/false,
122             /*out*/&deviceRemote);
123     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);
141     return Void();
142 }
143 
addToListenerCacheLocked(sp<HCameraServiceListener> hListener,sp<hardware::ICameraServiceListener> csListener)144 void HidlCameraService::addToListenerCacheLocked(sp<HCameraServiceListener> hListener,
145                                                  sp<hardware::ICameraServiceListener> csListener) {
146         mListeners.emplace_back(std::make_pair(hListener, csListener));
147 }
148 
149 sp<hardware::ICameraServiceListener>
searchListenerCacheLocked(sp<HCameraServiceListener> hListener,bool shouldRemove)150 HidlCameraService::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 
addListener(const sp<HCameraServiceListener> & hCsListener,addListener_cb _hidl_cb)170 Return<void> HidlCameraService::addListener(const sp<HCameraServiceListener>& hCsListener,
171                                             addListener_cb _hidl_cb) {
172     std::vector<hardware::CameraStatus> cameraStatusAndIds{};
173     HStatus status = addListenerInternal<HCameraServiceListener>(
174             hCsListener, &cameraStatusAndIds);
175     if (status != HStatus::NO_ERROR) {
176         _hidl_cb(status, {});
177         return Void();
178     }
179 
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 
addListener_2_1(const sp<HCameraServiceListener2_1> & hCsListener,addListener_2_1_cb _hidl_cb)188 Return<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, {});
195         return Void();
196     }
197 
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 
206 template<class T>
addListenerInternal(const sp<T> & hCsListener,std::vector<hardware::CameraStatus> * cameraStatusAndIds)207 HStatus 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     }
216     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());
230             return HStatus::ILLEGAL_ARGUMENT;
231         }
232     }
233     binder::Status serviceRet =
234             mAidlICameraService->addListenerHelper(csListener, cameraStatusAndIds, true);
235     HStatus status = HStatus::NO_ERROR;
236     if (!serviceRet.isOk()) {
237         ALOGE("%s: Unable to add camera device status listener", __FUNCTION__);
238         status = B2HStatus(serviceRet);
239         return status;
240     }
241     cameraStatusAndIds->erase(std::remove_if(cameraStatusAndIds->begin(), cameraStatusAndIds->end(),
242             [this](const hardware::CameraStatus& s) {
243                 bool supportsHAL3 = false;
244                 binder::Status sRet =
245                             mAidlICameraService->supportsCameraApi(String16(s.cameraId),
246                                     hardware::ICameraService::API_VERSION_2, &supportsHAL3);
247                 return !sRet.isOk() || !supportsHAL3;
248             }), cameraStatusAndIds->end());
249 
250     return HStatus::NO_ERROR;
251 }
252 
removeListener(const sp<HCameraServiceListener> & hCsListener)253 Return<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     }
258     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     }
269     return HStatus::NO_ERROR;
270 }
271 
getCameraVendorTagSections(getCameraVendorTagSections_cb _hidl_cb)272 Return<void> HidlCameraService::getCameraVendorTagSections(getCameraVendorTagSections_cb _hidl_cb) {
273     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, {});
282         return Void();
283     }
284 
285     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();
295         if (tagCount <= 0) {
296             continue;
297         }
298         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++;
318     }
319     _hidl_cb(HStatus::NO_ERROR, hTagIdsAndVendorTagSections);
320     return Void();
321 }
322 
323 } // implementation
324 } // V2_0
325 } // service
326 } // cameraservice
327 } // frameworks
328 } // android
329 
330