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