blob: 402f8a23856661591586aae769a739ae982777dc [file] [log] [blame]
Avichal Rakeshfcb78cb2022-10-27 15:45:54 -07001/*
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>
Euisang Lim0dabcbb2023-04-04 17:38:32 +090022#include <android-base/properties.h>
Avichal Rakeshfcb78cb2022-10-27 15:45:54 -070023
24namespace android::frameworks::cameraservice::device::implementation {
25
26// VNDK classes
27using SCaptureMetadataInfo = ::aidl::android::frameworks::cameraservice::device::CaptureMetadataInfo;
28// NDK classes
29using UOutputConfiguration = ::android::hardware::camera2::params::OutputConfiguration;
30using USessionConfiguration = ::android::hardware::camera2::params::SessionConfiguration;
31using UStatus = ::android::binder::Status;
32using USubmitInfo = ::android::hardware::camera2::utils::SubmitInfo;
33
34using ::android::CameraMetadata;
35using ::android::hardware::cameraservice::utils::conversion::aidl::cloneFromAidl;
36using ::android::hardware::cameraservice::utils::conversion::aidl::cloneToAidl;
37using ::android::hardware::cameraservice::utils::conversion::aidl::convertFromAidl;
38using ::android::hardware::cameraservice::utils::conversion::aidl::convertToAidl;
Euisang Lim0dabcbb2023-04-04 17:38:32 +090039using ::android::hardware::cameraservice::utils::conversion::aidl::filterVndkKeys;
Avichal Rakeshfcb78cb2022-10-27 15:45:54 -070040using ::ndk::ScopedAStatus;
41
42namespace {
43constexpr int32_t CAMERA_REQUEST_METADATA_QUEUE_SIZE = 1 << 20 /* 1 MB */;
44constexpr int32_t CAMERA_RESULT_METADATA_QUEUE_SIZE = 1 << 20 /* 1 MB */;
45
46inline ScopedAStatus fromSStatus(const SStatus& s) {
47 return s == SStatus::NO_ERROR ? ScopedAStatus::ok()
48 : ScopedAStatus::fromServiceSpecificError(
49 static_cast<int32_t>(s));
50}
51inline ScopedAStatus fromUStatus(const UStatus& status) {
52 return status.isOk() ? ScopedAStatus::ok() : fromSStatus(convertToAidl(status));
53}
54} // anonymous namespace
55
56AidlCameraDeviceUser::AidlCameraDeviceUser(const sp<UICameraDeviceUser>& deviceRemote):
57 mDeviceRemote(deviceRemote) {
58 mInitSuccess = initDevice();
Euisang Lim0dabcbb2023-04-04 17:38:32 +090059 mVndkVersion = base::GetIntProperty("ro.vndk.version", __ANDROID_API_FUTURE__);
Avichal Rakeshfcb78cb2022-10-27 15:45:54 -070060}
Jayant Chowdhary09b368b2023-02-13 06:53:05 +000061
Avichal Rakeshfcb78cb2022-10-27 15:45:54 -070062bool 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
85ndk::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
93ndk::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
Jayant Chowdhary09b368b2023-02-13 06:53:05 +0000101ndk::ScopedAStatus AidlCameraDeviceUser::prepare(int32_t in_streamId) {
102 UStatus ret = mDeviceRemote->prepare(in_streamId);
103 return fromUStatus(ret);
104}
105
Avichal Rakeshfcb78cb2022-10-27 15:45:54 -0700106ndk::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
130ndk::ScopedAStatus AidlCameraDeviceUser::cancelRepeatingRequest(int64_t* _aidl_return) {
131 UStatus ret = mDeviceRemote->cancelRequest(mRequestId, _aidl_return);
132 return fromUStatus(ret);
133}
134
135ScopedAStatus AidlCameraDeviceUser::beginConfigure() {
136 UStatus ret = mDeviceRemote->beginConfigure();
137 return fromUStatus(ret);
138}
139
140ndk::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
155ndk::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
167ndk::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 }
Euisang Lim0dabcbb2023-04-04 17:38:32 +0900176
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
Avichal Rakeshfcb78cb2022-10-27 15:45:54 -0700183 const camera_metadata_t* rawMetadata = metadata.getAndLock();
184 cloneToAidl(rawMetadata, _aidl_return);
185 metadata.unlock(rawMetadata);
186 return ScopedAStatus::ok();
187}
188
189ndk::ScopedAStatus AidlCameraDeviceUser::waitUntilIdle() {
190 UStatus ret = mDeviceRemote->waitUntilIdle();
191 return fromUStatus(ret);
192}
193
194ndk::ScopedAStatus AidlCameraDeviceUser::flush(int64_t* _aidl_return) {
195 UStatus ret = mDeviceRemote->flush(_aidl_return);
196 return fromUStatus(ret);
197}
198
199ndk::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}
209ndk::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}
216ndk::ScopedAStatus AidlCameraDeviceUser::deleteStream(int32_t in_streamId) {
217 UStatus ret = mDeviceRemote->deleteStream(in_streamId);
218 return fromUStatus(ret);
219}
220ndk::ScopedAStatus AidlCameraDeviceUser::disconnect() {
221 UStatus ret = mDeviceRemote->disconnect();
222 return fromUStatus(ret);
223}
224bool 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}
235bool 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