blob: 31bdf6de206b896b1eeab3a1706b45d05795868d [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
17#include <hidl/Convert.h>
18
19#include <hidl/HidlCameraService.h>
Jayant Chowdhary0c947272018-08-15 14:42:04 -070020
21#include <hidl/HidlCameraDeviceUser.h>
22#include <hidl/AidlCameraDeviceCallbacks.h>
Jayant Chowdhary94f79a92018-08-15 13:57:17 -070023#include <hidl/AidlCameraServiceListener.h>
Jayant Chowdharybe543d42018-08-15 13:16:14 -070024
25#include <hidl/HidlTransportSupport.h>
26
27namespace android {
28namespace frameworks {
29namespace cameraservice {
30namespace service {
31namespace V2_0 {
32namespace implementation {
33
34using frameworks::cameraservice::service::V2_0::implementation::HidlCameraService;
35using hardware::hidl_vec;
36using hardware::cameraservice::utils::conversion::convertToHidl;
37using hardware::cameraservice::utils::conversion::B2HStatus;
38using hardware::Void;
39
Jayant Chowdhary0c947272018-08-15 14:42:04 -070040using device::V2_0::implementation::H2BCameraDeviceCallbacks;
41using device::V2_0::implementation::HidlCameraDeviceUser;
Jayant Chowdhary94f79a92018-08-15 13:57:17 -070042using service::V2_0::implementation::H2BCameraServiceListener;
Jayant Chowdharybe543d42018-08-15 13:16:14 -070043using HCameraMetadataType = android::frameworks::cameraservice::common::V2_0::CameraMetadataType;
44using HVendorTag = android::frameworks::cameraservice::common::V2_0::VendorTag;
45using HVendorTagSection = android::frameworks::cameraservice::common::V2_0::VendorTagSection;
46
47sp<HidlCameraService> gHidlCameraService;
48
49sp<HidlCameraService> HidlCameraService::getInstance(android::CameraService *cs) {
50 gHidlCameraService = new HidlCameraService(cs);
51 return gHidlCameraService;
52}
53
54Return<void>
55HidlCameraService::getCameraCharacteristics(const hidl_string& cameraId,
56 getCameraCharacteristics_cb _hidl_cb) {
57 android::CameraMetadata cameraMetadata;
58 HStatus status = HStatus::NO_ERROR;
59 binder::Status serviceRet =
60 mAidlICameraService->getCameraCharacteristics(String16(cameraId.c_str()), &cameraMetadata);
61 HCameraMetadata hidlMetadata;
62 if (!serviceRet.isOk()) {
63 switch(serviceRet.serviceSpecificErrorCode()) {
64 // No ERROR_CAMERA_DISCONNECTED since we're in the same process.
65 case hardware::ICameraService::ERROR_ILLEGAL_ARGUMENT:
66 ALOGE("%s: Camera ID %s does not exist!", __FUNCTION__, cameraId.c_str());
67 status = HStatus::ILLEGAL_ARGUMENT;
68 break;
69 default:
70 ALOGE("Get camera characteristics from camera service failed: %s",
71 serviceRet.toString8().string());
72 status = B2HStatus(serviceRet);
73 }
74 _hidl_cb(status, hidlMetadata);
75 return Void();
76 }
77 const camera_metadata_t *rawMetadata = cameraMetadata.getAndLock();
78 convertToHidl(rawMetadata, &hidlMetadata);
79 _hidl_cb(status, hidlMetadata);
80 cameraMetadata.unlock(rawMetadata);
81 return Void();
82}
83
84Return<void> HidlCameraService::connectDevice(const sp<HCameraDeviceCallback>& hCallback,
85 const hidl_string& cameraId,
86 connectDevice_cb _hidl_cb) {
Jayant Chowdhary0c947272018-08-15 14:42:04 -070087 // Here, we first get ICameraDeviceUser from mAidlICameraService, then save
88 // that interface in the newly created HidlCameraDeviceUser impl class.
89 if (mAidlICameraService == nullptr) {
90 _hidl_cb(HStatus::UNKNOWN_ERROR, nullptr);
91 return Void();
92 }
93 sp<hardware::camera2::ICameraDeviceUser> deviceRemote = nullptr;
94 // Create a hardware::camera2::ICameraDeviceCallback object which internally
95 // calls callback functions passed through hCallback.
96 sp<H2BCameraDeviceCallbacks> hybridCallbacks = new H2BCameraDeviceCallbacks(hCallback);
97 if (!hybridCallbacks->initializeLooper()) {
98 ALOGE("Unable to handle callbacks on device, cannot connect");
99 _hidl_cb(HStatus::UNKNOWN_ERROR, nullptr);
100 return Void();
101 }
102 sp<hardware::camera2::ICameraDeviceCallbacks> callbacks = hybridCallbacks;
103 binder::Status serviceRet = mAidlICameraService->connectDevice(
104 callbacks, String16(cameraId.c_str()), String16(""),
105 hardware::ICameraService::USE_CALLING_UID, /*out*/&deviceRemote);
106 HStatus status = HStatus::NO_ERROR;
107 if (!serviceRet.isOk()) {
108 ALOGE("%s: Unable to connect to camera device", __FUNCTION__);
109 status = B2HStatus(serviceRet);
110 _hidl_cb(status, nullptr);
111 return Void();
112 }
113 // Now we create a HidlCameraDeviceUser class, store the deviceRemote in it,
114 // and return that back. All calls on that interface will be forwarded to
115 // the AIDL interface.
116 sp<HidlCameraDeviceUser> hDeviceRemote = new HidlCameraDeviceUser(deviceRemote);
117 if (!hDeviceRemote->initStatus()) {
118 ALOGE("%s: Unable to initialize camera device HIDL wrapper", __FUNCTION__);
119 _hidl_cb(HStatus::UNKNOWN_ERROR, nullptr);
120 return Void();
121 }
122 hybridCallbacks->setCaptureResultMetadataQueue(hDeviceRemote->getCaptureResultMetadataQueue());
123 _hidl_cb(status, hDeviceRemote);
Jayant Chowdharybe543d42018-08-15 13:16:14 -0700124 return Void();
125}
126
Jayant Chowdhary94f79a92018-08-15 13:57:17 -0700127void HidlCameraService::addToListenerCacheLocked(sp<HCameraServiceListener> hListener,
128 sp<hardware::ICameraServiceListener> csListener) {
129 mListeners.emplace_back(std::make_pair(hListener, csListener));
130}
131
132sp<hardware::ICameraServiceListener>
133HidlCameraService::searchListenerCacheLocked(sp<HCameraServiceListener> hListener,
134 bool shouldRemove) {
135 // Go through the mListeners list and compare the listener with the HIDL
136 // listener registered.
137 auto it = mListeners.begin();
138 sp<ICameraServiceListener> csListener = nullptr;
139 for (;it != mListeners.end(); it++) {
140 if (hardware::interfacesEqual(it->first, hListener)) {
141 break;
142 }
143 }
144 if (it != mListeners.end()) {
145 csListener = it->second;
146 if (shouldRemove) {
147 mListeners.erase(it);
148 }
149 }
150 return csListener;
151}
152
Jayant Chowdharybe543d42018-08-15 13:16:14 -0700153Return<void> HidlCameraService::addListener(const sp<HCameraServiceListener>& hCsListener,
154 addListener_cb _hidl_cb) {
Jayant Chowdhary94f79a92018-08-15 13:57:17 -0700155 if (mAidlICameraService == nullptr) {
156 _hidl_cb(HStatus::UNKNOWN_ERROR, {});
157 return Void();
158 }
159 if (hCsListener == nullptr) {
160 ALOGE("%s listener must not be NULL", __FUNCTION__);
161 _hidl_cb(HStatus::ILLEGAL_ARGUMENT, {});
162 return Void();
163 }
164 sp<hardware::ICameraServiceListener> csListener = nullptr;
165 // Check the cache for previously registered callbacks
166 {
167 Mutex::Autolock l(mListenerListLock);
168 csListener = searchListenerCacheLocked(hCsListener);
169 if (csListener == nullptr) {
170 // Wrap an hCsListener with AidlCameraServiceListener and pass it to
171 // CameraService.
172 csListener = new H2BCameraServiceListener(hCsListener);
173 // Add to cache
174 addToListenerCacheLocked(hCsListener, csListener);
175 } else {
176 ALOGE("%s: Trying to add a listener %p already registered",
177 __FUNCTION__, hCsListener.get());
178 _hidl_cb(HStatus::ILLEGAL_ARGUMENT, {});
179 return Void();
180 }
181 }
182 std::vector<hardware::CameraStatus> cameraStatusAndIds{};
183 binder::Status serviceRet = mAidlICameraService->addListener(csListener, &cameraStatusAndIds);
184 HStatus status = HStatus::NO_ERROR;
185 if (!serviceRet.isOk()) {
186 ALOGE("%s: Unable to add camera device status listener", __FUNCTION__);
187 status = B2HStatus(serviceRet);
188 _hidl_cb(status, {});
189 return Void();
190 }
191 hidl_vec<HCameraStatusAndId> hCameraStatusAndIds;
192 //Convert cameraStatusAndIds to HIDL and call callback
193 convertToHidl(cameraStatusAndIds, &hCameraStatusAndIds);
194 _hidl_cb(status, hCameraStatusAndIds);
Jayant Chowdharybe543d42018-08-15 13:16:14 -0700195 return Void();
196}
197
198Return<HStatus> HidlCameraService::removeListener(const sp<HCameraServiceListener>& hCsListener) {
199 if (hCsListener == nullptr) {
200 ALOGE("%s listener must not be NULL", __FUNCTION__);
201 return HStatus::ILLEGAL_ARGUMENT;
202 }
Jayant Chowdhary94f79a92018-08-15 13:57:17 -0700203 sp<ICameraServiceListener> csListener = nullptr;
204 {
205 Mutex::Autolock l(mListenerListLock);
206 csListener = searchListenerCacheLocked(hCsListener, /*removeIfFound*/true);
207 }
208 if (csListener != nullptr) {
209 mAidlICameraService->removeListener(csListener);
210 } else {
211 ALOGE("%s Removing unregistered listener %p", __FUNCTION__, hCsListener.get());
212 return HStatus::ILLEGAL_ARGUMENT;
213 }
Jayant Chowdharybe543d42018-08-15 13:16:14 -0700214 return HStatus::NO_ERROR;
215}
216
217Return<void> HidlCameraService::getCameraVendorTagSections(getCameraVendorTagSections_cb _hidl_cb) {
218 hidl_vec<HVendorTagSection> hVendorTagSections;
219 // TODO: Could this be just created on the stack since we don't set it to
220 // global cache or anything ?
221 HStatus hStatus = HStatus::NO_ERROR;
222 sp<VendorTagDescriptor> desc = new VendorTagDescriptor();
223 binder::Status serviceRet = mAidlICameraService->getCameraVendorTagDescriptor(desc.get());
224
225 if (!serviceRet.isOk()) {
226 ALOGE("%s: Failed to get VendorTagDescriptor", __FUNCTION__);
227 _hidl_cb(B2HStatus(serviceRet), hVendorTagSections);
228 return Void();
229 }
230
231 const SortedVector<String8>* sectionNames = desc->getAllSectionNames();
232 size_t numSections = sectionNames->size();
233 std::vector<std::vector<HVendorTag>> tagsBySection(numSections);
234 int tagCount = desc->getTagCount();
235 std::vector<uint32_t> tags(tagCount);
236 desc->getTagArray(tags.data());
237 for (int i = 0; i < tagCount; i++) {
238 HVendorTag vt;
239 vt.tagId = tags[i];
240 vt.tagName = desc->getTagName(tags[i]);
241 vt.tagType = (HCameraMetadataType) desc->getTagType(tags[i]);
242 ssize_t sectionIdx = desc->getSectionIndex(tags[i]);
243 tagsBySection[sectionIdx].push_back(vt);
244 }
245 hVendorTagSections.resize(numSections);
246 for (size_t s = 0; s < numSections; s++) {
247 hVendorTagSections[s].sectionName = (*sectionNames)[s].string();
248 hVendorTagSections[s].tags = tagsBySection[s];
249 }
250 _hidl_cb(hStatus, hVendorTagSections);
251 return Void();
252}
253
254} // implementation
255} // V2_0
256} // service
257} // cameraservice
258} // frameworks
259} // android
260