• 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 "AidlCameraDeviceUser"
18 
19 #include "AidlCameraDeviceUser.h"
20 #include <aidl/AidlUtils.h>
21 #include <aidl/android/frameworks/cameraservice/device/CaptureMetadataInfo.h>
22 #include <android-base/properties.h>
23 
24 namespace android::frameworks::cameraservice::device::implementation {
25 
26 // VNDK classes
27 using SCaptureMetadataInfo = ::aidl::android::frameworks::cameraservice::device::CaptureMetadataInfo;
28 // NDK classes
29 using UOutputConfiguration = ::android::hardware::camera2::params::OutputConfiguration;
30 using USessionConfiguration = ::android::hardware::camera2::params::SessionConfiguration;
31 using UStatus = ::android::binder::Status;
32 using USubmitInfo = ::android::hardware::camera2::utils::SubmitInfo;
33 
34 using ::android::CameraMetadata;
35 using ::android::hardware::cameraservice::utils::conversion::aidl::cloneFromAidl;
36 using ::android::hardware::cameraservice::utils::conversion::aidl::cloneToAidl;
37 using ::android::hardware::cameraservice::utils::conversion::aidl::convertFromAidl;
38 using ::android::hardware::cameraservice::utils::conversion::aidl::convertToAidl;
39 using ::android::hardware::cameraservice::utils::conversion::aidl::filterVndkKeys;
40 using ::ndk::ScopedAStatus;
41 
42 namespace {
43 constexpr int32_t CAMERA_REQUEST_METADATA_QUEUE_SIZE = 1 << 20 /* 1 MB */;
44 constexpr int32_t CAMERA_RESULT_METADATA_QUEUE_SIZE = 1 << 20 /* 1 MB */;
45 
fromSStatus(const SStatus & s)46 inline ScopedAStatus fromSStatus(const SStatus& s) {
47     return s == SStatus::NO_ERROR ? ScopedAStatus::ok()
48                                   : ScopedAStatus::fromServiceSpecificError(
49                                             static_cast<int32_t>(s));
50 }
fromUStatus(const UStatus & status)51 inline ScopedAStatus fromUStatus(const UStatus& status) {
52     return status.isOk() ? ScopedAStatus::ok() : fromSStatus(convertToAidl(status));
53 }
54 } // anonymous namespace
55 
AidlCameraDeviceUser(const sp<UICameraDeviceUser> & deviceRemote)56 AidlCameraDeviceUser::AidlCameraDeviceUser(const sp<UICameraDeviceUser>& deviceRemote):
57       mDeviceRemote(deviceRemote) {
58     mInitSuccess = initDevice();
59     mVndkVersion = base::GetIntProperty("ro.vndk.version", __ANDROID_API_FUTURE__);
60 }
61 
initDevice()62 bool AidlCameraDeviceUser::initDevice() {
63     // TODO: Get request and result metadata queue size from a system property.
64     int32_t reqFMQSize = CAMERA_REQUEST_METADATA_QUEUE_SIZE;
65 
66     mCaptureRequestMetadataQueue =
67         std::make_unique<CaptureRequestMetadataQueue>(static_cast<size_t>(reqFMQSize),
68                                                       false /* non blocking */);
69     if (!mCaptureRequestMetadataQueue->isValid()) {
70         ALOGE("%s: invalid request fmq", __FUNCTION__);
71         return false;
72     }
73 
74     int32_t resFMQSize = CAMERA_RESULT_METADATA_QUEUE_SIZE;
75     mCaptureResultMetadataQueue =
76         std::make_shared<CaptureResultMetadataQueue>(static_cast<size_t>(resFMQSize),
77                                                      false /* non blocking */);
78     if (!mCaptureResultMetadataQueue->isValid()) {
79         ALOGE("%s: invalid result fmq", __FUNCTION__);
80         return false;
81     }
82     return true;
83 }
84 
getCaptureRequestMetadataQueue(MQDescriptor<int8_t,SynchronizedReadWrite> * _aidl_return)85 ndk::ScopedAStatus AidlCameraDeviceUser::getCaptureRequestMetadataQueue(
86         MQDescriptor<int8_t, SynchronizedReadWrite>* _aidl_return) {
87     if (mInitSuccess) {
88         *_aidl_return = mCaptureRequestMetadataQueue->dupeDesc();
89     }
90     return ScopedAStatus::ok();
91 }
92 
getCaptureResultMetadataQueue(MQDescriptor<int8_t,SynchronizedReadWrite> * _aidl_return)93 ndk::ScopedAStatus AidlCameraDeviceUser::getCaptureResultMetadataQueue(
94         MQDescriptor<int8_t, SynchronizedReadWrite>* _aidl_return) {
95     if (mInitSuccess) {
96         *_aidl_return = mCaptureResultMetadataQueue->dupeDesc();
97     }
98     return ScopedAStatus::ok();
99 }
100 
prepare(int32_t in_streamId)101 ndk::ScopedAStatus AidlCameraDeviceUser::prepare(int32_t in_streamId) {
102     UStatus ret = mDeviceRemote->prepare(in_streamId);
103     return fromUStatus(ret);
104 }
105 
submitRequestList(const std::vector<SCaptureRequest> & in_requestList,bool in_isRepeating,SSubmitInfo * _aidl_return)106 ndk::ScopedAStatus AidlCameraDeviceUser::submitRequestList(
107         const std::vector<SCaptureRequest>& in_requestList, bool in_isRepeating,
108         SSubmitInfo* _aidl_return) {
109     USubmitInfo submitInfo;
110     std::vector<UCaptureRequest> requests;
111     for (const auto& req: in_requestList) {
112         requests.emplace_back();
113         if (!convertRequestFromAidl(req, &requests.back())) {
114             ALOGE("%s: Failed to convert AIDL CaptureRequest.", __FUNCTION__);
115             return fromSStatus(SStatus::ILLEGAL_ARGUMENT);
116         }
117     }
118     UStatus ret = mDeviceRemote->submitRequestList(requests,
119                                                    in_isRepeating, &submitInfo);
120     if (!ret.isOk()) {
121         ALOGE("%s: Failed submitRequestList to cameraservice: %s",
122               __FUNCTION__, ret.toString8().string());
123         return fromUStatus(ret);
124     }
125     mRequestId = submitInfo.mRequestId;
126     convertToAidl(submitInfo, _aidl_return);
127     return ScopedAStatus::ok();
128 }
129 
cancelRepeatingRequest(int64_t * _aidl_return)130 ndk::ScopedAStatus AidlCameraDeviceUser::cancelRepeatingRequest(int64_t* _aidl_return) {
131     UStatus ret = mDeviceRemote->cancelRequest(mRequestId, _aidl_return);
132     return fromUStatus(ret);
133 }
134 
beginConfigure()135 ScopedAStatus AidlCameraDeviceUser::beginConfigure() {
136     UStatus ret = mDeviceRemote->beginConfigure();
137     return fromUStatus(ret);
138 }
139 
endConfigure(SStreamConfigurationMode in_operatingMode,const SCameraMetadata & in_sessionParams,int64_t in_startTimeNs)140 ndk::ScopedAStatus AidlCameraDeviceUser::endConfigure(SStreamConfigurationMode in_operatingMode,
141                                                       const SCameraMetadata& in_sessionParams,
142                                                       int64_t in_startTimeNs) {
143     CameraMetadata metadata;
144     if (!cloneFromAidl(in_sessionParams, &metadata)) {
145         return fromSStatus(SStatus::ILLEGAL_ARGUMENT);
146     }
147 
148     std::vector<int32_t> offlineStreamIds;
149     UStatus ret = mDeviceRemote->endConfigure(convertFromAidl(in_operatingMode),
150                                               metadata, in_startTimeNs,
151                                               &offlineStreamIds);
152     return fromUStatus(ret);
153 }
154 
createStream(const SOutputConfiguration & in_outputConfiguration,int32_t * _aidl_return)155 ndk::ScopedAStatus AidlCameraDeviceUser::createStream(
156         const SOutputConfiguration& in_outputConfiguration, int32_t* _aidl_return) {
157     UOutputConfiguration outputConfig = convertFromAidl(in_outputConfiguration);
158     int32_t newStreamId;
159     UStatus ret = mDeviceRemote->createStream(outputConfig, &newStreamId);
160     if (!ret.isOk()) {
161         ALOGE("%s: Failed to create stream: %s", __FUNCTION__, ret.toString8().string());
162     }
163     *_aidl_return = newStreamId;
164     return fromUStatus(ret);
165 }
166 
createDefaultRequest(STemplateId in_templateId,SCameraMetadata * _aidl_return)167 ndk::ScopedAStatus AidlCameraDeviceUser::createDefaultRequest(STemplateId in_templateId,
168                                                               SCameraMetadata* _aidl_return) {
169     CameraMetadata metadata;
170     UStatus ret = mDeviceRemote->createDefaultRequest(convertFromAidl(in_templateId),
171                                                       &metadata);
172     if (!ret.isOk()) {
173         ALOGE("%s: Failed to create default request: %s", __FUNCTION__, ret.toString8().string());
174         return fromUStatus(ret);
175     }
176 
177     if (filterVndkKeys(mVndkVersion, metadata, /*isStatic*/false) != OK) {
178         ALOGE("%s: Unable to filter vndk metadata keys for version %d",
179               __FUNCTION__, mVndkVersion);
180         return fromSStatus(SStatus::UNKNOWN_ERROR);
181     }
182 
183     const camera_metadata_t* rawMetadata = metadata.getAndLock();
184     cloneToAidl(rawMetadata, _aidl_return);
185     metadata.unlock(rawMetadata);
186     return ScopedAStatus::ok();
187 }
188 
waitUntilIdle()189 ndk::ScopedAStatus AidlCameraDeviceUser::waitUntilIdle() {
190     UStatus ret = mDeviceRemote->waitUntilIdle();
191     return fromUStatus(ret);
192 }
193 
flush(int64_t * _aidl_return)194 ndk::ScopedAStatus AidlCameraDeviceUser::flush(int64_t* _aidl_return) {
195     UStatus ret = mDeviceRemote->flush(_aidl_return);
196     return fromUStatus(ret);
197 }
198 
updateOutputConfiguration(int32_t in_streamId,const SOutputConfiguration & in_outputConfiguration)199 ndk::ScopedAStatus AidlCameraDeviceUser::updateOutputConfiguration(
200         int32_t in_streamId, const SOutputConfiguration& in_outputConfiguration) {
201     UOutputConfiguration outputConfig = convertFromAidl(in_outputConfiguration);
202     UStatus ret = mDeviceRemote->updateOutputConfiguration(in_streamId, outputConfig);
203     if (!ret.isOk()) {
204         ALOGE("%s: Failed to update output config for stream id: %d: %s",
205               __FUNCTION__, in_streamId, ret.toString8().string());
206     }
207     return fromUStatus(ret);
208 }
isSessionConfigurationSupported(const SSessionConfiguration & in_sessionConfiguration,bool * _aidl_return)209 ndk::ScopedAStatus AidlCameraDeviceUser::isSessionConfigurationSupported(
210         const SSessionConfiguration& in_sessionConfiguration, bool* _aidl_return) {
211     USessionConfiguration sessionConfig = convertFromAidl(in_sessionConfiguration);
212     UStatus ret = mDeviceRemote->isSessionConfigurationSupported(sessionConfig,
213                                                                  _aidl_return);
214     return fromUStatus(ret);
215 }
deleteStream(int32_t in_streamId)216 ndk::ScopedAStatus AidlCameraDeviceUser::deleteStream(int32_t in_streamId) {
217     UStatus ret = mDeviceRemote->deleteStream(in_streamId);
218     return fromUStatus(ret);
219 }
disconnect()220 ndk::ScopedAStatus AidlCameraDeviceUser::disconnect() {
221     UStatus ret = mDeviceRemote->disconnect();
222     return fromUStatus(ret);
223 }
convertRequestFromAidl(const SCaptureRequest & src,UCaptureRequest * dst)224 bool AidlCameraDeviceUser::convertRequestFromAidl(
225         const SCaptureRequest& src, UCaptureRequest* dst) {
226     dst->mIsReprocess = false;
227     for (const auto& streamAndWindowId : src.streamAndWindowIds) {
228         dst->mStreamIdxList.push_back(streamAndWindowId.streamId);
229         dst->mSurfaceIdxList.push_back(streamAndWindowId.windowId);
230     }
231 
232     return copyPhysicalCameraSettings(src.physicalCameraSettings,
233                                       &(dst->mPhysicalCameraSettings));
234 }
copyPhysicalCameraSettings(const std::vector<SPhysicalCameraSettings> & src,std::vector<UCaptureRequest::PhysicalCameraSettings> * dst)235 bool AidlCameraDeviceUser::copyPhysicalCameraSettings(
236         const std::vector<SPhysicalCameraSettings>& src,
237         std::vector<UCaptureRequest::PhysicalCameraSettings>* dst) {
238     bool converted = false;
239     for (auto &e : src) {
240         dst->emplace_back();
241         CaptureRequest::PhysicalCameraSettings &physicalCameraSetting =
242             dst->back();
243         physicalCameraSetting.id = e.id;
244 
245         // Read the settings either from the fmq or straightaway from the
246         // request. We don't need any synchronization, since submitRequestList
247         // is guaranteed to be called serially by the client if it decides to
248         // use fmq.
249         if (e.settings.getTag() == SCaptureMetadataInfo::fmqMetadataSize) {
250             /**
251              * Get settings from the fmq.
252              */
253             SCameraMetadata settingsFmq;
254             int64_t metadataSize = e.settings.get<SCaptureMetadataInfo::fmqMetadataSize>();
255             settingsFmq.metadata.resize(metadataSize);
256             int8_t* metadataPtr = (int8_t*) settingsFmq.metadata.data();
257             bool read = mCaptureRequestMetadataQueue->read(metadataPtr,
258                                                            metadataSize);
259             if (!read) {
260                 ALOGE("%s capture request settings could't be read from fmq size", __FUNCTION__);
261                 converted = false;
262             } else {
263                 converted = cloneFromAidl(settingsFmq, &physicalCameraSetting.settings);
264             }
265         } else {
266             /**
267              * The settings metadata is contained in request settings field.
268              */
269             converted = cloneFromAidl(e.settings.get<SCaptureMetadataInfo::metadata>(),
270                     &physicalCameraSetting.settings);
271         }
272         if (!converted) {
273           ALOGE("%s: Unable to convert physicalCameraSettings from HIDL to AIDL.", __FUNCTION__);
274           return false;
275         }
276     }
277     return true;
278 }
279 
280 } // namespace android::frameworks::cameraservice::device::implementation