blob: fc987b2a77560dc2612746bd9efcb2132f78dbba [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 Rakesh74b5ae72023-12-27 16:56:45 -080023#include <utils/Utils.h>
Avichal Rakeshfcb78cb2022-10-27 15:45:54 -070024
25namespace android::frameworks::cameraservice::device::implementation {
26
27// VNDK classes
28using SCaptureMetadataInfo = ::aidl::android::frameworks::cameraservice::device::CaptureMetadataInfo;
29// NDK classes
30using UOutputConfiguration = ::android::hardware::camera2::params::OutputConfiguration;
31using USessionConfiguration = ::android::hardware::camera2::params::SessionConfiguration;
32using UStatus = ::android::binder::Status;
33using USubmitInfo = ::android::hardware::camera2::utils::SubmitInfo;
34
35using ::android::CameraMetadata;
36using ::android::hardware::cameraservice::utils::conversion::aidl::cloneFromAidl;
37using ::android::hardware::cameraservice::utils::conversion::aidl::cloneToAidl;
38using ::android::hardware::cameraservice::utils::conversion::aidl::convertFromAidl;
39using ::android::hardware::cameraservice::utils::conversion::aidl::convertToAidl;
Euisang Lim0dabcbb2023-04-04 17:38:32 +090040using ::android::hardware::cameraservice::utils::conversion::aidl::filterVndkKeys;
Avichal Rakeshfcb78cb2022-10-27 15:45:54 -070041using ::ndk::ScopedAStatus;
42
43namespace {
44constexpr int32_t CAMERA_REQUEST_METADATA_QUEUE_SIZE = 1 << 20 /* 1 MB */;
45constexpr int32_t CAMERA_RESULT_METADATA_QUEUE_SIZE = 1 << 20 /* 1 MB */;
46
47inline ScopedAStatus fromSStatus(const SStatus& s) {
48 return s == SStatus::NO_ERROR ? ScopedAStatus::ok()
49 : ScopedAStatus::fromServiceSpecificError(
50 static_cast<int32_t>(s));
51}
52inline ScopedAStatus fromUStatus(const UStatus& status) {
53 return status.isOk() ? ScopedAStatus::ok() : fromSStatus(convertToAidl(status));
54}
55} // anonymous namespace
56
57AidlCameraDeviceUser::AidlCameraDeviceUser(const sp<UICameraDeviceUser>& deviceRemote):
58 mDeviceRemote(deviceRemote) {
59 mInitSuccess = initDevice();
Avichal Rakesh74b5ae72023-12-27 16:56:45 -080060 mVndkVersion = getVNDKVersionFromProp(__ANDROID_API_FUTURE__);
Avichal Rakeshfcb78cb2022-10-27 15:45:54 -070061}
Jayant Chowdhary09b368b2023-02-13 06:53:05 +000062
Avichal Rakeshfcb78cb2022-10-27 15:45:54 -070063bool 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
86ndk::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
94ndk::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
Jayant Chowdhary09b368b2023-02-13 06:53:05 +0000102ndk::ScopedAStatus AidlCameraDeviceUser::prepare(int32_t in_streamId) {
103 UStatus ret = mDeviceRemote->prepare(in_streamId);
104 return fromUStatus(ret);
105}
106
Avichal Rakeshfcb78cb2022-10-27 15:45:54 -0700107ndk::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",
Tomasz Wasilczyk67b5ebc2023-08-30 17:45:57 +0000123 __FUNCTION__, ret.toString8().c_str());
Avichal Rakeshfcb78cb2022-10-27 15:45:54 -0700124 return fromUStatus(ret);
125 }
126 mRequestId = submitInfo.mRequestId;
127 convertToAidl(submitInfo, _aidl_return);
128 return ScopedAStatus::ok();
129}
130
131ndk::ScopedAStatus AidlCameraDeviceUser::cancelRepeatingRequest(int64_t* _aidl_return) {
132 UStatus ret = mDeviceRemote->cancelRequest(mRequestId, _aidl_return);
133 return fromUStatus(ret);
134}
135
136ScopedAStatus AidlCameraDeviceUser::beginConfigure() {
137 UStatus ret = mDeviceRemote->beginConfigure();
138 return fromUStatus(ret);
139}
140
141ndk::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
156ndk::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()) {
Tomasz Wasilczyk67b5ebc2023-08-30 17:45:57 +0000162 ALOGE("%s: Failed to create stream: %s", __FUNCTION__, ret.toString8().c_str());
Avichal Rakeshfcb78cb2022-10-27 15:45:54 -0700163 }
164 *_aidl_return = newStreamId;
165 return fromUStatus(ret);
166}
167
168ndk::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()) {
Tomasz Wasilczyk67b5ebc2023-08-30 17:45:57 +0000174 ALOGE("%s: Failed to create default request: %s", __FUNCTION__, ret.toString8().c_str());
Avichal Rakeshfcb78cb2022-10-27 15:45:54 -0700175 return fromUStatus(ret);
176 }
Euisang Lim0dabcbb2023-04-04 17:38:32 +0900177
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
Avichal Rakeshfcb78cb2022-10-27 15:45:54 -0700184 const camera_metadata_t* rawMetadata = metadata.getAndLock();
185 cloneToAidl(rawMetadata, _aidl_return);
186 metadata.unlock(rawMetadata);
187 return ScopedAStatus::ok();
188}
189
190ndk::ScopedAStatus AidlCameraDeviceUser::waitUntilIdle() {
191 UStatus ret = mDeviceRemote->waitUntilIdle();
192 return fromUStatus(ret);
193}
194
Jyoti Bhayana1f9600b2024-10-29 20:25:32 -0700195ndk::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
Avichal Rakeshfcb78cb2022-10-27 15:45:54 -0700205ndk::ScopedAStatus AidlCameraDeviceUser::flush(int64_t* _aidl_return) {
206 UStatus ret = mDeviceRemote->flush(_aidl_return);
207 return fromUStatus(ret);
208}
209
210ndk::ScopedAStatus AidlCameraDeviceUser::updateOutputConfiguration(
211 int32_t in_streamId, const SOutputConfiguration& in_outputConfiguration) {
212 UOutputConfiguration outputConfig = convertFromAidl(in_outputConfiguration);
213 UStatus ret = mDeviceRemote->updateOutputConfiguration(in_streamId, outputConfig);
214 if (!ret.isOk()) {
215 ALOGE("%s: Failed to update output config for stream id: %d: %s",
Tomasz Wasilczyk67b5ebc2023-08-30 17:45:57 +0000216 __FUNCTION__, in_streamId, ret.toString8().c_str());
Avichal Rakeshfcb78cb2022-10-27 15:45:54 -0700217 }
218 return fromUStatus(ret);
219}
220ndk::ScopedAStatus AidlCameraDeviceUser::isSessionConfigurationSupported(
221 const SSessionConfiguration& in_sessionConfiguration, bool* _aidl_return) {
222 USessionConfiguration sessionConfig = convertFromAidl(in_sessionConfiguration);
223 UStatus ret = mDeviceRemote->isSessionConfigurationSupported(sessionConfig,
224 _aidl_return);
225 return fromUStatus(ret);
226}
227ndk::ScopedAStatus AidlCameraDeviceUser::deleteStream(int32_t in_streamId) {
228 UStatus ret = mDeviceRemote->deleteStream(in_streamId);
229 return fromUStatus(ret);
230}
231ndk::ScopedAStatus AidlCameraDeviceUser::disconnect() {
232 UStatus ret = mDeviceRemote->disconnect();
233 return fromUStatus(ret);
234}
235bool AidlCameraDeviceUser::convertRequestFromAidl(
236 const SCaptureRequest& src, UCaptureRequest* dst) {
237 dst->mIsReprocess = false;
238 for (const auto& streamAndWindowId : src.streamAndWindowIds) {
239 dst->mStreamIdxList.push_back(streamAndWindowId.streamId);
240 dst->mSurfaceIdxList.push_back(streamAndWindowId.windowId);
241 }
242
243 return copyPhysicalCameraSettings(src.physicalCameraSettings,
244 &(dst->mPhysicalCameraSettings));
245}
246bool AidlCameraDeviceUser::copyPhysicalCameraSettings(
247 const std::vector<SPhysicalCameraSettings>& src,
248 std::vector<UCaptureRequest::PhysicalCameraSettings>* dst) {
249 bool converted = false;
250 for (auto &e : src) {
251 dst->emplace_back();
252 CaptureRequest::PhysicalCameraSettings &physicalCameraSetting =
253 dst->back();
254 physicalCameraSetting.id = e.id;
255
256 // Read the settings either from the fmq or straightaway from the
257 // request. We don't need any synchronization, since submitRequestList
258 // is guaranteed to be called serially by the client if it decides to
259 // use fmq.
260 if (e.settings.getTag() == SCaptureMetadataInfo::fmqMetadataSize) {
261 /**
262 * Get settings from the fmq.
263 */
264 SCameraMetadata settingsFmq;
265 int64_t metadataSize = e.settings.get<SCaptureMetadataInfo::fmqMetadataSize>();
266 settingsFmq.metadata.resize(metadataSize);
267 int8_t* metadataPtr = (int8_t*) settingsFmq.metadata.data();
268 bool read = mCaptureRequestMetadataQueue->read(metadataPtr,
269 metadataSize);
270 if (!read) {
271 ALOGE("%s capture request settings could't be read from fmq size", __FUNCTION__);
272 converted = false;
273 } else {
274 converted = cloneFromAidl(settingsFmq, &physicalCameraSetting.settings);
275 }
276 } else {
277 /**
278 * The settings metadata is contained in request settings field.
279 */
280 converted = cloneFromAidl(e.settings.get<SCaptureMetadataInfo::metadata>(),
281 &physicalCameraSetting.settings);
282 }
283 if (!converted) {
284 ALOGE("%s: Unable to convert physicalCameraSettings from HIDL to AIDL.", __FUNCTION__);
285 return false;
286 }
287 }
288 return true;
289}
290
Jyoti Bhayana1f9600b2024-10-29 20:25:32 -0700291} // namespace android::frameworks::cameraservice::device::implementation