blob: 83b8e95cbf5b5c24d17424a10fe7c1775e22ee44 [file] [log] [blame]
Igor Murashkine7ee7632013-06-11 18:10:18 -07001/*
Shuzhen Wangc28189a2017-11-27 23:05:10 -08002 * Copyright (C) 2013-2018 The Android Open Source Project
Igor Murashkine7ee7632013-06-11 18:10:18 -07003 *
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 "CameraDeviceClient"
18#define ATRACE_TAG ATRACE_TAG_CAMERA
Jianing Weicb0652e2014-03-12 18:29:36 -070019//#define LOG_NDEBUG 0
Igor Murashkine7ee7632013-06-11 18:10:18 -070020
Eino-Ville Talvala7b82efe2013-07-25 17:12:35 -070021#include <cutils/properties.h>
Jayant Chowdhary12361932018-08-27 14:46:13 -070022#include <utils/CameraThreadState.h>
Igor Murashkine7ee7632013-06-11 18:10:18 -070023#include <utils/Log.h>
Colin Crossb8a9dbb2020-08-27 04:12:26 +000024#include <utils/SessionConfigurationUtils.h>
Igor Murashkine7ee7632013-06-11 18:10:18 -070025#include <utils/Trace.h>
Igor Murashkine7ee7632013-06-11 18:10:18 -070026#include <gui/Surface.h>
Eino-Ville Talvala7b82efe2013-07-25 17:12:35 -070027#include <camera/camera2/CaptureRequest.h>
Ruben Brunk5698d442014-06-18 10:39:40 -070028#include <camera/CameraUtils.h>
Eino-Ville Talvala7b82efe2013-07-25 17:12:35 -070029
30#include "common/CameraDeviceBase.h"
Emilian Peev35ae8262018-11-08 13:11:32 +000031#include "device3/Camera3Device.h"
32#include "device3/Camera3OutputStream.h"
Eino-Ville Talvala7b82efe2013-07-25 17:12:35 -070033#include "api2/CameraDeviceClient.h"
Shuzhen Wang316781a2020-08-18 18:11:01 -070034#include "utils/CameraServiceProxyWrapper.h"
Eino-Ville Talvala7b82efe2013-07-25 17:12:35 -070035
Emilian Peev00420d22018-02-05 21:33:13 +000036#include <camera_metadata_hidden.h>
37
Emilian Peev538c90e2018-12-17 18:03:19 +000038#include "DepthCompositeStream.h"
Shuzhen Wang68ac7ad2019-01-30 14:03:28 -080039#include "HeicCompositeStream.h"
Emilian Peev538c90e2018-12-17 18:03:19 +000040
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -080041// Convenience methods for constructing binder::Status objects for error returns
Eino-Ville Talvala7b82efe2013-07-25 17:12:35 -070042
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -080043#define STATUS_ERROR(errorCode, errorString) \
44 binder::Status::fromServiceSpecificError(errorCode, \
Eino-Ville Talvala02bf0322016-02-18 12:41:10 -080045 String8::format("%s:%d: %s", __FUNCTION__, __LINE__, errorString))
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -080046
47#define STATUS_ERROR_FMT(errorCode, errorString, ...) \
48 binder::Status::fromServiceSpecificError(errorCode, \
Eino-Ville Talvala02bf0322016-02-18 12:41:10 -080049 String8::format("%s:%d: " errorString, __FUNCTION__, __LINE__, \
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -080050 __VA_ARGS__))
Igor Murashkine7ee7632013-06-11 18:10:18 -070051
52namespace android {
53using namespace camera2;
Emilian Peevf4816702020-04-03 15:44:51 -070054using camera3::camera_stream_rotation_t::CAMERA_STREAM_ROTATION_0;
Shuzhen Wangd4abdf72021-05-28 11:22:50 -070055using camera3::SessionConfigurationUtils;
Igor Murashkine7ee7632013-06-11 18:10:18 -070056
57CameraDeviceClientBase::CameraDeviceClientBase(
58 const sp<CameraService>& cameraService,
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -080059 const sp<hardware::camera2::ICameraDeviceCallbacks>& remoteCallback,
Igor Murashkine7ee7632013-06-11 18:10:18 -070060 const String16& clientPackageName,
Jooyung Han3f9a3b42020-01-23 12:27:18 +090061 const std::optional<String16>& clientFeatureId,
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -080062 const String8& cameraId,
Yin-Chia Yehc3e9d6f2018-02-06 10:56:32 -080063 int api1CameraId,
Igor Murashkine7ee7632013-06-11 18:10:18 -070064 int cameraFacing,
Emilian Peev8b64f282021-03-25 16:49:57 -070065 int sensorOrientation,
Igor Murashkine7ee7632013-06-11 18:10:18 -070066 int clientPid,
67 uid_t clientUid,
68 int servicePid) :
Eino-Ville Talvalae992e752014-11-07 16:17:48 -080069 BasicClient(cameraService,
Marco Nelissenf8880202014-11-14 07:58:25 -080070 IInterface::asBinder(remoteCallback),
Eino-Ville Talvalae992e752014-11-07 16:17:48 -080071 clientPackageName,
Philip P. Moltmann9e648f62019-11-04 12:52:45 -080072 clientFeatureId,
Eino-Ville Talvalae992e752014-11-07 16:17:48 -080073 cameraId,
74 cameraFacing,
Emilian Peev8b64f282021-03-25 16:49:57 -070075 sensorOrientation,
Eino-Ville Talvalae992e752014-11-07 16:17:48 -080076 clientPid,
77 clientUid,
78 servicePid),
Igor Murashkine7ee7632013-06-11 18:10:18 -070079 mRemoteCallback(remoteCallback) {
Yin-Chia Yehc3e9d6f2018-02-06 10:56:32 -080080 // We don't need it for API2 clients, but Camera2ClientBase requires it.
81 (void) api1CameraId;
Igor Murashkine7ee7632013-06-11 18:10:18 -070082}
Igor Murashkine7ee7632013-06-11 18:10:18 -070083
84// Interface used by CameraService
85
86CameraDeviceClient::CameraDeviceClient(const sp<CameraService>& cameraService,
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -080087 const sp<hardware::camera2::ICameraDeviceCallbacks>& remoteCallback,
88 const String16& clientPackageName,
Jooyung Han3f9a3b42020-01-23 12:27:18 +090089 const std::optional<String16>& clientFeatureId,
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -080090 const String8& cameraId,
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -080091 int cameraFacing,
Emilian Peev8b64f282021-03-25 16:49:57 -070092 int sensorOrientation,
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -080093 int clientPid,
94 uid_t clientUid,
Shuzhen Wangd4abdf72021-05-28 11:22:50 -070095 int servicePid,
96 bool overrideForPerfClass) :
Philip P. Moltmann9e648f62019-11-04 12:52:45 -080097 Camera2ClientBase(cameraService, remoteCallback, clientPackageName, clientFeatureId,
Shuzhen Wangd4abdf72021-05-28 11:22:50 -070098 cameraId, /*API1 camera ID*/ -1, cameraFacing, sensorOrientation,
99 clientPid, clientUid, servicePid, overrideForPerfClass),
Chien-Yu Chen618ff8a2015-03-13 11:27:17 -0700100 mInputStream(),
Chien-Yu Chene8c535e2016-04-14 12:18:26 -0700101 mStreamingRequestId(REQUEST_ID_NONE),
Shuzhen Wangd4abdf72021-05-28 11:22:50 -0700102 mRequestIdCounter(0),
103 mOverrideForPerfClass(overrideForPerfClass) {
Igor Murashkine7ee7632013-06-11 18:10:18 -0700104
105 ATRACE_CALL();
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800106 ALOGI("CameraDeviceClient %s: Opened", cameraId.string());
Igor Murashkine7ee7632013-06-11 18:10:18 -0700107}
108
Emilian Peevbd8c5032018-02-14 23:05:40 +0000109status_t CameraDeviceClient::initialize(sp<CameraProviderManager> manager,
110 const String8& monitorTags) {
111 return initializeImpl(manager, monitorTags);
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800112}
113
114template<typename TProviderPtr>
Emilian Peevbd8c5032018-02-14 23:05:40 +0000115status_t CameraDeviceClient::initializeImpl(TProviderPtr providerPtr, const String8& monitorTags) {
Igor Murashkine7ee7632013-06-11 18:10:18 -0700116 ATRACE_CALL();
117 status_t res;
118
Emilian Peevbd8c5032018-02-14 23:05:40 +0000119 res = Camera2ClientBase::initialize(providerPtr, monitorTags);
Igor Murashkine7ee7632013-06-11 18:10:18 -0700120 if (res != OK) {
121 return res;
122 }
123
124 String8 threadName;
Eino-Ville Talvala7b82efe2013-07-25 17:12:35 -0700125 mFrameProcessor = new FrameProcessorBase(mDevice);
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800126 threadName = String8::format("CDU-%s-FrameProc", mCameraIdStr.string());
Igor Murashkine7ee7632013-06-11 18:10:18 -0700127 mFrameProcessor->run(threadName.string());
128
Emilian Peevfaa4bde2020-01-23 12:19:37 -0800129 mFrameProcessor->registerListener(camera2::FrameProcessorBase::FRAME_PROCESSOR_LISTENER_MIN_ID,
130 camera2::FrameProcessorBase::FRAME_PROCESSOR_LISTENER_MAX_ID,
Eino-Ville Talvala184dfe42013-11-07 15:13:16 -0800131 /*listener*/this,
Zhijun He25a0aef2014-06-25 11:40:02 -0700132 /*sendPartials*/true);
Igor Murashkine7ee7632013-06-11 18:10:18 -0700133
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800134 const CameraMetadata &deviceInfo = mDevice->info();
135 camera_metadata_ro_entry_t physicalKeysEntry = deviceInfo.find(
Emilian Peev00420d22018-02-05 21:33:13 +0000136 ANDROID_REQUEST_AVAILABLE_PHYSICAL_CAMERA_REQUEST_KEYS);
137 if (physicalKeysEntry.count > 0) {
138 mSupportedPhysicalRequestKeys.insert(mSupportedPhysicalRequestKeys.begin(),
139 physicalKeysEntry.data.i32,
140 physicalKeysEntry.data.i32 + physicalKeysEntry.count);
141 }
142
Shuzhen Wang03d8cc12018-09-12 14:17:09 -0700143 mProviderManager = providerPtr;
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800144 // Cache physical camera ids corresponding to this device and also the high
145 // resolution sensors in this device + physical camera ids
146 mProviderManager->isLogicalCamera(mCameraIdStr.string(), &mPhysicalCameraIds);
147 if (isUltraHighResolutionSensor(mCameraIdStr)) {
148 mHighResolutionSensors.insert(mCameraIdStr.string());
149 }
150 for (auto &physicalId : mPhysicalCameraIds) {
151 if (isUltraHighResolutionSensor(String8(physicalId.c_str()))) {
152 mHighResolutionSensors.insert(physicalId.c_str());
153 }
154 }
Igor Murashkine7ee7632013-06-11 18:10:18 -0700155 return OK;
156}
157
158CameraDeviceClient::~CameraDeviceClient() {
159}
160
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800161binder::Status CameraDeviceClient::submitRequest(
162 const hardware::camera2::CaptureRequest& request,
163 bool streaming,
164 /*out*/
165 hardware::camera2::utils::SubmitInfo *submitInfo) {
166 std::vector<hardware::camera2::CaptureRequest> requestList = { request };
167 return submitRequestList(requestList, streaming, submitInfo);
Igor Murashkine7ee7632013-06-11 18:10:18 -0700168}
169
Yin-Chia Yeh4dfa4cc2017-11-10 20:00:09 -0800170binder::Status CameraDeviceClient::insertGbpLocked(const sp<IGraphicBufferProducer>& gbp,
Emilian Peevf873aa52018-01-26 14:58:28 +0000171 SurfaceMap* outSurfaceMap, Vector<int32_t>* outputStreamIds, int32_t *currentStreamId) {
Emilian Peev538c90e2018-12-17 18:03:19 +0000172 int compositeIdx;
Yin-Chia Yeh4dfa4cc2017-11-10 20:00:09 -0800173 int idx = mStreamMap.indexOfKey(IInterface::asBinder(gbp));
174
175 // Trying to submit request with surface that wasn't created
176 if (idx == NAME_NOT_FOUND) {
177 ALOGE("%s: Camera %s: Tried to submit a request with a surface that"
178 " we have not called createStream on",
179 __FUNCTION__, mCameraIdStr.string());
180 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT,
181 "Request targets Surface that is not part of current capture session");
Emilian Peev538c90e2018-12-17 18:03:19 +0000182 } else if ((compositeIdx = mCompositeStreamMap.indexOfKey(IInterface::asBinder(gbp)))
183 != NAME_NOT_FOUND) {
184 mCompositeStreamMap.valueAt(compositeIdx)->insertGbp(outSurfaceMap, outputStreamIds,
185 currentStreamId);
186 return binder::Status::ok();
Yin-Chia Yeh4dfa4cc2017-11-10 20:00:09 -0800187 }
188
189 const StreamSurfaceId& streamSurfaceId = mStreamMap.valueAt(idx);
190 if (outSurfaceMap->find(streamSurfaceId.streamId()) == outSurfaceMap->end()) {
Yin-Chia Yeh4dfa4cc2017-11-10 20:00:09 -0800191 outputStreamIds->push_back(streamSurfaceId.streamId());
192 }
193 (*outSurfaceMap)[streamSurfaceId.streamId()].push_back(streamSurfaceId.surfaceId());
194
195 ALOGV("%s: Camera %s: Appending output stream %d surface %d to request",
196 __FUNCTION__, mCameraIdStr.string(), streamSurfaceId.streamId(),
197 streamSurfaceId.surfaceId());
198
Emilian Peevf873aa52018-01-26 14:58:28 +0000199 if (currentStreamId != nullptr) {
200 *currentStreamId = streamSurfaceId.streamId();
201 }
202
Yin-Chia Yeh4dfa4cc2017-11-10 20:00:09 -0800203 return binder::Status::ok();
204}
205
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800206static std::list<int> getIntersection(const std::unordered_set<int> &streamIdsForThisCamera,
207 const Vector<int> &streamIdsForThisRequest) {
208 std::list<int> intersection;
209 for (auto &streamId : streamIdsForThisRequest) {
210 if (streamIdsForThisCamera.find(streamId) != streamIdsForThisCamera.end()) {
211 intersection.emplace_back(streamId);
212 }
213 }
214 return intersection;
215}
216
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800217binder::Status CameraDeviceClient::submitRequestList(
218 const std::vector<hardware::camera2::CaptureRequest>& requests,
219 bool streaming,
220 /*out*/
221 hardware::camera2::utils::SubmitInfo *submitInfo) {
Jianing Wei90e59c92014-03-12 18:29:36 -0700222 ATRACE_CALL();
Mark Salyzyn50468412014-06-18 16:33:43 -0700223 ALOGV("%s-start of function. Request list size %zu", __FUNCTION__, requests.size());
Jianing Wei90e59c92014-03-12 18:29:36 -0700224
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800225 binder::Status res = binder::Status::ok();
226 status_t err;
227 if ( !(res = checkPidStatus(__FUNCTION__) ).isOk()) {
228 return res;
229 }
Jianing Wei90e59c92014-03-12 18:29:36 -0700230
231 Mutex::Autolock icl(mBinderSerializationLock);
232
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800233 if (!mDevice.get()) {
234 return STATUS_ERROR(CameraService::ERROR_DISCONNECTED, "Camera device no longer alive");
235 }
Jianing Wei90e59c92014-03-12 18:29:36 -0700236
237 if (requests.empty()) {
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800238 ALOGE("%s: Camera %s: Sent null request. Rejecting request.",
239 __FUNCTION__, mCameraIdStr.string());
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800240 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, "Empty request list");
Jianing Wei90e59c92014-03-12 18:29:36 -0700241 }
242
Emilian Peevaebbe412018-01-15 13:53:24 +0000243 List<const CameraDeviceBase::PhysicalCameraSettingsList> metadataRequestList;
Shuzhen Wang0129d522016-10-30 22:43:41 -0700244 std::list<const SurfaceMap> surfaceMapList;
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800245 submitInfo->mRequestId = mRequestIdCounter;
Jianing Wei90e59c92014-03-12 18:29:36 -0700246 uint32_t loopCounter = 0;
247
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800248 for (auto&& request: requests) {
249 if (request.mIsReprocess) {
Chien-Yu Chened0412e2015-04-27 15:04:22 -0700250 if (!mInputStream.configured) {
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800251 ALOGE("%s: Camera %s: no input stream is configured.", __FUNCTION__,
252 mCameraIdStr.string());
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800253 return STATUS_ERROR_FMT(CameraService::ERROR_ILLEGAL_ARGUMENT,
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800254 "No input configured for camera %s but request is for reprocessing",
255 mCameraIdStr.string());
Chien-Yu Chened0412e2015-04-27 15:04:22 -0700256 } else if (streaming) {
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800257 ALOGE("%s: Camera %s: streaming reprocess requests not supported.", __FUNCTION__,
258 mCameraIdStr.string());
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800259 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT,
260 "Repeating reprocess requests not supported");
Emilian Peevaebbe412018-01-15 13:53:24 +0000261 } else if (request.mPhysicalCameraSettings.size() > 1) {
262 ALOGE("%s: Camera %s: reprocess requests not supported for "
263 "multiple physical cameras.", __FUNCTION__,
264 mCameraIdStr.string());
265 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT,
266 "Reprocess requests not supported for multiple cameras");
Chien-Yu Chen618ff8a2015-03-13 11:27:17 -0700267 }
Jianing Wei90e59c92014-03-12 18:29:36 -0700268 }
269
Emilian Peevaebbe412018-01-15 13:53:24 +0000270 if (request.mPhysicalCameraSettings.empty()) {
271 ALOGE("%s: Camera %s: request doesn't contain any settings.", __FUNCTION__,
272 mCameraIdStr.string());
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800273 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT,
Emilian Peevaebbe412018-01-15 13:53:24 +0000274 "Request doesn't contain any settings");
275 }
276
277 //The first capture settings should always match the logical camera id
278 String8 logicalId(request.mPhysicalCameraSettings.begin()->id.c_str());
279 if (mDevice->getId() != logicalId) {
280 ALOGE("%s: Camera %s: Invalid camera request settings.", __FUNCTION__,
281 mCameraIdStr.string());
282 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT,
283 "Invalid camera request settings");
284 }
285
Emilian Peevaebbe412018-01-15 13:53:24 +0000286 if (request.mSurfaceList.isEmpty() && request.mStreamIdxList.size() == 0) {
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800287 ALOGE("%s: Camera %s: Requests must have at least one surface target. "
288 "Rejecting request.", __FUNCTION__, mCameraIdStr.string());
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800289 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT,
290 "Request has no output targets");
Jianing Wei90e59c92014-03-12 18:29:36 -0700291 }
292
Jianing Wei90e59c92014-03-12 18:29:36 -0700293 /**
Shuzhen Wang0129d522016-10-30 22:43:41 -0700294 * Write in the output stream IDs and map from stream ID to surface ID
295 * which we calculate from the capture request's list of surface target
Jianing Wei90e59c92014-03-12 18:29:36 -0700296 */
Shuzhen Wang0129d522016-10-30 22:43:41 -0700297 SurfaceMap surfaceMap;
Jianing Wei90e59c92014-03-12 18:29:36 -0700298 Vector<int32_t> outputStreamIds;
Emilian Peevf873aa52018-01-26 14:58:28 +0000299 std::vector<std::string> requestedPhysicalIds;
Yin-Chia Yeh4dfa4cc2017-11-10 20:00:09 -0800300 if (request.mSurfaceList.size() > 0) {
Chih-Hung Hsieh3ef324d2018-12-11 11:48:12 -0800301 for (const sp<Surface>& surface : request.mSurfaceList) {
Yin-Chia Yeh4dfa4cc2017-11-10 20:00:09 -0800302 if (surface == 0) continue;
Jianing Wei90e59c92014-03-12 18:29:36 -0700303
Emilian Peevf873aa52018-01-26 14:58:28 +0000304 int32_t streamId;
Yin-Chia Yeh4dfa4cc2017-11-10 20:00:09 -0800305 sp<IGraphicBufferProducer> gbp = surface->getIGraphicBufferProducer();
Emilian Peevf873aa52018-01-26 14:58:28 +0000306 res = insertGbpLocked(gbp, &surfaceMap, &outputStreamIds, &streamId);
Yin-Chia Yeh4dfa4cc2017-11-10 20:00:09 -0800307 if (!res.isOk()) {
308 return res;
309 }
Emilian Peevf873aa52018-01-26 14:58:28 +0000310
311 ssize_t index = mConfiguredOutputs.indexOfKey(streamId);
312 if (index >= 0) {
313 String8 requestedPhysicalId(
314 mConfiguredOutputs.valueAt(index).getPhysicalCameraId());
315 requestedPhysicalIds.push_back(requestedPhysicalId.string());
316 } else {
317 ALOGW("%s: Output stream Id not found among configured outputs!", __FUNCTION__);
318 }
Jianing Wei90e59c92014-03-12 18:29:36 -0700319 }
Yin-Chia Yeh4dfa4cc2017-11-10 20:00:09 -0800320 } else {
321 for (size_t i = 0; i < request.mStreamIdxList.size(); i++) {
322 int streamId = request.mStreamIdxList.itemAt(i);
323 int surfaceIdx = request.mSurfaceIdxList.itemAt(i);
Jianing Wei90e59c92014-03-12 18:29:36 -0700324
Yin-Chia Yeh4dfa4cc2017-11-10 20:00:09 -0800325 ssize_t index = mConfiguredOutputs.indexOfKey(streamId);
326 if (index < 0) {
327 ALOGE("%s: Camera %s: Tried to submit a request with a surface that"
328 " we have not called createStream on: stream %d",
329 __FUNCTION__, mCameraIdStr.string(), streamId);
330 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT,
331 "Request targets Surface that is not part of current capture session");
332 }
333
334 const auto& gbps = mConfiguredOutputs.valueAt(index).getGraphicBufferProducers();
335 if ((size_t)surfaceIdx >= gbps.size()) {
336 ALOGE("%s: Camera %s: Tried to submit a request with a surface that"
337 " we have not called createStream on: stream %d, surfaceIdx %d",
338 __FUNCTION__, mCameraIdStr.string(), streamId, surfaceIdx);
339 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT,
340 "Request targets Surface has invalid surface index");
341 }
342
Emilian Peevf873aa52018-01-26 14:58:28 +0000343 res = insertGbpLocked(gbps[surfaceIdx], &surfaceMap, &outputStreamIds, nullptr);
Yin-Chia Yeh4dfa4cc2017-11-10 20:00:09 -0800344 if (!res.isOk()) {
345 return res;
346 }
Emilian Peevf873aa52018-01-26 14:58:28 +0000347
348 String8 requestedPhysicalId(
349 mConfiguredOutputs.valueAt(index).getPhysicalCameraId());
350 requestedPhysicalIds.push_back(requestedPhysicalId.string());
Shuzhen Wang0129d522016-10-30 22:43:41 -0700351 }
Jianing Wei90e59c92014-03-12 18:29:36 -0700352 }
353
Emilian Peevf873aa52018-01-26 14:58:28 +0000354 CameraDeviceBase::PhysicalCameraSettingsList physicalSettingsList;
355 for (const auto& it : request.mPhysicalCameraSettings) {
Emilian Peev00420d22018-02-05 21:33:13 +0000356 if (it.settings.isEmpty()) {
357 ALOGE("%s: Camera %s: Sent empty metadata packet. Rejecting request.",
358 __FUNCTION__, mCameraIdStr.string());
359 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT,
360 "Request settings are empty");
361 }
362
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800363 // Check whether the physical / logical stream has settings
364 // consistent with the sensor pixel mode(s) it was configured with.
365 // mCameraIdToStreamSet will only have ids that are high resolution
366 const auto streamIdSetIt = mHighResolutionCameraIdToStreamIdSet.find(it.id);
367 if (streamIdSetIt != mHighResolutionCameraIdToStreamIdSet.end()) {
368 std::list<int> streamIdsUsedInRequest = getIntersection(streamIdSetIt->second,
369 outputStreamIds);
370 if (!request.mIsReprocess &&
371 !isSensorPixelModeConsistent(streamIdsUsedInRequest, it.settings)) {
372 ALOGE("%s: Camera %s: Request settings CONTROL_SENSOR_PIXEL_MODE not "
373 "consistent with configured streams. Rejecting request.",
374 __FUNCTION__, it.id.c_str());
375 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT,
376 "Request settings CONTROL_SENSOR_PIXEL_MODE are not consistent with "
377 "streams configured");
378 }
379 }
380
Emilian Peevf873aa52018-01-26 14:58:28 +0000381 String8 physicalId(it.id.c_str());
Shuzhen Wang911c6a32021-10-27 13:36:03 -0700382 bool hasTestPatternModePhysicalKey = std::find(mSupportedPhysicalRequestKeys.begin(),
383 mSupportedPhysicalRequestKeys.end(), ANDROID_SENSOR_TEST_PATTERN_MODE) !=
384 mSupportedPhysicalRequestKeys.end();
385 bool hasTestPatternDataPhysicalKey = std::find(mSupportedPhysicalRequestKeys.begin(),
386 mSupportedPhysicalRequestKeys.end(), ANDROID_SENSOR_TEST_PATTERN_DATA) !=
387 mSupportedPhysicalRequestKeys.end();
Emilian Peevf873aa52018-01-26 14:58:28 +0000388 if (physicalId != mDevice->getId()) {
389 auto found = std::find(requestedPhysicalIds.begin(), requestedPhysicalIds.end(),
390 it.id);
391 if (found == requestedPhysicalIds.end()) {
392 ALOGE("%s: Camera %s: Physical camera id: %s not part of attached outputs.",
393 __FUNCTION__, mCameraIdStr.string(), physicalId.string());
394 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT,
395 "Invalid physical camera id");
396 }
Emilian Peev00420d22018-02-05 21:33:13 +0000397
398 if (!mSupportedPhysicalRequestKeys.empty()) {
399 // Filter out any unsupported physical request keys.
400 CameraMetadata filteredParams(mSupportedPhysicalRequestKeys.size());
401 camera_metadata_t *meta = const_cast<camera_metadata_t *>(
402 filteredParams.getAndLock());
403 set_camera_metadata_vendor_id(meta, mDevice->getVendorTagId());
404 filteredParams.unlock(meta);
405
406 for (const auto& keyIt : mSupportedPhysicalRequestKeys) {
407 camera_metadata_ro_entry entry = it.settings.find(keyIt);
408 if (entry.count > 0) {
409 filteredParams.update(entry);
410 }
411 }
412
Shuzhen Wang911c6a32021-10-27 13:36:03 -0700413 physicalSettingsList.push_back({it.id, filteredParams,
414 hasTestPatternModePhysicalKey, hasTestPatternDataPhysicalKey});
Emilian Peev00420d22018-02-05 21:33:13 +0000415 }
416 } else {
417 physicalSettingsList.push_back({it.id, it.settings});
Emilian Peevf873aa52018-01-26 14:58:28 +0000418 }
Emilian Peevf873aa52018-01-26 14:58:28 +0000419 }
420
421 if (!enforceRequestPermissions(physicalSettingsList.begin()->metadata)) {
422 // Callee logs
423 return STATUS_ERROR(CameraService::ERROR_PERMISSION_DENIED,
424 "Caller does not have permission to change restricted controls");
425 }
426
Emilian Peevaebbe412018-01-15 13:53:24 +0000427 physicalSettingsList.begin()->metadata.update(ANDROID_REQUEST_OUTPUT_STREAMS,
428 &outputStreamIds[0], outputStreamIds.size());
Jianing Wei90e59c92014-03-12 18:29:36 -0700429
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800430 if (request.mIsReprocess) {
Emilian Peevaebbe412018-01-15 13:53:24 +0000431 physicalSettingsList.begin()->metadata.update(ANDROID_REQUEST_INPUT_STREAMS,
432 &mInputStream.id, 1);
Chien-Yu Chen618ff8a2015-03-13 11:27:17 -0700433 }
434
Emilian Peevaebbe412018-01-15 13:53:24 +0000435 physicalSettingsList.begin()->metadata.update(ANDROID_REQUEST_ID,
436 &(submitInfo->mRequestId), /*size*/1);
Jianing Wei90e59c92014-03-12 18:29:36 -0700437 loopCounter++; // loopCounter starts from 1
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800438 ALOGV("%s: Camera %s: Creating request with ID %d (%d of %zu)",
439 __FUNCTION__, mCameraIdStr.string(), submitInfo->mRequestId,
440 loopCounter, requests.size());
Jianing Wei90e59c92014-03-12 18:29:36 -0700441
Emilian Peevaebbe412018-01-15 13:53:24 +0000442 metadataRequestList.push_back(physicalSettingsList);
Shuzhen Wang0129d522016-10-30 22:43:41 -0700443 surfaceMapList.push_back(surfaceMap);
Jianing Wei90e59c92014-03-12 18:29:36 -0700444 }
445 mRequestIdCounter++;
446
447 if (streaming) {
Shuzhen Wang0129d522016-10-30 22:43:41 -0700448 err = mDevice->setStreamingRequestList(metadataRequestList, surfaceMapList,
449 &(submitInfo->mLastFrameNumber));
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800450 if (err != OK) {
451 String8 msg = String8::format(
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800452 "Camera %s: Got error %s (%d) after trying to set streaming request",
453 mCameraIdStr.string(), strerror(-err), err);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800454 ALOGE("%s: %s", __FUNCTION__, msg.string());
455 res = STATUS_ERROR(CameraService::ERROR_INVALID_OPERATION,
456 msg.string());
Jianing Wei90e59c92014-03-12 18:29:36 -0700457 } else {
Shuzhen Wangc9ca6782016-04-26 13:40:31 -0700458 Mutex::Autolock idLock(mStreamingRequestIdLock);
Chien-Yu Chene8c535e2016-04-14 12:18:26 -0700459 mStreamingRequestId = submitInfo->mRequestId;
Jianing Wei90e59c92014-03-12 18:29:36 -0700460 }
461 } else {
Shuzhen Wang0129d522016-10-30 22:43:41 -0700462 err = mDevice->captureList(metadataRequestList, surfaceMapList,
463 &(submitInfo->mLastFrameNumber));
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800464 if (err != OK) {
465 String8 msg = String8::format(
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800466 "Camera %s: Got error %s (%d) after trying to submit capture request",
467 mCameraIdStr.string(), strerror(-err), err);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800468 ALOGE("%s: %s", __FUNCTION__, msg.string());
469 res = STATUS_ERROR(CameraService::ERROR_INVALID_OPERATION,
470 msg.string());
Jianing Wei90e59c92014-03-12 18:29:36 -0700471 }
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800472 ALOGV("%s: requestId = %d ", __FUNCTION__, submitInfo->mRequestId);
Jianing Wei90e59c92014-03-12 18:29:36 -0700473 }
474
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800475 ALOGV("%s: Camera %s: End of function", __FUNCTION__, mCameraIdStr.string());
Jianing Wei90e59c92014-03-12 18:29:36 -0700476 return res;
477}
478
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800479binder::Status CameraDeviceClient::cancelRequest(
480 int requestId,
481 /*out*/
482 int64_t* lastFrameNumber) {
Igor Murashkine7ee7632013-06-11 18:10:18 -0700483 ATRACE_CALL();
484 ALOGV("%s, requestId = %d", __FUNCTION__, requestId);
485
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800486 status_t err;
487 binder::Status res;
Igor Murashkine7ee7632013-06-11 18:10:18 -0700488
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800489 if (!(res = checkPidStatus(__FUNCTION__)).isOk()) return res;
Igor Murashkine7ee7632013-06-11 18:10:18 -0700490
491 Mutex::Autolock icl(mBinderSerializationLock);
492
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800493 if (!mDevice.get()) {
494 return STATUS_ERROR(CameraService::ERROR_DISCONNECTED, "Camera device no longer alive");
495 }
Igor Murashkine7ee7632013-06-11 18:10:18 -0700496
Shuzhen Wangc9ca6782016-04-26 13:40:31 -0700497 Mutex::Autolock idLock(mStreamingRequestIdLock);
Chien-Yu Chene8c535e2016-04-14 12:18:26 -0700498 if (mStreamingRequestId != requestId) {
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800499 String8 msg = String8::format("Camera %s: Canceling request ID %d doesn't match "
500 "current request ID %d", mCameraIdStr.string(), requestId, mStreamingRequestId);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800501 ALOGE("%s: %s", __FUNCTION__, msg.string());
502 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
Igor Murashkine7ee7632013-06-11 18:10:18 -0700503 }
504
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800505 err = mDevice->clearStreamingRequest(lastFrameNumber);
Igor Murashkine7ee7632013-06-11 18:10:18 -0700506
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800507 if (err == OK) {
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800508 ALOGV("%s: Camera %s: Successfully cleared streaming request",
509 __FUNCTION__, mCameraIdStr.string());
Chien-Yu Chene8c535e2016-04-14 12:18:26 -0700510 mStreamingRequestId = REQUEST_ID_NONE;
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800511 } else {
512 res = STATUS_ERROR_FMT(CameraService::ERROR_INVALID_OPERATION,
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800513 "Camera %s: Error clearing streaming request: %s (%d)",
514 mCameraIdStr.string(), strerror(-err), err);
Igor Murashkine7ee7632013-06-11 18:10:18 -0700515 }
516
517 return res;
518}
519
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800520binder::Status CameraDeviceClient::beginConfigure() {
Ruben Brunkb2119af2014-05-09 19:57:56 -0700521 // TODO: Implement this.
Eino-Ville Talvala6aeb8882017-08-07 17:40:49 -0700522 ATRACE_CALL();
Zhijun He1fa89992015-06-01 15:44:31 -0700523 ALOGV("%s: Not implemented yet.", __FUNCTION__);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800524 return binder::Status::ok();
Ruben Brunkb2119af2014-05-09 19:57:56 -0700525}
526
Emilian Peev5fbe0ba2017-10-20 15:45:45 +0100527binder::Status CameraDeviceClient::endConfigure(int operatingMode,
Shuzhen Wang316781a2020-08-18 18:11:01 -0700528 const hardware::camera2::impl::CameraMetadataNative& sessionParams, int64_t startTimeMs,
Emilian Peevcc0b7952020-01-07 13:54:47 -0800529 std::vector<int>* offlineStreamIds /*out*/) {
Eino-Ville Talvala6aeb8882017-08-07 17:40:49 -0700530 ATRACE_CALL();
Shuzhen Wang0129d522016-10-30 22:43:41 -0700531 ALOGV("%s: ending configure (%d input stream, %zu output surfaces)",
532 __FUNCTION__, mInputStream.configured ? 1 : 0,
533 mStreamMap.size());
Igor Murashkine2d167e2014-08-19 16:19:59 -0700534
Zhijun He0effd522016-03-04 10:22:27 -0800535 binder::Status res;
536 if (!(res = checkPidStatus(__FUNCTION__)).isOk()) return res;
537
Emilian Peevcc0b7952020-01-07 13:54:47 -0800538 if (offlineStreamIds == nullptr) {
539 String8 msg = String8::format("Invalid offline stream ids");
540 ALOGE("%s: %s", __FUNCTION__, msg.string());
541 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
542 }
543
Zhijun He0effd522016-03-04 10:22:27 -0800544 Mutex::Autolock icl(mBinderSerializationLock);
545
546 if (!mDevice.get()) {
547 return STATUS_ERROR(CameraService::ERROR_DISCONNECTED, "Camera device no longer alive");
548 }
549
Shuzhen Wangd4abdf72021-05-28 11:22:50 -0700550 res = SessionConfigurationUtils::checkOperatingMode(operatingMode, mDevice->info(),
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000551 mCameraIdStr);
Emilian Peev35ae8262018-11-08 13:11:32 +0000552 if (!res.isOk()) {
553 return res;
554 }
555
556 status_t err = mDevice->configureStreams(sessionParams, operatingMode);
557 if (err == BAD_VALUE) {
558 String8 msg = String8::format("Camera %s: Unsupported set of inputs/outputs provided",
559 mCameraIdStr.string());
560 ALOGE("%s: %s", __FUNCTION__, msg.string());
561 res = STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
562 } else if (err != OK) {
563 String8 msg = String8::format("Camera %s: Error configuring streams: %s (%d)",
564 mCameraIdStr.string(), strerror(-err), err);
565 ALOGE("%s: %s", __FUNCTION__, msg.string());
566 res = STATUS_ERROR(CameraService::ERROR_INVALID_OPERATION, msg.string());
Emilian Peev538c90e2018-12-17 18:03:19 +0000567 } else {
Emilian Peevcc0b7952020-01-07 13:54:47 -0800568 offlineStreamIds->clear();
569 mDevice->getOfflineStreamIds(offlineStreamIds);
570
Emilian Peev538c90e2018-12-17 18:03:19 +0000571 for (size_t i = 0; i < mCompositeStreamMap.size(); ++i) {
572 err = mCompositeStreamMap.valueAt(i)->configureStream();
Emilian Peevcc0b7952020-01-07 13:54:47 -0800573 if (err != OK) {
Emilian Peev538c90e2018-12-17 18:03:19 +0000574 String8 msg = String8::format("Camera %s: Error configuring composite "
575 "streams: %s (%d)", mCameraIdStr.string(), strerror(-err), err);
576 ALOGE("%s: %s", __FUNCTION__, msg.string());
577 res = STATUS_ERROR(CameraService::ERROR_INVALID_OPERATION, msg.string());
578 break;
579 }
Emilian Peevcc0b7952020-01-07 13:54:47 -0800580
581 // Composite streams can only support offline mode in case all individual internal
582 // streams are also supported.
583 std::vector<int> internalStreams;
584 mCompositeStreamMap.valueAt(i)->insertCompositeStreamIds(&internalStreams);
Emilian Peevfaa4bde2020-01-23 12:19:37 -0800585 offlineStreamIds->erase(
586 std::remove_if(offlineStreamIds->begin(), offlineStreamIds->end(),
Emilian Peevcc0b7952020-01-07 13:54:47 -0800587 [&internalStreams] (int streamId) {
588 auto it = std::find(internalStreams.begin(), internalStreams.end(),
589 streamId);
590 if (it != internalStreams.end()) {
591 internalStreams.erase(it);
592 return true;
593 }
594
Emilian Peevfaa4bde2020-01-23 12:19:37 -0800595 return false;}), offlineStreamIds->end());
Emilian Peevcc0b7952020-01-07 13:54:47 -0800596 if (internalStreams.empty()) {
597 offlineStreamIds->push_back(mCompositeStreamMap.valueAt(i)->getStreamId());
598 }
599 }
600
601 for (const auto& offlineStreamId : *offlineStreamIds) {
602 mStreamInfoMap[offlineStreamId].supportsOffline = true;
Emilian Peev538c90e2018-12-17 18:03:19 +0000603 }
Shuzhen Wang316781a2020-08-18 18:11:01 -0700604
605 nsecs_t configureEnd = systemTime();
606 int32_t configureDurationMs = ns2ms(configureEnd) - startTimeMs;
607 CameraServiceProxyWrapper::logStreamConfigured(mCameraIdStr, operatingMode,
608 false /*internalReconfig*/, configureDurationMs);
Emilian Peev35ae8262018-11-08 13:11:32 +0000609 }
610
611 return res;
612}
613
Jayant Chowdhary2bbdce42020-01-12 14:55:41 -0800614binder::Status CameraDeviceClient::isSessionConfigurationSupported(
615 const SessionConfiguration& sessionConfiguration, bool *status /*out*/) {
Jayant Chowdhary2bbdce42020-01-12 14:55:41 -0800616
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800617 ATRACE_CALL();
Jayant Chowdhary2bbdce42020-01-12 14:55:41 -0800618 binder::Status res;
619 status_t ret = OK;
620 if (!(res = checkPidStatus(__FUNCTION__)).isOk()) return res;
621
622 Mutex::Autolock icl(mBinderSerializationLock);
623
624 if (!mDevice.get()) {
625 return STATUS_ERROR(CameraService::ERROR_DISCONNECTED, "Camera device no longer alive");
626 }
627
628 auto operatingMode = sessionConfiguration.getOperatingMode();
Shuzhen Wangd4abdf72021-05-28 11:22:50 -0700629 res = SessionConfigurationUtils::checkOperatingMode(operatingMode, mDevice->info(),
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000630 mCameraIdStr);
Jayant Chowdhary2bbdce42020-01-12 14:55:41 -0800631 if (!res.isOk()) {
632 return res;
633 }
634
635 if (status == nullptr) {
636 String8 msg = String8::format( "Camera %s: Invalid status!", mCameraIdStr.string());
637 ALOGE("%s: %s", __FUNCTION__, msg.string());
638 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
639 }
Shuzhen Wangd4abdf72021-05-28 11:22:50 -0700640
Shuzhen Wang83bff122020-11-20 15:51:39 -0800641 hardware::camera::device::V3_7::StreamConfiguration streamConfiguration;
Jayant Chowdhary2bbdce42020-01-12 14:55:41 -0800642 bool earlyExit = false;
Shuzhen Wangd4abdf72021-05-28 11:22:50 -0700643 camera3::metadataGetter getMetadata = [this](const String8 &id, bool /*overrideForPerfClass*/) {
644 return mDevice->infoPhysical(id);};
Jayant Chowdhary2bbdce42020-01-12 14:55:41 -0800645 std::vector<std::string> physicalCameraIds;
646 mProviderManager->isLogicalCamera(mCameraIdStr.string(), &physicalCameraIds);
Shuzhen Wangd4abdf72021-05-28 11:22:50 -0700647 res = SessionConfigurationUtils::convertToHALStreamCombination(sessionConfiguration,
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000648 mCameraIdStr, mDevice->info(), getMetadata, physicalCameraIds, streamConfiguration,
Shuzhen Wangd4abdf72021-05-28 11:22:50 -0700649 mOverrideForPerfClass, &earlyExit);
Jayant Chowdhary2bbdce42020-01-12 14:55:41 -0800650 if (!res.isOk()) {
651 return res;
652 }
653
654 if (earlyExit) {
655 *status = false;
656 return binder::Status::ok();
657 }
Emilian Peev35ae8262018-11-08 13:11:32 +0000658
659 *status = false;
660 ret = mProviderManager->isSessionConfigurationSupported(mCameraIdStr.string(),
661 streamConfiguration, status);
662 switch (ret) {
663 case OK:
664 // Expected, do nothing.
665 break;
666 case INVALID_OPERATION: {
667 String8 msg = String8::format(
668 "Camera %s: Session configuration query not supported!",
669 mCameraIdStr.string());
670 ALOGD("%s: %s", __FUNCTION__, msg.string());
671 res = STATUS_ERROR(CameraService::ERROR_INVALID_OPERATION, msg.string());
672 }
673
674 break;
675 default: {
676 String8 msg = String8::format( "Camera %s: Error: %s (%d)", mCameraIdStr.string(),
677 strerror(-ret), ret);
678 ALOGE("%s: %s", __FUNCTION__, msg.string());
679 res = STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT,
680 msg.string());
681 }
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800682 }
683
684 return res;
Ruben Brunkb2119af2014-05-09 19:57:56 -0700685}
686
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800687binder::Status CameraDeviceClient::deleteStream(int streamId) {
Igor Murashkine7ee7632013-06-11 18:10:18 -0700688 ATRACE_CALL();
689 ALOGV("%s (streamId = 0x%x)", __FUNCTION__, streamId);
690
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800691 binder::Status res;
692 if (!(res = checkPidStatus(__FUNCTION__)).isOk()) return res;
Igor Murashkine7ee7632013-06-11 18:10:18 -0700693
694 Mutex::Autolock icl(mBinderSerializationLock);
695
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800696 if (!mDevice.get()) {
697 return STATUS_ERROR(CameraService::ERROR_DISCONNECTED, "Camera device no longer alive");
698 }
Igor Murashkine7ee7632013-06-11 18:10:18 -0700699
Chien-Yu Chen618ff8a2015-03-13 11:27:17 -0700700 bool isInput = false;
Shuzhen Wang0129d522016-10-30 22:43:41 -0700701 std::vector<sp<IBinder>> surfaces;
Zhijun He5d677d12016-05-29 16:52:39 -0700702 ssize_t dIndex = NAME_NOT_FOUND;
Emilian Peev538c90e2018-12-17 18:03:19 +0000703 ssize_t compositeIndex = NAME_NOT_FOUND;
Igor Murashkine7ee7632013-06-11 18:10:18 -0700704
Chien-Yu Chen618ff8a2015-03-13 11:27:17 -0700705 if (mInputStream.configured && mInputStream.id == streamId) {
706 isInput = true;
707 } else {
708 // Guard against trying to delete non-created streams
709 for (size_t i = 0; i < mStreamMap.size(); ++i) {
Shuzhen Wang0129d522016-10-30 22:43:41 -0700710 if (streamId == mStreamMap.valueAt(i).streamId()) {
711 surfaces.push_back(mStreamMap.keyAt(i));
712 }
713 }
714
715 // See if this stream is one of the deferred streams.
716 for (size_t i = 0; i < mDeferredStreams.size(); ++i) {
717 if (streamId == mDeferredStreams[i]) {
718 dIndex = i;
Chien-Yu Chen618ff8a2015-03-13 11:27:17 -0700719 break;
720 }
721 }
722
Emilian Peev538c90e2018-12-17 18:03:19 +0000723 for (size_t i = 0; i < mCompositeStreamMap.size(); ++i) {
724 if (streamId == mCompositeStreamMap.valueAt(i)->getStreamId()) {
725 compositeIndex = i;
726 break;
727 }
728 }
729
Shuzhen Wang0129d522016-10-30 22:43:41 -0700730 if (surfaces.empty() && dIndex == NAME_NOT_FOUND) {
731 String8 msg = String8::format("Camera %s: Invalid stream ID (%d) specified, no such"
732 " stream created yet", mCameraIdStr.string(), streamId);
733 ALOGW("%s: %s", __FUNCTION__, msg.string());
734 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
Chien-Yu Chen618ff8a2015-03-13 11:27:17 -0700735 }
Igor Murashkine7ee7632013-06-11 18:10:18 -0700736 }
737
738 // Also returns BAD_VALUE if stream ID was not valid
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800739 status_t err = mDevice->deleteStream(streamId);
Igor Murashkine7ee7632013-06-11 18:10:18 -0700740
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800741 if (err != OK) {
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800742 String8 msg = String8::format("Camera %s: Unexpected error %s (%d) when deleting stream %d",
743 mCameraIdStr.string(), strerror(-err), err, streamId);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800744 ALOGE("%s: %s", __FUNCTION__, msg.string());
745 res = STATUS_ERROR(CameraService::ERROR_INVALID_OPERATION, msg.string());
746 } else {
Chien-Yu Chen618ff8a2015-03-13 11:27:17 -0700747 if (isInput) {
748 mInputStream.configured = false;
Zhijun He5d677d12016-05-29 16:52:39 -0700749 } else {
Shuzhen Wang0129d522016-10-30 22:43:41 -0700750 for (auto& surface : surfaces) {
751 mStreamMap.removeItem(surface);
752 }
753
Yin-Chia Yeh4dfa4cc2017-11-10 20:00:09 -0800754 mConfiguredOutputs.removeItem(streamId);
755
Shuzhen Wang0129d522016-10-30 22:43:41 -0700756 if (dIndex != NAME_NOT_FOUND) {
757 mDeferredStreams.removeItemsAt(dIndex);
758 }
Emilian Peev538c90e2018-12-17 18:03:19 +0000759
760 if (compositeIndex != NAME_NOT_FOUND) {
761 status_t ret;
762 if ((ret = mCompositeStreamMap.valueAt(compositeIndex)->deleteStream())
763 != OK) {
764 String8 msg = String8::format("Camera %s: Unexpected error %s (%d) when "
765 "deleting composite stream %d", mCameraIdStr.string(), strerror(-err), err,
766 streamId);
767 ALOGE("%s: %s", __FUNCTION__, msg.string());
768 res = STATUS_ERROR(CameraService::ERROR_INVALID_OPERATION, msg.string());
769 }
770 mCompositeStreamMap.removeItemsAt(compositeIndex);
771 }
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800772 for (auto &mapIt: mHighResolutionCameraIdToStreamIdSet) {
773 auto &streamSet = mapIt.second;
774 if (streamSet.find(streamId) != streamSet.end()) {
775 streamSet.erase(streamId);
776 break;
777 }
778 }
Chien-Yu Chen618ff8a2015-03-13 11:27:17 -0700779 }
Igor Murashkine7ee7632013-06-11 18:10:18 -0700780 }
781
782 return res;
783}
784
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800785binder::Status CameraDeviceClient::createStream(
786 const hardware::camera2::params::OutputConfiguration &outputConfiguration,
787 /*out*/
788 int32_t* newStreamId) {
Igor Murashkine7ee7632013-06-11 18:10:18 -0700789 ATRACE_CALL();
Igor Murashkine7ee7632013-06-11 18:10:18 -0700790
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800791 binder::Status res;
792 if (!(res = checkPidStatus(__FUNCTION__)).isOk()) return res;
Igor Murashkine7ee7632013-06-11 18:10:18 -0700793
794 Mutex::Autolock icl(mBinderSerializationLock);
795
Shuzhen Wang0129d522016-10-30 22:43:41 -0700796 const std::vector<sp<IGraphicBufferProducer>>& bufferProducers =
797 outputConfiguration.getGraphicBufferProducers();
798 size_t numBufferProducers = bufferProducers.size();
Shuzhen Wang758c2152017-01-10 18:26:18 -0800799 bool deferredConsumer = outputConfiguration.isDeferred();
800 bool isShared = outputConfiguration.isShared();
Shuzhen Wangc28189a2017-11-27 23:05:10 -0800801 String8 physicalCameraId = String8(outputConfiguration.getPhysicalCameraId());
Shuzhen Wang758c2152017-01-10 18:26:18 -0800802 bool deferredConsumerOnly = deferredConsumer && numBufferProducers == 0;
Shuzhen Wang83bff122020-11-20 15:51:39 -0800803 bool isMultiResolution = outputConfiguration.isMultiResolution();
Shuzhen Wang0129d522016-10-30 22:43:41 -0700804
Shuzhen Wangd4abdf72021-05-28 11:22:50 -0700805 res = SessionConfigurationUtils::checkSurfaceType(numBufferProducers, deferredConsumer,
Emilian Peev35ae8262018-11-08 13:11:32 +0000806 outputConfiguration.getSurfaceType());
807 if (!res.isOk()) {
808 return res;
Yin-Chia Yeh89f14da2014-06-10 16:05:44 -0700809 }
Zhijun He5d677d12016-05-29 16:52:39 -0700810
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800811 if (!mDevice.get()) {
812 return STATUS_ERROR(CameraService::ERROR_DISCONNECTED, "Camera device no longer alive");
813 }
Shuzhen Wangd4abdf72021-05-28 11:22:50 -0700814 res = SessionConfigurationUtils::checkPhysicalCameraId(mPhysicalCameraIds,
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800815 physicalCameraId, mCameraIdStr);
Emilian Peev35ae8262018-11-08 13:11:32 +0000816 if (!res.isOk()) {
817 return res;
Shuzhen Wangc28189a2017-11-27 23:05:10 -0800818 }
Emilian Peev35ae8262018-11-08 13:11:32 +0000819
Shuzhen Wang0129d522016-10-30 22:43:41 -0700820 std::vector<sp<Surface>> surfaces;
821 std::vector<sp<IBinder>> binders;
Zhijun He5d677d12016-05-29 16:52:39 -0700822 status_t err;
823
824 // Create stream for deferred surface case.
Shuzhen Wang0129d522016-10-30 22:43:41 -0700825 if (deferredConsumerOnly) {
Shuzhen Wang758c2152017-01-10 18:26:18 -0800826 return createDeferredSurfaceStreamLocked(outputConfiguration, isShared, newStreamId);
Zhijun He5d677d12016-05-29 16:52:39 -0700827 }
828
Shuzhen Wang758c2152017-01-10 18:26:18 -0800829 OutputStreamInfo streamInfo;
830 bool isStreamInfoValid = false;
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800831 const std::vector<int32_t> &sensorPixelModesUsed =
832 outputConfiguration.getSensorPixelModesUsed();
Shuzhen Wang0129d522016-10-30 22:43:41 -0700833 for (auto& bufferProducer : bufferProducers) {
Shuzhen Wang0129d522016-10-30 22:43:41 -0700834 // Don't create multiple streams for the same target surface
Shuzhen Wang0129d522016-10-30 22:43:41 -0700835 sp<IBinder> binder = IInterface::asBinder(bufferProducer);
Shuzhen Wang758c2152017-01-10 18:26:18 -0800836 ssize_t index = mStreamMap.indexOfKey(binder);
837 if (index != NAME_NOT_FOUND) {
838 String8 msg = String8::format("Camera %s: Surface already has a stream created for it "
839 "(ID %zd)", mCameraIdStr.string(), index);
840 ALOGW("%s: %s", __FUNCTION__, msg.string());
841 return STATUS_ERROR(CameraService::ERROR_ALREADY_EXISTS, msg.string());
Shuzhen Wang0129d522016-10-30 22:43:41 -0700842 }
Igor Murashkine7ee7632013-06-11 18:10:18 -0700843
Shuzhen Wang758c2152017-01-10 18:26:18 -0800844 sp<Surface> surface;
Shuzhen Wangd4abdf72021-05-28 11:22:50 -0700845 res = SessionConfigurationUtils::createSurfaceFromGbp(streamInfo,
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800846 isStreamInfoValid, surface, bufferProducer, mCameraIdStr,
847 mDevice->infoPhysical(physicalCameraId), sensorPixelModesUsed);
Shuzhen Wang758c2152017-01-10 18:26:18 -0800848
849 if (!res.isOk())
850 return res;
851
852 if (!isStreamInfoValid) {
853 isStreamInfoValid = true;
Shuzhen Wang0129d522016-10-30 22:43:41 -0700854 }
855
Shuzhen Wang758c2152017-01-10 18:26:18 -0800856 binders.push_back(IInterface::asBinder(bufferProducer));
Shuzhen Wang0129d522016-10-30 22:43:41 -0700857 surfaces.push_back(surface);
Ruben Brunkbba75572014-11-20 17:29:50 -0800858 }
Shuzhen Wangd4abdf72021-05-28 11:22:50 -0700859
860 // If mOverrideForPerfClass is true, do not fail createStream() for small
861 // JPEG sizes because existing createSurfaceFromGbp() logic will find the
862 // closest possible supported size.
863
Zhijun He125684a2015-12-26 15:07:30 -0800864 int streamId = camera3::CAMERA3_STREAM_ID_INVALID;
Emilian Peev40ead602017-09-26 15:46:36 +0100865 std::vector<int> surfaceIds;
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800866 bool isDepthCompositeStream =
867 camera3::DepthCompositeStream::isDepthCompositeStream(surfaces[0]);
Shuzhen Wang68ac7ad2019-01-30 14:03:28 -0800868 bool isHeicCompisiteStream = camera3::HeicCompositeStream::isHeicCompositeStream(surfaces[0]);
869 if (isDepthCompositeStream || isHeicCompisiteStream) {
870 sp<CompositeStream> compositeStream;
871 if (isDepthCompositeStream) {
872 compositeStream = new camera3::DepthCompositeStream(mDevice, getRemoteCallback());
873 } else {
874 compositeStream = new camera3::HeicCompositeStream(mDevice, getRemoteCallback());
875 }
876
Emilian Peev538c90e2018-12-17 18:03:19 +0000877 err = compositeStream->createStream(surfaces, deferredConsumer, streamInfo.width,
878 streamInfo.height, streamInfo.format,
Emilian Peevf4816702020-04-03 15:44:51 -0700879 static_cast<camera_stream_rotation_t>(outputConfiguration.getRotation()),
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800880 &streamId, physicalCameraId, streamInfo.sensorPixelModesUsed, &surfaceIds,
881 outputConfiguration.getSurfaceSetID(), isShared, isMultiResolution);
Emilian Peev538c90e2018-12-17 18:03:19 +0000882 if (err == OK) {
883 mCompositeStreamMap.add(IInterface::asBinder(surfaces[0]->getIGraphicBufferProducer()),
884 compositeStream);
885 }
Shuzhen Wang68ac7ad2019-01-30 14:03:28 -0800886 } else {
887 err = mDevice->createStream(surfaces, deferredConsumer, streamInfo.width,
888 streamInfo.height, streamInfo.format, streamInfo.dataSpace,
Emilian Peevf4816702020-04-03 15:44:51 -0700889 static_cast<camera_stream_rotation_t>(outputConfiguration.getRotation()),
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800890 &streamId, physicalCameraId, streamInfo.sensorPixelModesUsed, &surfaceIds,
891 outputConfiguration.getSurfaceSetID(), isShared, isMultiResolution);
Emilian Peev538c90e2018-12-17 18:03:19 +0000892 }
Igor Murashkine7ee7632013-06-11 18:10:18 -0700893
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800894 if (err != OK) {
895 res = STATUS_ERROR_FMT(CameraService::ERROR_INVALID_OPERATION,
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800896 "Camera %s: Error creating output stream (%d x %d, fmt %x, dataSpace %x): %s (%d)",
Shuzhen Wang758c2152017-01-10 18:26:18 -0800897 mCameraIdStr.string(), streamInfo.width, streamInfo.height, streamInfo.format,
898 streamInfo.dataSpace, strerror(-err), err);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800899 } else {
Shuzhen Wang0129d522016-10-30 22:43:41 -0700900 int i = 0;
901 for (auto& binder : binders) {
902 ALOGV("%s: mStreamMap add binder %p streamId %d, surfaceId %d",
903 __FUNCTION__, binder.get(), streamId, i);
Emilian Peev40ead602017-09-26 15:46:36 +0100904 mStreamMap.add(binder, StreamSurfaceId(streamId, surfaceIds[i]));
905 i++;
Shuzhen Wang0129d522016-10-30 22:43:41 -0700906 }
Shuzhen Wang758c2152017-01-10 18:26:18 -0800907
Yin-Chia Yeh4dfa4cc2017-11-10 20:00:09 -0800908 mConfiguredOutputs.add(streamId, outputConfiguration);
Shuzhen Wang758c2152017-01-10 18:26:18 -0800909 mStreamInfoMap[streamId] = streamInfo;
910
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800911 ALOGV("%s: Camera %s: Successfully created a new stream ID %d for output surface"
Shuzhen Wang0129d522016-10-30 22:43:41 -0700912 " (%d x %d) with format 0x%x.",
Shuzhen Wang758c2152017-01-10 18:26:18 -0800913 __FUNCTION__, mCameraIdStr.string(), streamId, streamInfo.width,
914 streamInfo.height, streamInfo.format);
Igor Murashkinf8b2a6f2013-09-17 17:03:28 -0700915
Zhijun He5d677d12016-05-29 16:52:39 -0700916 // Set transform flags to ensure preview to be rotated correctly.
917 res = setStreamTransformLocked(streamId);
Igor Murashkinf8b2a6f2013-09-17 17:03:28 -0700918
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800919 // Fill in mHighResolutionCameraIdToStreamIdSet map
920 const String8 &cameraIdUsed =
921 physicalCameraId.size() != 0 ? physicalCameraId : mCameraIdStr;
922 const char *cameraIdUsedCStr = cameraIdUsed.string();
923 // Only needed for high resolution sensors
924 if (mHighResolutionSensors.find(cameraIdUsedCStr) !=
925 mHighResolutionSensors.end()) {
926 mHighResolutionCameraIdToStreamIdSet[cameraIdUsedCStr].insert(streamId);
927 }
928
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800929 *newStreamId = streamId;
Igor Murashkine7ee7632013-06-11 18:10:18 -0700930 }
931
932 return res;
933}
934
Zhijun He5d677d12016-05-29 16:52:39 -0700935binder::Status CameraDeviceClient::createDeferredSurfaceStreamLocked(
936 const hardware::camera2::params::OutputConfiguration &outputConfiguration,
Shuzhen Wang758c2152017-01-10 18:26:18 -0800937 bool isShared,
Zhijun He5d677d12016-05-29 16:52:39 -0700938 /*out*/
939 int* newStreamId) {
940 int width, height, format, surfaceType;
Emilian Peev050f5dc2017-05-18 14:43:56 +0100941 uint64_t consumerUsage;
Zhijun He5d677d12016-05-29 16:52:39 -0700942 android_dataspace dataSpace;
943 status_t err;
944 binder::Status res;
945
946 if (!mDevice.get()) {
947 return STATUS_ERROR(CameraService::ERROR_DISCONNECTED, "Camera device no longer alive");
948 }
949
950 // Infer the surface info for deferred surface stream creation.
951 width = outputConfiguration.getWidth();
952 height = outputConfiguration.getHeight();
953 surfaceType = outputConfiguration.getSurfaceType();
954 format = HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED;
955 dataSpace = android_dataspace_t::HAL_DATASPACE_UNKNOWN;
956 // Hardcode consumer usage flags: SurfaceView--0x900, SurfaceTexture--0x100.
957 consumerUsage = GraphicBuffer::USAGE_HW_TEXTURE;
958 if (surfaceType == OutputConfiguration::SURFACE_TYPE_SURFACE_VIEW) {
959 consumerUsage |= GraphicBuffer::USAGE_HW_COMPOSER;
960 }
961 int streamId = camera3::CAMERA3_STREAM_ID_INVALID;
Shuzhen Wang0129d522016-10-30 22:43:41 -0700962 std::vector<sp<Surface>> noSurface;
Emilian Peev40ead602017-09-26 15:46:36 +0100963 std::vector<int> surfaceIds;
Shuzhen Wangc28189a2017-11-27 23:05:10 -0800964 String8 physicalCameraId(outputConfiguration.getPhysicalCameraId());
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800965 const String8 &cameraIdUsed =
966 physicalCameraId.size() != 0 ? physicalCameraId : mCameraIdStr;
967 // Here, we override sensor pixel modes
968 std::unordered_set<int32_t> overriddenSensorPixelModesUsed;
969 const std::vector<int32_t> &sensorPixelModesUsed =
970 outputConfiguration.getSensorPixelModesUsed();
Shuzhen Wangd4abdf72021-05-28 11:22:50 -0700971 if (SessionConfigurationUtils::checkAndOverrideSensorPixelModesUsed(
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800972 sensorPixelModesUsed, format, width, height, getStaticInfo(cameraIdUsed),
973 /*allowRounding*/ false, &overriddenSensorPixelModesUsed) != OK) {
974 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT,
975 "sensor pixel modes used not valid for deferred stream");
976 }
977
Shuzhen Wang0129d522016-10-30 22:43:41 -0700978 err = mDevice->createStream(noSurface, /*hasDeferredConsumer*/true, width,
979 height, format, dataSpace,
Emilian Peevf4816702020-04-03 15:44:51 -0700980 static_cast<camera_stream_rotation_t>(outputConfiguration.getRotation()),
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800981 &streamId, physicalCameraId,
982 overriddenSensorPixelModesUsed,
983 &surfaceIds,
Shuzhen Wangc28189a2017-11-27 23:05:10 -0800984 outputConfiguration.getSurfaceSetID(), isShared,
Shuzhen Wang83bff122020-11-20 15:51:39 -0800985 outputConfiguration.isMultiResolution(), consumerUsage);
Zhijun He5d677d12016-05-29 16:52:39 -0700986
987 if (err != OK) {
988 res = STATUS_ERROR_FMT(CameraService::ERROR_INVALID_OPERATION,
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800989 "Camera %s: Error creating output stream (%d x %d, fmt %x, dataSpace %x): %s (%d)",
990 mCameraIdStr.string(), width, height, format, dataSpace, strerror(-err), err);
Zhijun He5d677d12016-05-29 16:52:39 -0700991 } else {
992 // Can not add streamId to mStreamMap here, as the surface is deferred. Add it to
993 // a separate list to track. Once the deferred surface is set, this id will be
994 // relocated to mStreamMap.
995 mDeferredStreams.push_back(streamId);
Shuzhen Wang758c2152017-01-10 18:26:18 -0800996 mStreamInfoMap.emplace(std::piecewise_construct, std::forward_as_tuple(streamId),
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800997 std::forward_as_tuple(width, height, format, dataSpace, consumerUsage,
998 overriddenSensorPixelModesUsed));
Shuzhen Wang758c2152017-01-10 18:26:18 -0800999
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -08001000 ALOGV("%s: Camera %s: Successfully created a new stream ID %d for a deferred surface"
Zhijun He5d677d12016-05-29 16:52:39 -07001001 " (%d x %d) stream with format 0x%x.",
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -08001002 __FUNCTION__, mCameraIdStr.string(), streamId, width, height, format);
Zhijun He5d677d12016-05-29 16:52:39 -07001003
1004 // Set transform flags to ensure preview to be rotated correctly.
1005 res = setStreamTransformLocked(streamId);
1006
1007 *newStreamId = streamId;
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -08001008 // Fill in mHighResolutionCameraIdToStreamIdSet
1009 const char *cameraIdUsedCStr = cameraIdUsed.string();
1010 // Only needed for high resolution sensors
1011 if (mHighResolutionSensors.find(cameraIdUsedCStr) !=
1012 mHighResolutionSensors.end()) {
1013 mHighResolutionCameraIdToStreamIdSet[cameraIdUsed.string()].insert(streamId);
1014 }
Zhijun He5d677d12016-05-29 16:52:39 -07001015 }
1016 return res;
1017}
1018
1019binder::Status CameraDeviceClient::setStreamTransformLocked(int streamId) {
1020 int32_t transform = 0;
1021 status_t err;
1022 binder::Status res;
1023
1024 if (!mDevice.get()) {
1025 return STATUS_ERROR(CameraService::ERROR_DISCONNECTED, "Camera device no longer alive");
1026 }
1027
1028 err = getRotationTransformLocked(&transform);
1029 if (err != OK) {
1030 // Error logged by getRotationTransformLocked.
1031 return STATUS_ERROR(CameraService::ERROR_INVALID_OPERATION,
1032 "Unable to calculate rotation transform for new stream");
1033 }
1034
1035 err = mDevice->setStreamTransform(streamId, transform);
1036 if (err != OK) {
1037 String8 msg = String8::format("Failed to set stream transform (stream id %d)",
1038 streamId);
1039 ALOGE("%s: %s", __FUNCTION__, msg.string());
1040 return STATUS_ERROR(CameraService::ERROR_INVALID_OPERATION, msg.string());
1041 }
1042
1043 return res;
1044}
Ruben Brunkbba75572014-11-20 17:29:50 -08001045
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001046binder::Status CameraDeviceClient::createInputStream(
Shuzhen Wang83bff122020-11-20 15:51:39 -08001047 int width, int height, int format, bool isMultiResolution,
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001048 /*out*/
1049 int32_t* newStreamId) {
Chien-Yu Chen618ff8a2015-03-13 11:27:17 -07001050
1051 ATRACE_CALL();
Shuzhen Wang83bff122020-11-20 15:51:39 -08001052 ALOGV("%s (w = %d, h = %d, f = 0x%x, isMultiResolution %d)", __FUNCTION__,
1053 width, height, format, isMultiResolution);
Chien-Yu Chen618ff8a2015-03-13 11:27:17 -07001054
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001055 binder::Status res;
1056 if (!(res = checkPidStatus(__FUNCTION__)).isOk()) return res;
Chien-Yu Chen618ff8a2015-03-13 11:27:17 -07001057
1058 Mutex::Autolock icl(mBinderSerializationLock);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001059
1060 if (!mDevice.get()) {
1061 return STATUS_ERROR(CameraService::ERROR_DISCONNECTED, "Camera device no longer alive");
1062 }
Chien-Yu Chen618ff8a2015-03-13 11:27:17 -07001063
1064 if (mInputStream.configured) {
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -08001065 String8 msg = String8::format("Camera %s: Already has an input stream "
Yi Kong0f414de2017-12-15 13:48:50 -08001066 "configured (ID %d)", mCameraIdStr.string(), mInputStream.id);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001067 ALOGE("%s: %s", __FUNCTION__, msg.string() );
1068 return STATUS_ERROR(CameraService::ERROR_ALREADY_EXISTS, msg.string());
Chien-Yu Chen618ff8a2015-03-13 11:27:17 -07001069 }
1070
1071 int streamId = -1;
Shuzhen Wang83bff122020-11-20 15:51:39 -08001072 status_t err = mDevice->createInputStream(width, height, format, isMultiResolution, &streamId);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001073 if (err == OK) {
Chien-Yu Chen618ff8a2015-03-13 11:27:17 -07001074 mInputStream.configured = true;
1075 mInputStream.width = width;
1076 mInputStream.height = height;
1077 mInputStream.format = format;
1078 mInputStream.id = streamId;
1079
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -08001080 ALOGV("%s: Camera %s: Successfully created a new input stream ID %d",
1081 __FUNCTION__, mCameraIdStr.string(), streamId);
Chien-Yu Chen618ff8a2015-03-13 11:27:17 -07001082
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001083 *newStreamId = streamId;
1084 } else {
1085 res = STATUS_ERROR_FMT(CameraService::ERROR_INVALID_OPERATION,
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -08001086 "Camera %s: Error creating new input stream: %s (%d)", mCameraIdStr.string(),
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001087 strerror(-err), err);
Chien-Yu Chen618ff8a2015-03-13 11:27:17 -07001088 }
1089
1090 return res;
1091}
1092
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001093binder::Status CameraDeviceClient::getInputSurface(/*out*/ view::Surface *inputSurface) {
Chien-Yu Chen618ff8a2015-03-13 11:27:17 -07001094
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001095 binder::Status res;
1096 if (!(res = checkPidStatus(__FUNCTION__)).isOk()) return res;
1097
1098 if (inputSurface == NULL) {
1099 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, "Null input surface");
Chien-Yu Chen618ff8a2015-03-13 11:27:17 -07001100 }
1101
1102 Mutex::Autolock icl(mBinderSerializationLock);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001103 if (!mDevice.get()) {
1104 return STATUS_ERROR(CameraService::ERROR_DISCONNECTED, "Camera device no longer alive");
1105 }
1106 sp<IGraphicBufferProducer> producer;
1107 status_t err = mDevice->getInputBufferProducer(&producer);
1108 if (err != OK) {
1109 res = STATUS_ERROR_FMT(CameraService::ERROR_INVALID_OPERATION,
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -08001110 "Camera %s: Error getting input Surface: %s (%d)",
1111 mCameraIdStr.string(), strerror(-err), err);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001112 } else {
1113 inputSurface->name = String16("CameraInput");
1114 inputSurface->graphicBufferProducer = producer;
1115 }
1116 return res;
Chien-Yu Chen618ff8a2015-03-13 11:27:17 -07001117}
1118
Emilian Peev40ead602017-09-26 15:46:36 +01001119binder::Status CameraDeviceClient::updateOutputConfiguration(int streamId,
1120 const hardware::camera2::params::OutputConfiguration &outputConfiguration) {
1121 ATRACE_CALL();
1122
1123 binder::Status res;
1124 if (!(res = checkPidStatus(__FUNCTION__)).isOk()) return res;
1125
1126 Mutex::Autolock icl(mBinderSerializationLock);
1127
1128 if (!mDevice.get()) {
1129 return STATUS_ERROR(CameraService::ERROR_DISCONNECTED, "Camera device no longer alive");
1130 }
1131
1132 const std::vector<sp<IGraphicBufferProducer> >& bufferProducers =
1133 outputConfiguration.getGraphicBufferProducers();
Shuzhen Wang2e7f58f2018-07-11 14:00:29 -07001134 String8 physicalCameraId(outputConfiguration.getPhysicalCameraId());
1135
Emilian Peev40ead602017-09-26 15:46:36 +01001136 auto producerCount = bufferProducers.size();
1137 if (producerCount == 0) {
1138 ALOGE("%s: bufferProducers must not be empty", __FUNCTION__);
1139 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT,
1140 "bufferProducers must not be empty");
1141 }
1142
1143 // The first output is the one associated with the output configuration.
1144 // It should always be present, valid and the corresponding stream id should match.
1145 sp<IBinder> binder = IInterface::asBinder(bufferProducers[0]);
1146 ssize_t index = mStreamMap.indexOfKey(binder);
1147 if (index == NAME_NOT_FOUND) {
1148 ALOGE("%s: Outputconfiguration is invalid", __FUNCTION__);
1149 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT,
1150 "OutputConfiguration is invalid");
1151 }
1152 if (mStreamMap.valueFor(binder).streamId() != streamId) {
1153 ALOGE("%s: Stream Id: %d provided doesn't match the id: %d in the stream map",
1154 __FUNCTION__, streamId, mStreamMap.valueFor(binder).streamId());
1155 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT,
1156 "Stream id is invalid");
1157 }
1158
1159 std::vector<size_t> removedSurfaceIds;
1160 std::vector<sp<IBinder>> removedOutputs;
1161 std::vector<sp<Surface>> newOutputs;
1162 std::vector<OutputStreamInfo> streamInfos;
1163 KeyedVector<sp<IBinder>, sp<IGraphicBufferProducer>> newOutputsMap;
1164 for (auto &it : bufferProducers) {
1165 newOutputsMap.add(IInterface::asBinder(it), it);
1166 }
1167
1168 for (size_t i = 0; i < mStreamMap.size(); i++) {
1169 ssize_t idx = newOutputsMap.indexOfKey(mStreamMap.keyAt(i));
1170 if (idx == NAME_NOT_FOUND) {
1171 if (mStreamMap[i].streamId() == streamId) {
1172 removedSurfaceIds.push_back(mStreamMap[i].surfaceId());
1173 removedOutputs.push_back(mStreamMap.keyAt(i));
1174 }
1175 } else {
1176 if (mStreamMap[i].streamId() != streamId) {
1177 ALOGE("%s: Output surface already part of a different stream", __FUNCTION__);
1178 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT,
1179 "Target Surface is invalid");
1180 }
1181 newOutputsMap.removeItemsAt(idx);
1182 }
1183 }
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -08001184 const std::vector<int32_t> &sensorPixelModesUsed =
1185 outputConfiguration.getSensorPixelModesUsed();
Emilian Peev40ead602017-09-26 15:46:36 +01001186
1187 for (size_t i = 0; i < newOutputsMap.size(); i++) {
1188 OutputStreamInfo outInfo;
1189 sp<Surface> surface;
Shuzhen Wangd4abdf72021-05-28 11:22:50 -07001190 res = SessionConfigurationUtils::createSurfaceFromGbp(outInfo,
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -08001191 /*isStreamInfoValid*/ false, surface, newOutputsMap.valueAt(i), mCameraIdStr,
1192 mDevice->infoPhysical(physicalCameraId), sensorPixelModesUsed);
Emilian Peev40ead602017-09-26 15:46:36 +01001193 if (!res.isOk())
1194 return res;
1195
Emilian Peev40ead602017-09-26 15:46:36 +01001196 streamInfos.push_back(outInfo);
1197 newOutputs.push_back(surface);
1198 }
1199
1200 //Trivial case no changes required
1201 if (removedSurfaceIds.empty() && newOutputs.empty()) {
1202 return binder::Status::ok();
1203 }
1204
1205 KeyedVector<sp<Surface>, size_t> outputMap;
1206 auto ret = mDevice->updateStream(streamId, newOutputs, streamInfos, removedSurfaceIds,
1207 &outputMap);
1208 if (ret != OK) {
1209 switch (ret) {
1210 case NAME_NOT_FOUND:
1211 case BAD_VALUE:
1212 case -EBUSY:
1213 res = STATUS_ERROR_FMT(CameraService::ERROR_ILLEGAL_ARGUMENT,
1214 "Camera %s: Error updating stream: %s (%d)",
1215 mCameraIdStr.string(), strerror(ret), ret);
1216 break;
1217 default:
1218 res = STATUS_ERROR_FMT(CameraService::ERROR_INVALID_OPERATION,
1219 "Camera %s: Error updating stream: %s (%d)",
1220 mCameraIdStr.string(), strerror(ret), ret);
1221 break;
1222 }
1223 } else {
1224 for (const auto &it : removedOutputs) {
1225 mStreamMap.removeItem(it);
1226 }
1227
1228 for (size_t i = 0; i < outputMap.size(); i++) {
1229 mStreamMap.add(IInterface::asBinder(outputMap.keyAt(i)->getIGraphicBufferProducer()),
1230 StreamSurfaceId(streamId, outputMap.valueAt(i)));
1231 }
1232
Yin-Chia Yeh4dfa4cc2017-11-10 20:00:09 -08001233 mConfiguredOutputs.replaceValueFor(streamId, outputConfiguration);
1234
Emilian Peev40ead602017-09-26 15:46:36 +01001235 ALOGV("%s: Camera %s: Successful stream ID %d update",
1236 __FUNCTION__, mCameraIdStr.string(), streamId);
1237 }
1238
1239 return res;
1240}
1241
Igor Murashkine7ee7632013-06-11 18:10:18 -07001242// Create a request object from a template.
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001243binder::Status CameraDeviceClient::createDefaultRequest(int templateId,
1244 /*out*/
1245 hardware::camera2::impl::CameraMetadataNative* request)
Igor Murashkine7ee7632013-06-11 18:10:18 -07001246{
1247 ATRACE_CALL();
1248 ALOGV("%s (templateId = 0x%x)", __FUNCTION__, templateId);
1249
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001250 binder::Status res;
1251 if (!(res = checkPidStatus(__FUNCTION__)).isOk()) return res;
Igor Murashkine7ee7632013-06-11 18:10:18 -07001252
1253 Mutex::Autolock icl(mBinderSerializationLock);
1254
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001255 if (!mDevice.get()) {
1256 return STATUS_ERROR(CameraService::ERROR_DISCONNECTED, "Camera device no longer alive");
1257 }
Igor Murashkine7ee7632013-06-11 18:10:18 -07001258
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001259 status_t err;
Emilian Peevf4816702020-04-03 15:44:51 -07001260 camera_request_template_t tempId = camera_request_template_t::CAMERA_TEMPLATE_COUNT;
1261 if (!(res = mapRequestTemplate(templateId, &tempId)).isOk()) return res;
1262
1263 CameraMetadata metadata;
1264 if ( (err = mDevice->createDefaultRequest(tempId, &metadata) ) == OK &&
Igor Murashkine7ee7632013-06-11 18:10:18 -07001265 request != NULL) {
1266
1267 request->swap(metadata);
Chien-Yu Chen9cd14022016-03-09 12:21:01 -08001268 } else if (err == BAD_VALUE) {
1269 res = STATUS_ERROR_FMT(CameraService::ERROR_ILLEGAL_ARGUMENT,
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -08001270 "Camera %s: Template ID %d is invalid or not supported: %s (%d)",
1271 mCameraIdStr.string(), templateId, strerror(-err), err);
Chien-Yu Chen9cd14022016-03-09 12:21:01 -08001272
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001273 } else {
1274 res = STATUS_ERROR_FMT(CameraService::ERROR_INVALID_OPERATION,
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -08001275 "Camera %s: Error creating default request for template %d: %s (%d)",
1276 mCameraIdStr.string(), templateId, strerror(-err), err);
Igor Murashkine7ee7632013-06-11 18:10:18 -07001277 }
Igor Murashkine7ee7632013-06-11 18:10:18 -07001278 return res;
1279}
1280
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001281binder::Status CameraDeviceClient::getCameraInfo(
1282 /*out*/
1283 hardware::camera2::impl::CameraMetadataNative* info)
Igor Murashkine7ee7632013-06-11 18:10:18 -07001284{
1285 ATRACE_CALL();
1286 ALOGV("%s", __FUNCTION__);
1287
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001288 binder::Status res;
Igor Murashkine7ee7632013-06-11 18:10:18 -07001289
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001290 if (!(res = checkPidStatus(__FUNCTION__)).isOk()) return res;
Igor Murashkine7ee7632013-06-11 18:10:18 -07001291
1292 Mutex::Autolock icl(mBinderSerializationLock);
1293
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001294 if (!mDevice.get()) {
1295 return STATUS_ERROR(CameraService::ERROR_DISCONNECTED, "Camera device no longer alive");
1296 }
Igor Murashkine7ee7632013-06-11 18:10:18 -07001297
Igor Murashkin099b4572013-07-12 17:52:16 -07001298 if (info != NULL) {
1299 *info = mDevice->info(); // static camera metadata
1300 // TODO: merge with device-specific camera metadata
1301 }
Igor Murashkine7ee7632013-06-11 18:10:18 -07001302
1303 return res;
1304}
1305
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001306binder::Status CameraDeviceClient::waitUntilIdle()
Zhijun He2ab500c2013-07-23 08:02:53 -07001307{
1308 ATRACE_CALL();
1309 ALOGV("%s", __FUNCTION__);
1310
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001311 binder::Status res;
1312 if (!(res = checkPidStatus(__FUNCTION__)).isOk()) return res;
Zhijun He2ab500c2013-07-23 08:02:53 -07001313
1314 Mutex::Autolock icl(mBinderSerializationLock);
1315
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001316 if (!mDevice.get()) {
1317 return STATUS_ERROR(CameraService::ERROR_DISCONNECTED, "Camera device no longer alive");
1318 }
Zhijun He2ab500c2013-07-23 08:02:53 -07001319
1320 // FIXME: Also need check repeating burst.
Shuzhen Wangc9ca6782016-04-26 13:40:31 -07001321 Mutex::Autolock idLock(mStreamingRequestIdLock);
Chien-Yu Chene8c535e2016-04-14 12:18:26 -07001322 if (mStreamingRequestId != REQUEST_ID_NONE) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001323 String8 msg = String8::format(
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -08001324 "Camera %s: Try to waitUntilIdle when there are active streaming requests",
1325 mCameraIdStr.string());
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001326 ALOGE("%s: %s", __FUNCTION__, msg.string());
1327 return STATUS_ERROR(CameraService::ERROR_INVALID_OPERATION, msg.string());
Zhijun He2ab500c2013-07-23 08:02:53 -07001328 }
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001329 status_t err = mDevice->waitUntilDrained();
1330 if (err != OK) {
1331 res = STATUS_ERROR_FMT(CameraService::ERROR_INVALID_OPERATION,
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -08001332 "Camera %s: Error waiting to drain: %s (%d)",
1333 mCameraIdStr.string(), strerror(-err), err);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001334 }
Zhijun He2ab500c2013-07-23 08:02:53 -07001335 ALOGV("%s Done", __FUNCTION__);
Zhijun He2ab500c2013-07-23 08:02:53 -07001336 return res;
1337}
1338
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001339binder::Status CameraDeviceClient::flush(
1340 /*out*/
1341 int64_t* lastFrameNumber) {
Eino-Ville Talvalaabaa51d2013-08-14 11:37:00 -07001342 ATRACE_CALL();
1343 ALOGV("%s", __FUNCTION__);
1344
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001345 binder::Status res;
1346 if (!(res = checkPidStatus(__FUNCTION__)).isOk()) return res;
Eino-Ville Talvalaabaa51d2013-08-14 11:37:00 -07001347
1348 Mutex::Autolock icl(mBinderSerializationLock);
1349
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001350 if (!mDevice.get()) {
1351 return STATUS_ERROR(CameraService::ERROR_DISCONNECTED, "Camera device no longer alive");
1352 }
Eino-Ville Talvalaabaa51d2013-08-14 11:37:00 -07001353
Shuzhen Wangc9ca6782016-04-26 13:40:31 -07001354 Mutex::Autolock idLock(mStreamingRequestIdLock);
Chien-Yu Chene8c535e2016-04-14 12:18:26 -07001355 mStreamingRequestId = REQUEST_ID_NONE;
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001356 status_t err = mDevice->flush(lastFrameNumber);
1357 if (err != OK) {
1358 res = STATUS_ERROR_FMT(CameraService::ERROR_INVALID_OPERATION,
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -08001359 "Camera %s: Error flushing device: %s (%d)", mCameraIdStr.string(), strerror(-err), err);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001360 }
1361 return res;
Eino-Ville Talvalaabaa51d2013-08-14 11:37:00 -07001362}
1363
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001364binder::Status CameraDeviceClient::prepare(int streamId) {
Eino-Ville Talvala4d44cad2015-04-11 13:15:45 -07001365 ATRACE_CALL();
1366 ALOGV("%s", __FUNCTION__);
1367
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001368 binder::Status res;
1369 if (!(res = checkPidStatus(__FUNCTION__)).isOk()) return res;
Eino-Ville Talvala4d44cad2015-04-11 13:15:45 -07001370
1371 Mutex::Autolock icl(mBinderSerializationLock);
1372
1373 // Guard against trying to prepare non-created streams
1374 ssize_t index = NAME_NOT_FOUND;
1375 for (size_t i = 0; i < mStreamMap.size(); ++i) {
Shuzhen Wang0129d522016-10-30 22:43:41 -07001376 if (streamId == mStreamMap.valueAt(i).streamId()) {
Eino-Ville Talvala4d44cad2015-04-11 13:15:45 -07001377 index = i;
1378 break;
1379 }
1380 }
1381
1382 if (index == NAME_NOT_FOUND) {
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -08001383 String8 msg = String8::format("Camera %s: Invalid stream ID (%d) specified, no stream "
1384 "with that ID exists", mCameraIdStr.string(), streamId);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001385 ALOGW("%s: %s", __FUNCTION__, msg.string());
1386 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
Eino-Ville Talvala4d44cad2015-04-11 13:15:45 -07001387 }
1388
Eino-Ville Talvala261394e2015-05-13 14:28:38 -07001389 // Also returns BAD_VALUE if stream ID was not valid, or stream already
1390 // has been used
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001391 status_t err = mDevice->prepare(streamId);
1392 if (err == BAD_VALUE) {
1393 res = STATUS_ERROR_FMT(CameraService::ERROR_ILLEGAL_ARGUMENT,
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -08001394 "Camera %s: Stream %d has already been used, and cannot be prepared",
1395 mCameraIdStr.string(), streamId);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001396 } else if (err != OK) {
1397 res = STATUS_ERROR_FMT(CameraService::ERROR_INVALID_OPERATION,
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -08001398 "Camera %s: Error preparing stream %d: %s (%d)", mCameraIdStr.string(), streamId,
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001399 strerror(-err), err);
1400 }
Eino-Ville Talvala4d44cad2015-04-11 13:15:45 -07001401 return res;
1402}
1403
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001404binder::Status CameraDeviceClient::prepare2(int maxCount, int streamId) {
Ruben Brunkc78ac262015-08-13 17:58:46 -07001405 ATRACE_CALL();
1406 ALOGV("%s", __FUNCTION__);
1407
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001408 binder::Status res;
1409 if (!(res = checkPidStatus(__FUNCTION__)).isOk()) return res;
Ruben Brunkc78ac262015-08-13 17:58:46 -07001410
1411 Mutex::Autolock icl(mBinderSerializationLock);
1412
1413 // Guard against trying to prepare non-created streams
1414 ssize_t index = NAME_NOT_FOUND;
1415 for (size_t i = 0; i < mStreamMap.size(); ++i) {
Shuzhen Wang0129d522016-10-30 22:43:41 -07001416 if (streamId == mStreamMap.valueAt(i).streamId()) {
Ruben Brunkc78ac262015-08-13 17:58:46 -07001417 index = i;
1418 break;
1419 }
1420 }
1421
1422 if (index == NAME_NOT_FOUND) {
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -08001423 String8 msg = String8::format("Camera %s: Invalid stream ID (%d) specified, no stream "
1424 "with that ID exists", mCameraIdStr.string(), streamId);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001425 ALOGW("%s: %s", __FUNCTION__, msg.string());
1426 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
Ruben Brunkc78ac262015-08-13 17:58:46 -07001427 }
1428
1429 if (maxCount <= 0) {
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -08001430 String8 msg = String8::format("Camera %s: maxCount (%d) must be greater than 0",
1431 mCameraIdStr.string(), maxCount);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001432 ALOGE("%s: %s", __FUNCTION__, msg.string());
1433 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
Ruben Brunkc78ac262015-08-13 17:58:46 -07001434 }
1435
1436 // Also returns BAD_VALUE if stream ID was not valid, or stream already
1437 // has been used
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001438 status_t err = mDevice->prepare(maxCount, streamId);
1439 if (err == BAD_VALUE) {
1440 res = STATUS_ERROR_FMT(CameraService::ERROR_ILLEGAL_ARGUMENT,
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -08001441 "Camera %s: Stream %d has already been used, and cannot be prepared",
1442 mCameraIdStr.string(), streamId);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001443 } else if (err != OK) {
1444 res = STATUS_ERROR_FMT(CameraService::ERROR_INVALID_OPERATION,
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -08001445 "Camera %s: Error preparing stream %d: %s (%d)", mCameraIdStr.string(), streamId,
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001446 strerror(-err), err);
1447 }
Ruben Brunkc78ac262015-08-13 17:58:46 -07001448
1449 return res;
1450}
1451
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001452binder::Status CameraDeviceClient::tearDown(int streamId) {
Eino-Ville Talvalab25e3c82015-07-15 16:04:27 -07001453 ATRACE_CALL();
1454 ALOGV("%s", __FUNCTION__);
1455
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001456 binder::Status res;
1457 if (!(res = checkPidStatus(__FUNCTION__)).isOk()) return res;
Eino-Ville Talvalab25e3c82015-07-15 16:04:27 -07001458
1459 Mutex::Autolock icl(mBinderSerializationLock);
1460
1461 // Guard against trying to prepare non-created streams
1462 ssize_t index = NAME_NOT_FOUND;
1463 for (size_t i = 0; i < mStreamMap.size(); ++i) {
Shuzhen Wang0129d522016-10-30 22:43:41 -07001464 if (streamId == mStreamMap.valueAt(i).streamId()) {
Eino-Ville Talvalab25e3c82015-07-15 16:04:27 -07001465 index = i;
1466 break;
1467 }
1468 }
1469
1470 if (index == NAME_NOT_FOUND) {
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -08001471 String8 msg = String8::format("Camera %s: Invalid stream ID (%d) specified, no stream "
1472 "with that ID exists", mCameraIdStr.string(), streamId);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001473 ALOGW("%s: %s", __FUNCTION__, msg.string());
1474 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
Eino-Ville Talvalab25e3c82015-07-15 16:04:27 -07001475 }
1476
1477 // Also returns BAD_VALUE if stream ID was not valid or if the stream is in
1478 // use
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001479 status_t err = mDevice->tearDown(streamId);
1480 if (err == BAD_VALUE) {
1481 res = STATUS_ERROR_FMT(CameraService::ERROR_ILLEGAL_ARGUMENT,
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -08001482 "Camera %s: Stream %d is still in use, cannot be torn down",
1483 mCameraIdStr.string(), streamId);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001484 } else if (err != OK) {
1485 res = STATUS_ERROR_FMT(CameraService::ERROR_INVALID_OPERATION,
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -08001486 "Camera %s: Error tearing down stream %d: %s (%d)", mCameraIdStr.string(), streamId,
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001487 strerror(-err), err);
1488 }
Eino-Ville Talvalab25e3c82015-07-15 16:04:27 -07001489
1490 return res;
1491}
1492
Shuzhen Wang758c2152017-01-10 18:26:18 -08001493binder::Status CameraDeviceClient::finalizeOutputConfigurations(int32_t streamId,
Zhijun He5d677d12016-05-29 16:52:39 -07001494 const hardware::camera2::params::OutputConfiguration &outputConfiguration) {
1495 ATRACE_CALL();
1496
1497 binder::Status res;
1498 if (!(res = checkPidStatus(__FUNCTION__)).isOk()) return res;
1499
1500 Mutex::Autolock icl(mBinderSerializationLock);
1501
Shuzhen Wang0129d522016-10-30 22:43:41 -07001502 const std::vector<sp<IGraphicBufferProducer> >& bufferProducers =
1503 outputConfiguration.getGraphicBufferProducers();
Shuzhen Wang2e7f58f2018-07-11 14:00:29 -07001504 String8 physicalId(outputConfiguration.getPhysicalCameraId());
Zhijun He5d677d12016-05-29 16:52:39 -07001505
Shuzhen Wang0129d522016-10-30 22:43:41 -07001506 if (bufferProducers.size() == 0) {
1507 ALOGE("%s: bufferProducers must not be empty", __FUNCTION__);
Zhijun He5d677d12016-05-29 16:52:39 -07001508 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, "Target Surface is invalid");
1509 }
Shuzhen Wang0129d522016-10-30 22:43:41 -07001510
Shuzhen Wang758c2152017-01-10 18:26:18 -08001511 // streamId should be in mStreamMap if this stream already has a surface attached
1512 // to it. Otherwise, it should be in mDeferredStreams.
1513 bool streamIdConfigured = false;
1514 ssize_t deferredStreamIndex = NAME_NOT_FOUND;
1515 for (size_t i = 0; i < mStreamMap.size(); i++) {
1516 if (mStreamMap.valueAt(i).streamId() == streamId) {
1517 streamIdConfigured = true;
1518 break;
1519 }
Zhijun He5d677d12016-05-29 16:52:39 -07001520 }
Shuzhen Wang758c2152017-01-10 18:26:18 -08001521 for (size_t i = 0; i < mDeferredStreams.size(); i++) {
1522 if (streamId == mDeferredStreams[i]) {
1523 deferredStreamIndex = i;
1524 break;
Shuzhen Wang0129d522016-10-30 22:43:41 -07001525 }
1526
Shuzhen Wang758c2152017-01-10 18:26:18 -08001527 }
1528 if (deferredStreamIndex == NAME_NOT_FOUND && !streamIdConfigured) {
1529 String8 msg = String8::format("Camera %s: deferred surface is set to a unknown stream"
1530 "(ID %d)", mCameraIdStr.string(), streamId);
1531 ALOGW("%s: %s", __FUNCTION__, msg.string());
1532 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
Zhijun He5d677d12016-05-29 16:52:39 -07001533 }
1534
Shuzhen Wang88fd0052017-02-09 16:40:07 -08001535 if (mStreamInfoMap[streamId].finalized) {
1536 String8 msg = String8::format("Camera %s: finalizeOutputConfigurations has been called"
1537 " on stream ID %d", mCameraIdStr.string(), streamId);
1538 ALOGW("%s: %s", __FUNCTION__, msg.string());
1539 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
1540 }
1541
Zhijun He5d677d12016-05-29 16:52:39 -07001542 if (!mDevice.get()) {
1543 return STATUS_ERROR(CameraService::ERROR_DISCONNECTED, "Camera device no longer alive");
1544 }
1545
Shuzhen Wang758c2152017-01-10 18:26:18 -08001546 std::vector<sp<Surface>> consumerSurfaces;
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -08001547 const std::vector<int32_t> &sensorPixelModesUsed =
1548 outputConfiguration.getSensorPixelModesUsed();
Shuzhen Wang758c2152017-01-10 18:26:18 -08001549 for (auto& bufferProducer : bufferProducers) {
1550 // Don't create multiple streams for the same target surface
Zhijun He5d677d12016-05-29 16:52:39 -07001551 ssize_t index = mStreamMap.indexOfKey(IInterface::asBinder(bufferProducer));
1552 if (index != NAME_NOT_FOUND) {
Shuzhen Wang758c2152017-01-10 18:26:18 -08001553 ALOGV("Camera %s: Surface already has a stream created "
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -08001554 " for it (ID %zd)", mCameraIdStr.string(), index);
Shuzhen Wang758c2152017-01-10 18:26:18 -08001555 continue;
Zhijun He5d677d12016-05-29 16:52:39 -07001556 }
Shuzhen Wang758c2152017-01-10 18:26:18 -08001557
1558 sp<Surface> surface;
Shuzhen Wangd4abdf72021-05-28 11:22:50 -07001559 res = SessionConfigurationUtils::createSurfaceFromGbp(mStreamInfoMap[streamId],
Colin Crossb8a9dbb2020-08-27 04:12:26 +00001560 true /*isStreamInfoValid*/, surface, bufferProducer, mCameraIdStr,
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -08001561 mDevice->infoPhysical(physicalId), sensorPixelModesUsed);
Shuzhen Wang758c2152017-01-10 18:26:18 -08001562
1563 if (!res.isOk())
1564 return res;
1565
1566 consumerSurfaces.push_back(surface);
Zhijun He5d677d12016-05-29 16:52:39 -07001567 }
1568
Shuzhen Wanga81ce342017-04-13 15:18:36 -07001569 // Gracefully handle case where finalizeOutputConfigurations is called
1570 // without any new surface.
1571 if (consumerSurfaces.size() == 0) {
1572 mStreamInfoMap[streamId].finalized = true;
1573 return res;
1574 }
1575
Zhijun He5d677d12016-05-29 16:52:39 -07001576 // Finish the deferred stream configuration with the surface.
Shuzhen Wang758c2152017-01-10 18:26:18 -08001577 status_t err;
Emilian Peev40ead602017-09-26 15:46:36 +01001578 std::vector<int> consumerSurfaceIds;
1579 err = mDevice->setConsumerSurfaces(streamId, consumerSurfaces, &consumerSurfaceIds);
Zhijun He5d677d12016-05-29 16:52:39 -07001580 if (err == OK) {
Shuzhen Wang758c2152017-01-10 18:26:18 -08001581 for (size_t i = 0; i < consumerSurfaces.size(); i++) {
1582 sp<IBinder> binder = IInterface::asBinder(
1583 consumerSurfaces[i]->getIGraphicBufferProducer());
Emilian Peev40ead602017-09-26 15:46:36 +01001584 ALOGV("%s: mStreamMap add binder %p streamId %d, surfaceId %d", __FUNCTION__,
Shuzhen Wang758c2152017-01-10 18:26:18 -08001585 binder.get(), streamId, consumerSurfaceIds[i]);
1586 mStreamMap.add(binder, StreamSurfaceId(streamId, consumerSurfaceIds[i]));
1587 }
1588 if (deferredStreamIndex != NAME_NOT_FOUND) {
1589 mDeferredStreams.removeItemsAt(deferredStreamIndex);
Shuzhen Wang0129d522016-10-30 22:43:41 -07001590 }
Shuzhen Wang88fd0052017-02-09 16:40:07 -08001591 mStreamInfoMap[streamId].finalized = true;
Yin-Chia Yeh4dfa4cc2017-11-10 20:00:09 -08001592 mConfiguredOutputs.replaceValueFor(streamId, outputConfiguration);
Zhijun He5d677d12016-05-29 16:52:39 -07001593 } else if (err == NO_INIT) {
1594 res = STATUS_ERROR_FMT(CameraService::ERROR_ILLEGAL_ARGUMENT,
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -08001595 "Camera %s: Deferred surface is invalid: %s (%d)",
1596 mCameraIdStr.string(), strerror(-err), err);
Zhijun He5d677d12016-05-29 16:52:39 -07001597 } else {
1598 res = STATUS_ERROR_FMT(CameraService::ERROR_INVALID_OPERATION,
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -08001599 "Camera %s: Error setting output stream deferred surface: %s (%d)",
1600 mCameraIdStr.string(), strerror(-err), err);
Zhijun He5d677d12016-05-29 16:52:39 -07001601 }
1602
1603 return res;
1604}
1605
Yin-Chia Yehcfab4e12019-09-09 13:08:28 -07001606binder::Status CameraDeviceClient::setCameraAudioRestriction(int32_t mode) {
Yin-Chia Yehdba03232019-08-19 15:54:28 -07001607 ATRACE_CALL();
1608 binder::Status res;
1609 if (!(res = checkPidStatus(__FUNCTION__)).isOk()) return res;
1610
1611 if (!isValidAudioRestriction(mode)) {
1612 String8 msg = String8::format("Camera %s: invalid audio restriction mode %d",
1613 mCameraIdStr.string(), mode);
1614 ALOGW("%s: %s", __FUNCTION__, msg.string());
1615 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
1616 }
1617
1618 Mutex::Autolock icl(mBinderSerializationLock);
Yin-Chia Yehcfab4e12019-09-09 13:08:28 -07001619 BasicClient::setAudioRestriction(mode);
1620 return binder::Status::ok();
1621}
1622
1623binder::Status CameraDeviceClient::getGlobalAudioRestriction(/*out*/ int32_t* outMode) {
1624 ATRACE_CALL();
1625 binder::Status res;
1626 if (!(res = checkPidStatus(__FUNCTION__)).isOk()) return res;
1627 Mutex::Autolock icl(mBinderSerializationLock);
Yin-Chia Yehdba03232019-08-19 15:54:28 -07001628 if (outMode != nullptr) {
Yin-Chia Yehcfab4e12019-09-09 13:08:28 -07001629 *outMode = BasicClient::getServiceAudioRestriction();
Yin-Chia Yehdba03232019-08-19 15:54:28 -07001630 }
1631 return binder::Status::ok();
1632}
1633
Eino-Ville Talvalaf2e37092020-01-07 15:32:32 -08001634status_t CameraDeviceClient::setRotateAndCropOverride(uint8_t rotateAndCrop) {
1635 if (rotateAndCrop > ANDROID_SCALER_ROTATE_AND_CROP_AUTO) return BAD_VALUE;
1636
1637 return mDevice->setRotateAndCropAutoBehavior(
1638 static_cast<camera_metadata_enum_android_scaler_rotate_and_crop_t>(rotateAndCrop));
1639}
1640
Eino-Ville Talvala305cec62020-11-12 14:18:17 -08001641bool CameraDeviceClient::supportsCameraMute() {
1642 return mDevice->supportsCameraMute();
1643}
1644
1645status_t CameraDeviceClient::setCameraMute(bool enabled) {
1646 return mDevice->setCameraMute(enabled);
1647}
1648
Yin-Chia Yehb978c382019-10-30 00:22:37 -07001649binder::Status CameraDeviceClient::switchToOffline(
1650 const sp<hardware::camera2::ICameraDeviceCallbacks>& cameraCb,
Emilian Peevb2bc5a42019-11-20 16:02:14 -08001651 const std::vector<int>& offlineOutputIds,
Yin-Chia Yehb978c382019-10-30 00:22:37 -07001652 /*out*/
1653 sp<hardware::camera2::ICameraOfflineSession>* session) {
1654 ATRACE_CALL();
1655
1656 binder::Status res;
1657 if (!(res = checkPidStatus(__FUNCTION__)).isOk()) return res;
1658
1659 Mutex::Autolock icl(mBinderSerializationLock);
1660
1661 if (!mDevice.get()) {
1662 return STATUS_ERROR(CameraService::ERROR_DISCONNECTED, "Camera device no longer alive");
1663 }
1664
Emilian Peevb2bc5a42019-11-20 16:02:14 -08001665 if (offlineOutputIds.empty()) {
Emilian Peevcc0b7952020-01-07 13:54:47 -08001666 String8 msg = String8::format("Offline surfaces must not be empty");
Yin-Chia Yehb978c382019-10-30 00:22:37 -07001667 ALOGE("%s: %s", __FUNCTION__, msg.string());
1668 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
1669 }
1670
1671 if (session == nullptr) {
1672 String8 msg = String8::format("Invalid offline session");
1673 ALOGE("%s: %s", __FUNCTION__, msg.string());
1674 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
1675 }
1676
Yin-Chia Yeh87fccca2020-01-28 09:37:18 -08001677 std::vector<int32_t> offlineStreamIds;
1678 offlineStreamIds.reserve(offlineOutputIds.size());
Emilian Peev4697b642019-11-19 17:11:14 -08001679 KeyedVector<sp<IBinder>, sp<CompositeStream>> offlineCompositeStreamMap;
Emilian Peevb2bc5a42019-11-20 16:02:14 -08001680 for (const auto& streamId : offlineOutputIds) {
1681 ssize_t index = mConfiguredOutputs.indexOfKey(streamId);
Yin-Chia Yehb978c382019-10-30 00:22:37 -07001682 if (index == NAME_NOT_FOUND) {
Emilian Peevcc0b7952020-01-07 13:54:47 -08001683 String8 msg = String8::format("Offline surface with id: %d is not registered",
1684 streamId);
Yin-Chia Yehb978c382019-10-30 00:22:37 -07001685 ALOGE("%s: %s", __FUNCTION__, msg.string());
1686 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
1687 }
Emilian Peevcc0b7952020-01-07 13:54:47 -08001688
1689 if (!mStreamInfoMap[streamId].supportsOffline) {
1690 String8 msg = String8::format("Offline surface with id: %d doesn't support "
1691 "offline mode", streamId);
1692 ALOGE("%s: %s", __FUNCTION__, msg.string());
1693 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
1694 }
Yin-Chia Yehb978c382019-10-30 00:22:37 -07001695
Emilian Peevb2bc5a42019-11-20 16:02:14 -08001696 bool isCompositeStream = false;
1697 for (const auto& gbp : mConfiguredOutputs[streamId].getGraphicBufferProducers()) {
1698 sp<Surface> s = new Surface(gbp, false /*controlledByApp*/);
1699 isCompositeStream = camera3::DepthCompositeStream::isDepthCompositeStream(s) |
1700 camera3::HeicCompositeStream::isHeicCompositeStream(s);
Emilian Peev4697b642019-11-19 17:11:14 -08001701 if (isCompositeStream) {
1702 auto compositeIdx = mCompositeStreamMap.indexOfKey(IInterface::asBinder(gbp));
1703 if (compositeIdx == NAME_NOT_FOUND) {
1704 ALOGE("%s: Unknown composite stream", __FUNCTION__);
1705 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT,
1706 "Unknown composite stream");
1707 }
1708
1709 mCompositeStreamMap.valueAt(compositeIdx)->insertCompositeStreamIds(
1710 &offlineStreamIds);
1711 offlineCompositeStreamMap.add(mCompositeStreamMap.keyAt(compositeIdx),
1712 mCompositeStreamMap.valueAt(compositeIdx));
1713 break;
1714 }
Emilian Peevb2bc5a42019-11-20 16:02:14 -08001715 }
1716
Emilian Peev4697b642019-11-19 17:11:14 -08001717 if (!isCompositeStream) {
Emilian Peevb2bc5a42019-11-20 16:02:14 -08001718 offlineStreamIds.push_back(streamId);
Yin-Chia Yehb978c382019-10-30 00:22:37 -07001719 }
1720 }
1721
1722 sp<CameraOfflineSessionBase> offlineSession;
1723 auto ret = mDevice->switchToOffline(offlineStreamIds, &offlineSession);
1724 if (ret != OK) {
1725 return STATUS_ERROR_FMT(CameraService::ERROR_ILLEGAL_ARGUMENT,
1726 "Camera %s: Error switching to offline mode: %s (%d)",
1727 mCameraIdStr.string(), strerror(ret), ret);
1728 }
1729
Emilian Peevcc0b7952020-01-07 13:54:47 -08001730 sp<CameraOfflineSessionClient> offlineClient;
1731 if (offlineSession.get() != nullptr) {
1732 offlineClient = new CameraOfflineSessionClient(sCameraService,
1733 offlineSession, offlineCompositeStreamMap, cameraCb, mClientPackageName,
Emilian Peev8b64f282021-03-25 16:49:57 -07001734 mClientFeatureId, mCameraIdStr, mCameraFacing, mOrientation, mClientPid, mClientUid,
1735 mServicePid);
Emilian Peevcc0b7952020-01-07 13:54:47 -08001736 ret = sCameraService->addOfflineClient(mCameraIdStr, offlineClient);
1737 }
1738
Yin-Chia Yehb978c382019-10-30 00:22:37 -07001739 if (ret == OK) {
Emilian Peevd99c8ae2019-11-26 13:19:13 -08001740 // A successful offline session switch must reset the current camera client
1741 // and release any resources occupied by previously configured streams.
1742 mStreamMap.clear();
1743 mConfiguredOutputs.clear();
1744 mDeferredStreams.clear();
1745 mStreamInfoMap.clear();
1746 mCompositeStreamMap.clear();
1747 mInputStream = {false, 0, 0, 0, 0};
Yin-Chia Yehb978c382019-10-30 00:22:37 -07001748 } else {
Emilian Peevb2bc5a42019-11-20 16:02:14 -08001749 switch(ret) {
1750 case BAD_VALUE:
1751 return STATUS_ERROR_FMT(CameraService::ERROR_ILLEGAL_ARGUMENT,
1752 "Illegal argument to HAL module for camera \"%s\"", mCameraIdStr.c_str());
1753 case TIMED_OUT:
1754 return STATUS_ERROR_FMT(CameraService::ERROR_CAMERA_IN_USE,
1755 "Camera \"%s\" is already open", mCameraIdStr.c_str());
1756 default:
1757 return STATUS_ERROR_FMT(CameraService::ERROR_INVALID_OPERATION,
1758 "Failed to initialize camera \"%s\": %s (%d)", mCameraIdStr.c_str(),
1759 strerror(-ret), ret);
1760 }
Yin-Chia Yehb978c382019-10-30 00:22:37 -07001761 }
1762
1763 *session = offlineClient;
1764
1765 return binder::Status::ok();
1766}
1767
Igor Murashkine7ee7632013-06-11 18:10:18 -07001768status_t CameraDeviceClient::dump(int fd, const Vector<String16>& args) {
Eino-Ville Talvalac4003962016-01-13 10:07:04 -08001769 return BasicClient::dump(fd, args);
1770}
1771
1772status_t CameraDeviceClient::dumpClient(int fd, const Vector<String16>& args) {
Eino-Ville Talvalad00111e2017-01-31 11:59:12 -08001773 dprintf(fd, " CameraDeviceClient[%s] (%p) dump:\n",
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -08001774 mCameraIdStr.string(),
Eino-Ville Talvalae992e752014-11-07 16:17:48 -08001775 (getRemoteCallback() != NULL ?
Marco Nelissenf8880202014-11-14 07:58:25 -08001776 IInterface::asBinder(getRemoteCallback()).get() : NULL) );
Eino-Ville Talvalad00111e2017-01-31 11:59:12 -08001777 dprintf(fd, " Current client UID %u\n", mClientUid);
Igor Murashkine7ee7632013-06-11 18:10:18 -07001778
Eino-Ville Talvalad00111e2017-01-31 11:59:12 -08001779 dprintf(fd, " State:\n");
1780 dprintf(fd, " Request ID counter: %d\n", mRequestIdCounter);
Chien-Yu Chen618ff8a2015-03-13 11:27:17 -07001781 if (mInputStream.configured) {
Eino-Ville Talvalad00111e2017-01-31 11:59:12 -08001782 dprintf(fd, " Current input stream ID: %d\n", mInputStream.id);
Chien-Yu Chen618ff8a2015-03-13 11:27:17 -07001783 } else {
Eino-Ville Talvalad00111e2017-01-31 11:59:12 -08001784 dprintf(fd, " No input stream configured.\n");
Chien-Yu Chen618ff8a2015-03-13 11:27:17 -07001785 }
Eino-Ville Talvala67489d22014-09-18 15:52:02 -07001786 if (!mStreamMap.isEmpty()) {
Eino-Ville Talvalad00111e2017-01-31 11:59:12 -08001787 dprintf(fd, " Current output stream/surface IDs:\n");
Eino-Ville Talvala67489d22014-09-18 15:52:02 -07001788 for (size_t i = 0; i < mStreamMap.size(); i++) {
Eino-Ville Talvalad00111e2017-01-31 11:59:12 -08001789 dprintf(fd, " Stream %d Surface %d\n",
Shuzhen Wang0129d522016-10-30 22:43:41 -07001790 mStreamMap.valueAt(i).streamId(),
1791 mStreamMap.valueAt(i).surfaceId());
Eino-Ville Talvala67489d22014-09-18 15:52:02 -07001792 }
Zhijun He5d677d12016-05-29 16:52:39 -07001793 } else if (!mDeferredStreams.isEmpty()) {
Eino-Ville Talvalad00111e2017-01-31 11:59:12 -08001794 dprintf(fd, " Current deferred surface output stream IDs:\n");
Zhijun He5d677d12016-05-29 16:52:39 -07001795 for (auto& streamId : mDeferredStreams) {
Eino-Ville Talvalad00111e2017-01-31 11:59:12 -08001796 dprintf(fd, " Stream %d\n", streamId);
Zhijun He5d677d12016-05-29 16:52:39 -07001797 }
Eino-Ville Talvala67489d22014-09-18 15:52:02 -07001798 } else {
Eino-Ville Talvalad00111e2017-01-31 11:59:12 -08001799 dprintf(fd, " No output streams configured.\n");
Eino-Ville Talvala67489d22014-09-18 15:52:02 -07001800 }
Igor Murashkine7ee7632013-06-11 18:10:18 -07001801 // TODO: print dynamic/request section from most recent requests
1802 mFrameProcessor->dump(fd, args);
1803
1804 return dumpDevice(fd, args);
1805}
1806
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001807void CameraDeviceClient::notifyError(int32_t errorCode,
Jianing Weicb0652e2014-03-12 18:29:36 -07001808 const CaptureResultExtras& resultExtras) {
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07001809 // Thread safe. Don't bother locking.
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001810 sp<hardware::camera2::ICameraDeviceCallbacks> remoteCb = getRemoteCallback();
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07001811
Emilian Peev538c90e2018-12-17 18:03:19 +00001812 // Composites can have multiple internal streams. Error notifications coming from such internal
1813 // streams may need to remain within camera service.
1814 bool skipClientNotification = false;
1815 for (size_t i = 0; i < mCompositeStreamMap.size(); i++) {
1816 skipClientNotification |= mCompositeStreamMap.valueAt(i)->onError(errorCode, resultExtras);
1817 }
1818
1819 if ((remoteCb != 0) && (!skipClientNotification)) {
Jianing Weicb0652e2014-03-12 18:29:36 -07001820 remoteCb->onDeviceError(errorCode, resultExtras);
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07001821 }
1822}
1823
Chien-Yu Chene8c535e2016-04-14 12:18:26 -07001824void CameraDeviceClient::notifyRepeatingRequestError(long lastFrameNumber) {
1825 sp<hardware::camera2::ICameraDeviceCallbacks> remoteCb = getRemoteCallback();
1826
1827 if (remoteCb != 0) {
Yin-Chia Yeh8ca23dc2017-09-05 18:15:56 -07001828 remoteCb->onRepeatingRequestError(lastFrameNumber, mStreamingRequestId);
Chien-Yu Chene8c535e2016-04-14 12:18:26 -07001829 }
1830
Shuzhen Wangc9ca6782016-04-26 13:40:31 -07001831 Mutex::Autolock idLock(mStreamingRequestIdLock);
Chien-Yu Chene8c535e2016-04-14 12:18:26 -07001832 mStreamingRequestId = REQUEST_ID_NONE;
1833}
1834
Shuzhen Wang316781a2020-08-18 18:11:01 -07001835void CameraDeviceClient::notifyIdle(
1836 int64_t requestCount, int64_t resultErrorCount, bool deviceError,
1837 const std::vector<hardware::CameraStreamStats>& streamStats) {
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07001838 // Thread safe. Don't bother locking.
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001839 sp<hardware::camera2::ICameraDeviceCallbacks> remoteCb = getRemoteCallback();
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07001840
1841 if (remoteCb != 0) {
1842 remoteCb->onDeviceIdle();
1843 }
Shuzhen Wang316781a2020-08-18 18:11:01 -07001844 Camera2ClientBase::notifyIdle(requestCount, resultErrorCount, deviceError, streamStats);
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07001845}
1846
Jianing Weicb0652e2014-03-12 18:29:36 -07001847void CameraDeviceClient::notifyShutter(const CaptureResultExtras& resultExtras,
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07001848 nsecs_t timestamp) {
1849 // Thread safe. Don't bother locking.
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001850 sp<hardware::camera2::ICameraDeviceCallbacks> remoteCb = getRemoteCallback();
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07001851 if (remoteCb != 0) {
Jianing Weicb0652e2014-03-12 18:29:36 -07001852 remoteCb->onCaptureStarted(resultExtras, timestamp);
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07001853 }
Eino-Ville Talvala412fe562015-08-20 17:08:32 -07001854 Camera2ClientBase::notifyShutter(resultExtras, timestamp);
Shuzhen Wang68ac7ad2019-01-30 14:03:28 -08001855
1856 for (size_t i = 0; i < mCompositeStreamMap.size(); i++) {
1857 mCompositeStreamMap.valueAt(i)->onShutter(resultExtras, timestamp);
1858 }
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07001859}
1860
Eino-Ville Talvala4d44cad2015-04-11 13:15:45 -07001861void CameraDeviceClient::notifyPrepared(int streamId) {
1862 // Thread safe. Don't bother locking.
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001863 sp<hardware::camera2::ICameraDeviceCallbacks> remoteCb = getRemoteCallback();
Eino-Ville Talvala4d44cad2015-04-11 13:15:45 -07001864 if (remoteCb != 0) {
1865 remoteCb->onPrepared(streamId);
1866 }
1867}
1868
Shuzhen Wang9d066012016-09-30 11:30:20 -07001869void CameraDeviceClient::notifyRequestQueueEmpty() {
1870 // Thread safe. Don't bother locking.
1871 sp<hardware::camera2::ICameraDeviceCallbacks> remoteCb = getRemoteCallback();
1872 if (remoteCb != 0) {
1873 remoteCb->onRequestQueueEmpty();
1874 }
1875}
1876
Igor Murashkine7ee7632013-06-11 18:10:18 -07001877void CameraDeviceClient::detachDevice() {
1878 if (mDevice == 0) return;
1879
Shuzhen Wang316781a2020-08-18 18:11:01 -07001880 nsecs_t startTime = systemTime();
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -08001881 ALOGV("Camera %s: Stopping processors", mCameraIdStr.string());
Igor Murashkine7ee7632013-06-11 18:10:18 -07001882
Emilian Peevfaa4bde2020-01-23 12:19:37 -08001883 mFrameProcessor->removeListener(camera2::FrameProcessorBase::FRAME_PROCESSOR_LISTENER_MIN_ID,
1884 camera2::FrameProcessorBase::FRAME_PROCESSOR_LISTENER_MAX_ID,
Igor Murashkine7ee7632013-06-11 18:10:18 -07001885 /*listener*/this);
1886 mFrameProcessor->requestExit();
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -08001887 ALOGV("Camera %s: Waiting for threads", mCameraIdStr.string());
Igor Murashkine7ee7632013-06-11 18:10:18 -07001888 mFrameProcessor->join();
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -08001889 ALOGV("Camera %s: Disconnecting device", mCameraIdStr.string());
Igor Murashkine7ee7632013-06-11 18:10:18 -07001890
1891 // WORKAROUND: HAL refuses to disconnect while there's streams in flight
1892 {
Emilian Peev6b51d7d2018-07-23 11:41:44 +01001893 int64_t lastFrameNumber;
Igor Murashkine7ee7632013-06-11 18:10:18 -07001894 status_t code;
Emilian Peev6b51d7d2018-07-23 11:41:44 +01001895 if ((code = mDevice->flush(&lastFrameNumber)) != OK) {
1896 ALOGE("%s: flush failed with code 0x%x", __FUNCTION__, code);
1897 }
1898
Igor Murashkine7ee7632013-06-11 18:10:18 -07001899 if ((code = mDevice->waitUntilDrained()) != OK) {
1900 ALOGE("%s: waitUntilDrained failed with code 0x%x", __FUNCTION__,
1901 code);
1902 }
1903 }
1904
Emilian Peev5e4c7322019-10-22 14:20:52 -07001905 for (size_t i = 0; i < mCompositeStreamMap.size(); i++) {
1906 auto ret = mCompositeStreamMap.valueAt(i)->deleteInternalStreams();
1907 if (ret != OK) {
1908 ALOGE("%s: Failed removing composite stream %s (%d)", __FUNCTION__,
1909 strerror(-ret), ret);
1910 }
1911 }
1912 mCompositeStreamMap.clear();
1913
Igor Murashkine7ee7632013-06-11 18:10:18 -07001914 Camera2ClientBase::detachDevice();
Shuzhen Wang316781a2020-08-18 18:11:01 -07001915
1916 int32_t closeLatencyMs = ns2ms(systemTime() - startTime);
1917 CameraServiceProxyWrapper::logClose(mCameraIdStr, closeLatencyMs);
Igor Murashkine7ee7632013-06-11 18:10:18 -07001918}
1919
1920/** Device-related methods */
Jianing Weicb0652e2014-03-12 18:29:36 -07001921void CameraDeviceClient::onResultAvailable(const CaptureResult& result) {
Igor Murashkine7ee7632013-06-11 18:10:18 -07001922 ATRACE_CALL();
1923 ALOGV("%s", __FUNCTION__);
1924
Igor Murashkin4fb55c12013-08-29 17:43:01 -07001925 // Thread-safe. No lock necessary.
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001926 sp<hardware::camera2::ICameraDeviceCallbacks> remoteCb = mRemoteCallback;
Igor Murashkin4fb55c12013-08-29 17:43:01 -07001927 if (remoteCb != NULL) {
Shuzhen Wang5c22c152017-12-31 17:12:25 -08001928 remoteCb->onResultReceived(result.mMetadata, result.mResultExtras,
1929 result.mPhysicalMetadatas);
Igor Murashkine7ee7632013-06-11 18:10:18 -07001930 }
Emilian Peev538c90e2018-12-17 18:03:19 +00001931
1932 for (size_t i = 0; i < mCompositeStreamMap.size(); i++) {
1933 mCompositeStreamMap.valueAt(i)->onResultAvailable(result);
1934 }
Igor Murashkine7ee7632013-06-11 18:10:18 -07001935}
1936
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001937binder::Status CameraDeviceClient::checkPidStatus(const char* checkLocation) {
Eino-Ville Talvala6192b892016-04-04 12:31:18 -07001938 if (mDisconnected) {
1939 return STATUS_ERROR(CameraService::ERROR_DISCONNECTED,
1940 "The camera device has been disconnected");
1941 }
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001942 status_t res = checkPid(checkLocation);
1943 return (res == OK) ? binder::Status::ok() :
1944 STATUS_ERROR(CameraService::ERROR_PERMISSION_DENIED,
1945 "Attempt to use camera from a different process than original client");
1946}
1947
Igor Murashkine7ee7632013-06-11 18:10:18 -07001948// TODO: move to Camera2ClientBase
1949bool CameraDeviceClient::enforceRequestPermissions(CameraMetadata& metadata) {
1950
Jayant Chowdhary12361932018-08-27 14:46:13 -07001951 const int pid = CameraThreadState::getCallingPid();
Igor Murashkine7ee7632013-06-11 18:10:18 -07001952 const int selfPid = getpid();
1953 camera_metadata_entry_t entry;
1954
1955 /**
1956 * Mixin default important security values
1957 * - android.led.transmit = defaulted ON
1958 */
1959 CameraMetadata staticInfo = mDevice->info();
1960 entry = staticInfo.find(ANDROID_LED_AVAILABLE_LEDS);
1961 for(size_t i = 0; i < entry.count; ++i) {
1962 uint8_t led = entry.data.u8[i];
1963
1964 switch(led) {
1965 case ANDROID_LED_AVAILABLE_LEDS_TRANSMIT: {
1966 uint8_t transmitDefault = ANDROID_LED_TRANSMIT_ON;
1967 if (!metadata.exists(ANDROID_LED_TRANSMIT)) {
1968 metadata.update(ANDROID_LED_TRANSMIT,
1969 &transmitDefault, 1);
1970 }
1971 break;
1972 }
1973 }
1974 }
1975
1976 // We can do anything!
1977 if (pid == selfPid) {
1978 return true;
1979 }
1980
1981 /**
1982 * Permission check special fields in the request
1983 * - android.led.transmit = android.permission.CAMERA_DISABLE_TRANSMIT
1984 */
1985 entry = metadata.find(ANDROID_LED_TRANSMIT);
1986 if (entry.count > 0 && entry.data.u8[0] != ANDROID_LED_TRANSMIT_ON) {
1987 String16 permissionString =
1988 String16("android.permission.CAMERA_DISABLE_TRANSMIT_LED");
1989 if (!checkCallingPermission(permissionString)) {
Jayant Chowdhary12361932018-08-27 14:46:13 -07001990 const int uid = CameraThreadState::getCallingUid();
Igor Murashkine7ee7632013-06-11 18:10:18 -07001991 ALOGE("Permission Denial: "
1992 "can't disable transmit LED pid=%d, uid=%d", pid, uid);
1993 return false;
1994 }
1995 }
1996
1997 return true;
1998}
1999
Igor Murashkinf8b2a6f2013-09-17 17:03:28 -07002000status_t CameraDeviceClient::getRotationTransformLocked(int32_t* transform) {
2001 ALOGV("%s: begin", __FUNCTION__);
2002
Igor Murashkinf8b2a6f2013-09-17 17:03:28 -07002003 const CameraMetadata& staticInfo = mDevice->info();
Ruben Brunk5698d442014-06-18 10:39:40 -07002004 return CameraUtils::getRotationTransform(staticInfo, transform);
Igor Murashkinf8b2a6f2013-09-17 17:03:28 -07002005}
2006
Emilian Peevf4816702020-04-03 15:44:51 -07002007binder::Status CameraDeviceClient::mapRequestTemplate(int templateId,
2008 camera_request_template_t* tempId /*out*/) {
2009 binder::Status ret = binder::Status::ok();
2010
2011 if (tempId == nullptr) {
2012 ret = STATUS_ERROR_FMT(CameraService::ERROR_ILLEGAL_ARGUMENT,
2013 "Camera %s: Invalid template argument", mCameraIdStr.string());
2014 return ret;
2015 }
2016 switch(templateId) {
2017 case ICameraDeviceUser::TEMPLATE_PREVIEW:
2018 *tempId = camera_request_template_t::CAMERA_TEMPLATE_PREVIEW;
2019 break;
2020 case ICameraDeviceUser::TEMPLATE_RECORD:
2021 *tempId = camera_request_template_t::CAMERA_TEMPLATE_VIDEO_RECORD;
2022 break;
2023 case ICameraDeviceUser::TEMPLATE_STILL_CAPTURE:
2024 *tempId = camera_request_template_t::CAMERA_TEMPLATE_STILL_CAPTURE;
2025 break;
2026 case ICameraDeviceUser::TEMPLATE_VIDEO_SNAPSHOT:
2027 *tempId = camera_request_template_t::CAMERA_TEMPLATE_VIDEO_SNAPSHOT;
2028 break;
2029 case ICameraDeviceUser::TEMPLATE_ZERO_SHUTTER_LAG:
2030 *tempId = camera_request_template_t::CAMERA_TEMPLATE_ZERO_SHUTTER_LAG;
2031 break;
2032 case ICameraDeviceUser::TEMPLATE_MANUAL:
2033 *tempId = camera_request_template_t::CAMERA_TEMPLATE_MANUAL;
2034 break;
2035 default:
2036 ret = STATUS_ERROR_FMT(CameraService::ERROR_ILLEGAL_ARGUMENT,
2037 "Camera %s: Template ID %d is invalid or not supported",
2038 mCameraIdStr.string(), templateId);
2039 return ret;
2040 }
2041
2042 return ret;
2043}
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -08002044
2045const CameraMetadata &CameraDeviceClient::getStaticInfo(const String8 &cameraId) {
2046 if (mDevice->getId() == cameraId) {
2047 return mDevice->info();
2048 }
2049 return mDevice->infoPhysical(cameraId);
2050}
2051
2052bool CameraDeviceClient::isUltraHighResolutionSensor(const String8 &cameraId) {
2053 const CameraMetadata &deviceInfo = getStaticInfo(cameraId);
Shuzhen Wangd4abdf72021-05-28 11:22:50 -07002054 return SessionConfigurationUtils::isUltraHighResolutionSensor(deviceInfo);
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -08002055}
2056
2057bool CameraDeviceClient::isSensorPixelModeConsistent(
2058 const std::list<int> &streamIdList, const CameraMetadata &settings) {
2059 // First we get the sensorPixelMode from the settings metadata.
2060 int32_t sensorPixelMode = ANDROID_SENSOR_PIXEL_MODE_DEFAULT;
2061 camera_metadata_ro_entry sensorPixelModeEntry = settings.find(ANDROID_SENSOR_PIXEL_MODE);
2062 if (sensorPixelModeEntry.count != 0) {
2063 sensorPixelMode = sensorPixelModeEntry.data.u8[0];
2064 if (sensorPixelMode != ANDROID_SENSOR_PIXEL_MODE_DEFAULT &&
2065 sensorPixelMode != ANDROID_SENSOR_PIXEL_MODE_MAXIMUM_RESOLUTION) {
2066 ALOGE("%s: Request sensor pixel mode not is not one of the valid values %d",
2067 __FUNCTION__, sensorPixelMode);
2068 return false;
2069 }
2070 }
2071 // Check whether each stream has max resolution allowed.
2072 bool consistent = true;
2073 for (auto it : streamIdList) {
2074 auto const streamInfoIt = mStreamInfoMap.find(it);
2075 if (streamInfoIt == mStreamInfoMap.end()) {
2076 ALOGE("%s: stream id %d not created, skipping", __FUNCTION__, it);
2077 return false;
2078 }
2079 consistent =
2080 streamInfoIt->second.sensorPixelModesUsed.find(sensorPixelMode) !=
2081 streamInfoIt->second.sensorPixelModesUsed.end();
2082 if (!consistent) {
2083 ALOGE("sensorPixelMode used %i not consistent with configured modes", sensorPixelMode);
2084 for (auto m : streamInfoIt->second.sensorPixelModesUsed) {
2085 ALOGE("sensor pixel mode used list: %i", m);
2086 }
2087 break;
2088 }
2089 }
2090
2091 return consistent;
2092}
2093
Igor Murashkine7ee7632013-06-11 18:10:18 -07002094} // namespace android