blob: d22ba5aa6174ae74d9f33539b28eb2970b9a9bcc [file] [log] [blame]
Jayant Chowdhary0c947272018-08-15 14:42:04 -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 <android/hardware/camera/device/3.2/types.h>
18#include <cutils/properties.h>
19#include <gui/Surface.h>
20#include <gui/bufferqueue/1.0/H2BGraphicBufferProducer.h>
21
22#include <hidl/AidlCameraDeviceCallbacks.h>
23#include <hidl/Convert.h>
24#include <hidl/HidlCameraDeviceUser.h>
25#include <android/hardware/camera/device/3.2/types.h>
26
27namespace android {
28namespace frameworks {
29namespace cameraservice {
30namespace device {
31namespace V2_0 {
32namespace implementation {
33
34using hardware::cameraservice::utils::conversion::convertToHidl;
35using hardware::cameraservice::utils::conversion::convertFromHidl;
36using hardware::cameraservice::utils::conversion::B2HStatus;
37
38using hardware::graphics::bufferqueue::V1_0::utils::H2BGraphicBufferProducer;
39using hardware::hidl_vec;
40using hardware::Return;
41using hardware::Void;
42using HSubmitInfo = device::V2_0::SubmitInfo;
43using hardware::camera2::params::OutputConfiguration;
44
45static constexpr int32_t CAMERA_REQUEST_METADATA_QUEUE_SIZE = 1 << 20 /* 1 MB */;
46static constexpr int32_t CAMERA_RESULT_METADATA_QUEUE_SIZE = 1 << 20 /* 1 MB */;
47
48Return<void> HidlCameraDeviceUser::disconnect() {
49 mDeviceRemote->disconnect();
50 return Void();
51}
52
53HidlCameraDeviceUser::HidlCameraDeviceUser(
54 const sp<hardware::camera2::ICameraDeviceUser> &deviceRemote)
55 : mDeviceRemote(deviceRemote) {
56 mInitSuccess = initDevice();
57}
58
59bool HidlCameraDeviceUser::initDevice() {
60 // TODO: Get request and result metadata queue size from a system property.
61 int32_t reqFMQSize = CAMERA_REQUEST_METADATA_QUEUE_SIZE;
62
63 mCaptureRequestMetadataQueue =
64 std::make_unique<CaptureRequestMetadataQueue>(static_cast<size_t>(reqFMQSize),
65 false /* non blocking */);
66 if (!mCaptureRequestMetadataQueue->isValid()) {
67 ALOGE("%s: invalid request fmq", __FUNCTION__);
68 return false;
69 }
70
71 int32_t resFMQSize = CAMERA_RESULT_METADATA_QUEUE_SIZE;
72 mCaptureResultMetadataQueue =
73 std::make_shared<CaptureResultMetadataQueue>(static_cast<size_t>(resFMQSize),
74 false /* non blocking */);
75 if (!mCaptureResultMetadataQueue->isValid()) {
76 ALOGE("%s: invalid result fmq", __FUNCTION__);
77 return false;
78 }
79 return true;
80}
81
82Return<void> HidlCameraDeviceUser::getCaptureRequestMetadataQueue(
83 getCaptureRequestMetadataQueue_cb _hidl_cb) {
84 if (mInitSuccess) {
85 _hidl_cb(*mCaptureRequestMetadataQueue->getDesc());
86 }
87 return Void();
88}
89
90Return<void> HidlCameraDeviceUser::getCaptureResultMetadataQueue(
91 getCaptureResultMetadataQueue_cb _hidl_cb) {
92 if (mInitSuccess) {
93 _hidl_cb(*mCaptureResultMetadataQueue->getDesc());
94 }
95 return Void();
96}
97
98/**
99 * To be used only by submitRequestList implementation, since it requires
100 * clients to call this method serially, incase fmq is used to send metadata.
101 */
102bool HidlCameraDeviceUser::copyPhysicalCameraSettings(
103 const hidl_vec<HPhysicalCameraSettings> &hPhysicalCameraSettings,
104 std::vector<CaptureRequest::PhysicalCameraSettings> *physicalCameraSettings) {
105 bool converted = false;
106 for (auto &e : hPhysicalCameraSettings) {
107 physicalCameraSettings->emplace_back();
108 CaptureRequest::PhysicalCameraSettings &physicalCameraSetting =
109 physicalCameraSettings->back();
110 physicalCameraSetting.id = e.id.c_str();
111
112 // Read the settings either from the fmq or straightaway from the
113 // request. We don't need any synchronization, since submitRequestList
114 // is guaranteed to be called serially by the client if it decides to
115 // use fmq.
116 if (e.settings.getDiscriminator() ==
117 FmqSizeOrMetadata::hidl_discriminator::fmqMetadataSize) {
118 /**
119 * Get settings from the fmq.
120 */
121 HCameraMetadata settingsFmq;
122 settingsFmq.resize(e.settings.fmqMetadataSize());
123 bool read = mCaptureRequestMetadataQueue->read(settingsFmq.data(),
124 e.settings.fmqMetadataSize());
125 if (!read) {
126 ALOGE("%s capture request settings could't be read from fmq size",
127 __FUNCTION__);
128 converted = false;
129 } else {
130 converted = convertFromHidl(settingsFmq, &physicalCameraSetting.settings);
131 }
132 } else {
133 /**
134 * The settings metadata is contained in request settings field.
135 */
136 converted =
137 convertFromHidl(e.settings.metadata(),
138 &physicalCameraSetting.settings);
139 }
140 if (!converted) {
141 ALOGE("%s: Unable to convert physicalCameraSettings from HIDL to AIDL.", __FUNCTION__);
142 return false;
143 }
144 }
145 return true;
146}
147
148bool HidlCameraDeviceUser::convertRequestFromHidl(const HCaptureRequest &hRequest,
149 CaptureRequest *request) {
150 // No reprocessing support.
151 request->mIsReprocess = false;
152 for (const auto &streamAndWindowId : hRequest.streamAndWindowIds) {
153 request->mStreamIdxList.push_back(streamAndWindowId.streamId);
154 request->mSurfaceIdxList.push_back(streamAndWindowId.windowId);
155 }
156 return copyPhysicalCameraSettings(hRequest.physicalCameraSettings,
157 &(request->mPhysicalCameraSettings));
158}
159
160Return<void> HidlCameraDeviceUser::submitRequestList(const hidl_vec<HCaptureRequest>& hRequestList,
161 bool streaming,
162 submitRequestList_cb _hidl_cb) {
163 hardware::camera2::utils::SubmitInfo submitInfo;
164 HSubmitInfo hSubmitInfo;
165 /**
166 * Create AIDL CaptureRequest from requestList and graphicBufferProducers.
167 */
168 std::vector<hardware::camera2::CaptureRequest> requests;
169 for (auto &hRequest : hRequestList) {
170 requests.emplace_back();
171 auto &request = requests.back();
172 if (!convertRequestFromHidl(hRequest, &request)) {
173 _hidl_cb(HStatus::ILLEGAL_ARGUMENT, hSubmitInfo);
174 return Void();
175 }
176 }
177 mDeviceRemote->submitRequestList(requests, streaming, &submitInfo);
178 mRequestId = submitInfo.mRequestId;
179 convertToHidl(submitInfo, &hSubmitInfo);
180 _hidl_cb(HStatus::NO_ERROR, hSubmitInfo);
181 return Void();
182}
183
184Return<void> HidlCameraDeviceUser::cancelRepeatingRequest(cancelRepeatingRequest_cb _hidl_cb) {
185 int64_t lastFrameNumber = 0;
186 binder::Status ret = mDeviceRemote->cancelRequest(mRequestId, &lastFrameNumber);
187 _hidl_cb(B2HStatus(ret), lastFrameNumber);
188 return Void();
189}
190
191Return<HStatus> HidlCameraDeviceUser::beginConfigure() {
192 binder::Status ret = mDeviceRemote->beginConfigure();
193 return B2HStatus(ret);
194}
195
196Return<HStatus> HidlCameraDeviceUser::endConfigure(StreamConfigurationMode operatingMode,
197 const hidl_vec<uint8_t>& sessionParams) {
198 android::CameraMetadata cameraMetadata;
199 if (!convertFromHidl(sessionParams, &cameraMetadata)) {
200 return HStatus::ILLEGAL_ARGUMENT;
201 }
202
203 binder::Status ret = mDeviceRemote->endConfigure(convertFromHidl(operatingMode),
204 cameraMetadata);
205 return B2HStatus(ret);
206}
207
208Return<HStatus> HidlCameraDeviceUser::deleteStream(int32_t streamId) {
209 binder::Status ret = mDeviceRemote->deleteStream(streamId);
210 return B2HStatus(ret);
211}
212
213Return<void> HidlCameraDeviceUser::createStream(const HOutputConfiguration& hOutputConfiguration,
214 createStream_cb hidl_cb_) {
215 OutputConfiguration outputConfiguration =
216 convertFromHidl(hOutputConfiguration);
217 int32_t newStreamId = 0;
218 binder::Status ret = mDeviceRemote->createStream(outputConfiguration, &newStreamId);
219 HStatus status = B2HStatus(ret);
220 hidl_cb_(status, newStreamId);
221 return Void();
222}
223
224Return<void> HidlCameraDeviceUser::createDefaultRequest(TemplateId templateId,
225 createDefaultRequest_cb _hidl_cb) {
226 android::CameraMetadata cameraMetadata;
227 binder::Status ret = mDeviceRemote->createDefaultRequest(convertFromHidl(templateId),
228 &cameraMetadata);
229 HStatus hStatus = B2HStatus(ret);
230 HCameraMetadata hidlMetadata;
231 const camera_metadata_t *rawMetadata = cameraMetadata.getAndLock();
232 convertToHidl(rawMetadata, &hidlMetadata);
233 _hidl_cb(hStatus, hidlMetadata);
234 cameraMetadata.unlock(rawMetadata);
235 return Void();
236}
237
238Return<HStatus> HidlCameraDeviceUser::waitUntilIdle() {
239 binder::Status ret = mDeviceRemote->waitUntilIdle();
240 return B2HStatus(ret);
241}
242
243Return<void> HidlCameraDeviceUser::flush(flush_cb _hidl_cb) {
244 int64_t lastFrameNumber = 0;
245 binder::Status ret = mDeviceRemote->flush(&lastFrameNumber);
246 _hidl_cb(B2HStatus(ret),lastFrameNumber);
247 return Void();
248}
249
250Return<HStatus> HidlCameraDeviceUser::updateOutputConfiguration(
251 int32_t streamId,
252 const HOutputConfiguration& hOutputConfiguration) {
253 OutputConfiguration outputConfiguration = convertFromHidl(hOutputConfiguration);
254 binder::Status ret = mDeviceRemote->updateOutputConfiguration(streamId, outputConfiguration);
255 return B2HStatus(ret);
256}
257
258} // implementation
259} // V2_0
260} // device
261} // cameraservice
262} // frameworks
263} // android