blob: ba26ac4fe50b4cef4ea86b8fbf4fdc709bf7578b [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"
34
Emilian Peev00420d22018-02-05 21:33:13 +000035#include <camera_metadata_hidden.h>
36
Emilian Peev538c90e2018-12-17 18:03:19 +000037#include "DepthCompositeStream.h"
Shuzhen Wang68ac7ad2019-01-30 14:03:28 -080038#include "HeicCompositeStream.h"
Emilian Peev538c90e2018-12-17 18:03:19 +000039
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -080040// Convenience methods for constructing binder::Status objects for error returns
Eino-Ville Talvala7b82efe2013-07-25 17:12:35 -070041
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -080042#define STATUS_ERROR(errorCode, errorString) \
43 binder::Status::fromServiceSpecificError(errorCode, \
Eino-Ville Talvala02bf0322016-02-18 12:41:10 -080044 String8::format("%s:%d: %s", __FUNCTION__, __LINE__, errorString))
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -080045
46#define STATUS_ERROR_FMT(errorCode, errorString, ...) \
47 binder::Status::fromServiceSpecificError(errorCode, \
Eino-Ville Talvala02bf0322016-02-18 12:41:10 -080048 String8::format("%s:%d: " errorString, __FUNCTION__, __LINE__, \
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -080049 __VA_ARGS__))
Igor Murashkine7ee7632013-06-11 18:10:18 -070050
51namespace android {
52using namespace camera2;
Austin Borgerea931242021-12-13 23:10:41 +000053using namespace camera3;
Emilian Peevf4816702020-04-03 15:44:51 -070054using camera3::camera_stream_rotation_t::CAMERA_STREAM_ROTATION_0;
Igor Murashkine7ee7632013-06-11 18:10:18 -070055
56CameraDeviceClientBase::CameraDeviceClientBase(
57 const sp<CameraService>& cameraService,
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -080058 const sp<hardware::camera2::ICameraDeviceCallbacks>& remoteCallback,
Igor Murashkine7ee7632013-06-11 18:10:18 -070059 const String16& clientPackageName,
Jayant Chowdharyeb0169f2022-01-31 00:00:02 -080060 bool systemNativeClient,
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,
Jayant Chowdharyeb0169f2022-01-31 00:00:02 -080072 systemNativeClient,
Philip P. Moltmann9e648f62019-11-04 12:52:45 -080073 clientFeatureId,
Eino-Ville Talvalae992e752014-11-07 16:17:48 -080074 cameraId,
75 cameraFacing,
Emilian Peev8b64f282021-03-25 16:49:57 -070076 sensorOrientation,
Eino-Ville Talvalae992e752014-11-07 16:17:48 -080077 clientPid,
78 clientUid,
79 servicePid),
Igor Murashkine7ee7632013-06-11 18:10:18 -070080 mRemoteCallback(remoteCallback) {
Yin-Chia Yehc3e9d6f2018-02-06 10:56:32 -080081 // We don't need it for API2 clients, but Camera2ClientBase requires it.
82 (void) api1CameraId;
Igor Murashkine7ee7632013-06-11 18:10:18 -070083}
Igor Murashkine7ee7632013-06-11 18:10:18 -070084
85// Interface used by CameraService
86
87CameraDeviceClient::CameraDeviceClient(const sp<CameraService>& cameraService,
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -080088 const sp<hardware::camera2::ICameraDeviceCallbacks>& remoteCallback,
Austin Borger74fca042022-05-23 12:41:21 -070089 std::shared_ptr<CameraServiceProxyWrapper> cameraServiceProxyWrapper,
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -080090 const String16& clientPackageName,
Jayant Chowdharyeb0169f2022-01-31 00:00:02 -080091 bool systemNativeClient,
Jooyung Han3f9a3b42020-01-23 12:27:18 +090092 const std::optional<String16>& clientFeatureId,
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -080093 const String8& cameraId,
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -080094 int cameraFacing,
Emilian Peev8b64f282021-03-25 16:49:57 -070095 int sensorOrientation,
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -080096 int clientPid,
97 uid_t clientUid,
Shuzhen Wangd4abdf72021-05-28 11:22:50 -070098 int servicePid,
99 bool overrideForPerfClass) :
Austin Borger74fca042022-05-23 12:41:21 -0700100 Camera2ClientBase(cameraService, remoteCallback, cameraServiceProxyWrapper, clientPackageName,
101 systemNativeClient, clientFeatureId, cameraId, /*API1 camera ID*/ -1, cameraFacing,
102 sensorOrientation, clientPid, clientUid, servicePid, overrideForPerfClass),
Chien-Yu Chen618ff8a2015-03-13 11:27:17 -0700103 mInputStream(),
Chien-Yu Chene8c535e2016-04-14 12:18:26 -0700104 mStreamingRequestId(REQUEST_ID_NONE),
Shuzhen Wangd4abdf72021-05-28 11:22:50 -0700105 mRequestIdCounter(0),
106 mOverrideForPerfClass(overrideForPerfClass) {
Igor Murashkine7ee7632013-06-11 18:10:18 -0700107
108 ATRACE_CALL();
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800109 ALOGI("CameraDeviceClient %s: Opened", cameraId.string());
Igor Murashkine7ee7632013-06-11 18:10:18 -0700110}
111
Emilian Peevbd8c5032018-02-14 23:05:40 +0000112status_t CameraDeviceClient::initialize(sp<CameraProviderManager> manager,
113 const String8& monitorTags) {
114 return initializeImpl(manager, monitorTags);
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800115}
116
117template<typename TProviderPtr>
Emilian Peevbd8c5032018-02-14 23:05:40 +0000118status_t CameraDeviceClient::initializeImpl(TProviderPtr providerPtr, const String8& monitorTags) {
Igor Murashkine7ee7632013-06-11 18:10:18 -0700119 ATRACE_CALL();
120 status_t res;
121
Emilian Peevbd8c5032018-02-14 23:05:40 +0000122 res = Camera2ClientBase::initialize(providerPtr, monitorTags);
Igor Murashkine7ee7632013-06-11 18:10:18 -0700123 if (res != OK) {
124 return res;
125 }
126
127 String8 threadName;
Eino-Ville Talvala7b82efe2013-07-25 17:12:35 -0700128 mFrameProcessor = new FrameProcessorBase(mDevice);
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800129 threadName = String8::format("CDU-%s-FrameProc", mCameraIdStr.string());
Austin Borger7b129542022-06-09 13:23:06 -0700130 res = mFrameProcessor->run(threadName.string());
131 if (res != OK) {
132 ALOGE("%s: Unable to start frame processor thread: %s (%d)",
133 __FUNCTION__, strerror(-res), res);
134 return res;
135 }
Igor Murashkine7ee7632013-06-11 18:10:18 -0700136
Emilian Peevfaa4bde2020-01-23 12:19:37 -0800137 mFrameProcessor->registerListener(camera2::FrameProcessorBase::FRAME_PROCESSOR_LISTENER_MIN_ID,
138 camera2::FrameProcessorBase::FRAME_PROCESSOR_LISTENER_MAX_ID,
Eino-Ville Talvala184dfe42013-11-07 15:13:16 -0800139 /*listener*/this,
Zhijun He25a0aef2014-06-25 11:40:02 -0700140 /*sendPartials*/true);
Igor Murashkine7ee7632013-06-11 18:10:18 -0700141
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800142 const CameraMetadata &deviceInfo = mDevice->info();
143 camera_metadata_ro_entry_t physicalKeysEntry = deviceInfo.find(
Emilian Peev00420d22018-02-05 21:33:13 +0000144 ANDROID_REQUEST_AVAILABLE_PHYSICAL_CAMERA_REQUEST_KEYS);
145 if (physicalKeysEntry.count > 0) {
146 mSupportedPhysicalRequestKeys.insert(mSupportedPhysicalRequestKeys.begin(),
147 physicalKeysEntry.data.i32,
148 physicalKeysEntry.data.i32 + physicalKeysEntry.count);
149 }
150
Emilian Peev2295df72021-11-12 18:14:10 -0800151 auto entry = deviceInfo.find(ANDROID_REQUEST_AVAILABLE_CAPABILITIES);
152 mDynamicProfileMap.emplace(
153 ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD,
154 ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD);
155 if (entry.count > 0) {
Shuzhen Wangc8ab4522021-12-14 20:12:42 -0800156 const auto it = std::find(entry.data.u8, entry.data.u8 + entry.count,
Emilian Peev2295df72021-11-12 18:14:10 -0800157 ANDROID_REQUEST_AVAILABLE_CAPABILITIES_DYNAMIC_RANGE_TEN_BIT);
Shuzhen Wangc8ab4522021-12-14 20:12:42 -0800158 if (it != entry.data.u8 + entry.count) {
Emilian Peev2295df72021-11-12 18:14:10 -0800159 entry = deviceInfo.find(ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP);
Emilian Peevc81a7592022-02-14 17:38:18 -0800160 if (entry.count > 0 || ((entry.count % 3) != 0)) {
161 int64_t standardBitmap =
162 ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD;
163 for (size_t i = 0; i < entry.count; i += 3) {
164 if (entry.data.i64[i] !=
Emilian Peev2295df72021-11-12 18:14:10 -0800165 ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD) {
Emilian Peevc81a7592022-02-14 17:38:18 -0800166 mDynamicProfileMap.emplace(entry.data.i64[i], entry.data.i64[i+1]);
167 if ((entry.data.i64[i+1] == 0) || (entry.data.i64[i+1] &
Emilian Peev2295df72021-11-12 18:14:10 -0800168 ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD)) {
Emilian Peevc81a7592022-02-14 17:38:18 -0800169 standardBitmap |= entry.data.i64[i];
Emilian Peev2295df72021-11-12 18:14:10 -0800170 }
171 } else {
Emilian Peevc81a7592022-02-14 17:38:18 -0800172 ALOGE("%s: Device %s includes unexpected profile entry: 0x%" PRIx64 "!",
173 __FUNCTION__, mCameraIdStr.c_str(), entry.data.i64[i]);
Emilian Peev2295df72021-11-12 18:14:10 -0800174 }
175 }
Emilian Peevef715e22022-05-19 17:44:33 -0700176 mDynamicProfileMap[ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD] =
177 standardBitmap;
Emilian Peev2295df72021-11-12 18:14:10 -0800178 } else {
179 ALOGE("%s: Device %s supports 10-bit output but doesn't include a dynamic range"
180 " profile map!", __FUNCTION__, mCameraIdStr.c_str());
181 }
182 }
183 }
184
Shuzhen Wang03d8cc12018-09-12 14:17:09 -0700185 mProviderManager = providerPtr;
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800186 // Cache physical camera ids corresponding to this device and also the high
187 // resolution sensors in this device + physical camera ids
188 mProviderManager->isLogicalCamera(mCameraIdStr.string(), &mPhysicalCameraIds);
189 if (isUltraHighResolutionSensor(mCameraIdStr)) {
190 mHighResolutionSensors.insert(mCameraIdStr.string());
191 }
192 for (auto &physicalId : mPhysicalCameraIds) {
193 if (isUltraHighResolutionSensor(String8(physicalId.c_str()))) {
194 mHighResolutionSensors.insert(physicalId.c_str());
195 }
196 }
Igor Murashkine7ee7632013-06-11 18:10:18 -0700197 return OK;
198}
199
200CameraDeviceClient::~CameraDeviceClient() {
201}
202
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800203binder::Status CameraDeviceClient::submitRequest(
204 const hardware::camera2::CaptureRequest& request,
205 bool streaming,
206 /*out*/
207 hardware::camera2::utils::SubmitInfo *submitInfo) {
208 std::vector<hardware::camera2::CaptureRequest> requestList = { request };
209 return submitRequestList(requestList, streaming, submitInfo);
Igor Murashkine7ee7632013-06-11 18:10:18 -0700210}
211
Yin-Chia Yeh4dfa4cc2017-11-10 20:00:09 -0800212binder::Status CameraDeviceClient::insertGbpLocked(const sp<IGraphicBufferProducer>& gbp,
Emilian Peevf873aa52018-01-26 14:58:28 +0000213 SurfaceMap* outSurfaceMap, Vector<int32_t>* outputStreamIds, int32_t *currentStreamId) {
Emilian Peev538c90e2018-12-17 18:03:19 +0000214 int compositeIdx;
Yin-Chia Yeh4dfa4cc2017-11-10 20:00:09 -0800215 int idx = mStreamMap.indexOfKey(IInterface::asBinder(gbp));
216
Emilian Peev2f5d6012022-01-19 16:16:50 -0800217 Mutex::Autolock l(mCompositeLock);
Yin-Chia Yeh4dfa4cc2017-11-10 20:00:09 -0800218 // Trying to submit request with surface that wasn't created
219 if (idx == NAME_NOT_FOUND) {
220 ALOGE("%s: Camera %s: Tried to submit a request with a surface that"
221 " we have not called createStream on",
222 __FUNCTION__, mCameraIdStr.string());
223 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT,
224 "Request targets Surface that is not part of current capture session");
Emilian Peev538c90e2018-12-17 18:03:19 +0000225 } else if ((compositeIdx = mCompositeStreamMap.indexOfKey(IInterface::asBinder(gbp)))
226 != NAME_NOT_FOUND) {
227 mCompositeStreamMap.valueAt(compositeIdx)->insertGbp(outSurfaceMap, outputStreamIds,
228 currentStreamId);
229 return binder::Status::ok();
Yin-Chia Yeh4dfa4cc2017-11-10 20:00:09 -0800230 }
231
232 const StreamSurfaceId& streamSurfaceId = mStreamMap.valueAt(idx);
233 if (outSurfaceMap->find(streamSurfaceId.streamId()) == outSurfaceMap->end()) {
Yin-Chia Yeh4dfa4cc2017-11-10 20:00:09 -0800234 outputStreamIds->push_back(streamSurfaceId.streamId());
235 }
236 (*outSurfaceMap)[streamSurfaceId.streamId()].push_back(streamSurfaceId.surfaceId());
237
238 ALOGV("%s: Camera %s: Appending output stream %d surface %d to request",
239 __FUNCTION__, mCameraIdStr.string(), streamSurfaceId.streamId(),
240 streamSurfaceId.surfaceId());
241
Emilian Peevf873aa52018-01-26 14:58:28 +0000242 if (currentStreamId != nullptr) {
243 *currentStreamId = streamSurfaceId.streamId();
244 }
245
Yin-Chia Yeh4dfa4cc2017-11-10 20:00:09 -0800246 return binder::Status::ok();
247}
248
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800249static std::list<int> getIntersection(const std::unordered_set<int> &streamIdsForThisCamera,
250 const Vector<int> &streamIdsForThisRequest) {
251 std::list<int> intersection;
252 for (auto &streamId : streamIdsForThisRequest) {
253 if (streamIdsForThisCamera.find(streamId) != streamIdsForThisCamera.end()) {
254 intersection.emplace_back(streamId);
255 }
256 }
257 return intersection;
258}
259
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800260binder::Status CameraDeviceClient::submitRequestList(
261 const std::vector<hardware::camera2::CaptureRequest>& requests,
262 bool streaming,
263 /*out*/
264 hardware::camera2::utils::SubmitInfo *submitInfo) {
Jianing Wei90e59c92014-03-12 18:29:36 -0700265 ATRACE_CALL();
Mark Salyzyn50468412014-06-18 16:33:43 -0700266 ALOGV("%s-start of function. Request list size %zu", __FUNCTION__, requests.size());
Jianing Wei90e59c92014-03-12 18:29:36 -0700267
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800268 binder::Status res = binder::Status::ok();
269 status_t err;
270 if ( !(res = checkPidStatus(__FUNCTION__) ).isOk()) {
271 return res;
272 }
Jianing Wei90e59c92014-03-12 18:29:36 -0700273
274 Mutex::Autolock icl(mBinderSerializationLock);
275
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800276 if (!mDevice.get()) {
277 return STATUS_ERROR(CameraService::ERROR_DISCONNECTED, "Camera device no longer alive");
278 }
Jianing Wei90e59c92014-03-12 18:29:36 -0700279
280 if (requests.empty()) {
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800281 ALOGE("%s: Camera %s: Sent null request. Rejecting request.",
282 __FUNCTION__, mCameraIdStr.string());
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800283 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, "Empty request list");
Jianing Wei90e59c92014-03-12 18:29:36 -0700284 }
285
Emilian Peevaebbe412018-01-15 13:53:24 +0000286 List<const CameraDeviceBase::PhysicalCameraSettingsList> metadataRequestList;
Shuzhen Wang0129d522016-10-30 22:43:41 -0700287 std::list<const SurfaceMap> surfaceMapList;
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800288 submitInfo->mRequestId = mRequestIdCounter;
Jianing Wei90e59c92014-03-12 18:29:36 -0700289 uint32_t loopCounter = 0;
290
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800291 for (auto&& request: requests) {
292 if (request.mIsReprocess) {
Chien-Yu Chened0412e2015-04-27 15:04:22 -0700293 if (!mInputStream.configured) {
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800294 ALOGE("%s: Camera %s: no input stream is configured.", __FUNCTION__,
295 mCameraIdStr.string());
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800296 return STATUS_ERROR_FMT(CameraService::ERROR_ILLEGAL_ARGUMENT,
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800297 "No input configured for camera %s but request is for reprocessing",
298 mCameraIdStr.string());
Chien-Yu Chened0412e2015-04-27 15:04:22 -0700299 } else if (streaming) {
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800300 ALOGE("%s: Camera %s: streaming reprocess requests not supported.", __FUNCTION__,
301 mCameraIdStr.string());
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800302 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT,
303 "Repeating reprocess requests not supported");
Emilian Peevaebbe412018-01-15 13:53:24 +0000304 } else if (request.mPhysicalCameraSettings.size() > 1) {
305 ALOGE("%s: Camera %s: reprocess requests not supported for "
306 "multiple physical cameras.", __FUNCTION__,
307 mCameraIdStr.string());
308 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT,
309 "Reprocess requests not supported for multiple cameras");
Chien-Yu Chen618ff8a2015-03-13 11:27:17 -0700310 }
Jianing Wei90e59c92014-03-12 18:29:36 -0700311 }
312
Emilian Peevaebbe412018-01-15 13:53:24 +0000313 if (request.mPhysicalCameraSettings.empty()) {
314 ALOGE("%s: Camera %s: request doesn't contain any settings.", __FUNCTION__,
315 mCameraIdStr.string());
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800316 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT,
Emilian Peevaebbe412018-01-15 13:53:24 +0000317 "Request doesn't contain any settings");
318 }
319
320 //The first capture settings should always match the logical camera id
321 String8 logicalId(request.mPhysicalCameraSettings.begin()->id.c_str());
322 if (mDevice->getId() != logicalId) {
323 ALOGE("%s: Camera %s: Invalid camera request settings.", __FUNCTION__,
324 mCameraIdStr.string());
325 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT,
326 "Invalid camera request settings");
327 }
328
Emilian Peevaebbe412018-01-15 13:53:24 +0000329 if (request.mSurfaceList.isEmpty() && request.mStreamIdxList.size() == 0) {
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800330 ALOGE("%s: Camera %s: Requests must have at least one surface target. "
331 "Rejecting request.", __FUNCTION__, mCameraIdStr.string());
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800332 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT,
333 "Request has no output targets");
Jianing Wei90e59c92014-03-12 18:29:36 -0700334 }
335
Jianing Wei90e59c92014-03-12 18:29:36 -0700336 /**
Shuzhen Wang0129d522016-10-30 22:43:41 -0700337 * Write in the output stream IDs and map from stream ID to surface ID
338 * which we calculate from the capture request's list of surface target
Jianing Wei90e59c92014-03-12 18:29:36 -0700339 */
Shuzhen Wang0129d522016-10-30 22:43:41 -0700340 SurfaceMap surfaceMap;
Jianing Wei90e59c92014-03-12 18:29:36 -0700341 Vector<int32_t> outputStreamIds;
Emilian Peevf873aa52018-01-26 14:58:28 +0000342 std::vector<std::string> requestedPhysicalIds;
Emilian Peevc81a7592022-02-14 17:38:18 -0800343 int64_t dynamicProfileBitmap = 0;
Yin-Chia Yeh4dfa4cc2017-11-10 20:00:09 -0800344 if (request.mSurfaceList.size() > 0) {
Chih-Hung Hsieh3ef324d2018-12-11 11:48:12 -0800345 for (const sp<Surface>& surface : request.mSurfaceList) {
Yin-Chia Yeh4dfa4cc2017-11-10 20:00:09 -0800346 if (surface == 0) continue;
Jianing Wei90e59c92014-03-12 18:29:36 -0700347
Emilian Peevf873aa52018-01-26 14:58:28 +0000348 int32_t streamId;
Yin-Chia Yeh4dfa4cc2017-11-10 20:00:09 -0800349 sp<IGraphicBufferProducer> gbp = surface->getIGraphicBufferProducer();
Emilian Peevf873aa52018-01-26 14:58:28 +0000350 res = insertGbpLocked(gbp, &surfaceMap, &outputStreamIds, &streamId);
Yin-Chia Yeh4dfa4cc2017-11-10 20:00:09 -0800351 if (!res.isOk()) {
352 return res;
353 }
Emilian Peevf873aa52018-01-26 14:58:28 +0000354
355 ssize_t index = mConfiguredOutputs.indexOfKey(streamId);
356 if (index >= 0) {
357 String8 requestedPhysicalId(
358 mConfiguredOutputs.valueAt(index).getPhysicalCameraId());
359 requestedPhysicalIds.push_back(requestedPhysicalId.string());
Emilian Peev2295df72021-11-12 18:14:10 -0800360 dynamicProfileBitmap |=
361 mConfiguredOutputs.valueAt(index).getDynamicRangeProfile();
Emilian Peevf873aa52018-01-26 14:58:28 +0000362 } else {
363 ALOGW("%s: Output stream Id not found among configured outputs!", __FUNCTION__);
364 }
Jianing Wei90e59c92014-03-12 18:29:36 -0700365 }
Yin-Chia Yeh4dfa4cc2017-11-10 20:00:09 -0800366 } else {
367 for (size_t i = 0; i < request.mStreamIdxList.size(); i++) {
368 int streamId = request.mStreamIdxList.itemAt(i);
369 int surfaceIdx = request.mSurfaceIdxList.itemAt(i);
Jianing Wei90e59c92014-03-12 18:29:36 -0700370
Yin-Chia Yeh4dfa4cc2017-11-10 20:00:09 -0800371 ssize_t index = mConfiguredOutputs.indexOfKey(streamId);
372 if (index < 0) {
373 ALOGE("%s: Camera %s: Tried to submit a request with a surface that"
374 " we have not called createStream on: stream %d",
375 __FUNCTION__, mCameraIdStr.string(), streamId);
376 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT,
377 "Request targets Surface that is not part of current capture session");
378 }
379
380 const auto& gbps = mConfiguredOutputs.valueAt(index).getGraphicBufferProducers();
381 if ((size_t)surfaceIdx >= gbps.size()) {
382 ALOGE("%s: Camera %s: Tried to submit a request with a surface that"
383 " we have not called createStream on: stream %d, surfaceIdx %d",
384 __FUNCTION__, mCameraIdStr.string(), streamId, surfaceIdx);
385 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT,
386 "Request targets Surface has invalid surface index");
387 }
388
Emilian Peevf873aa52018-01-26 14:58:28 +0000389 res = insertGbpLocked(gbps[surfaceIdx], &surfaceMap, &outputStreamIds, nullptr);
Yin-Chia Yeh4dfa4cc2017-11-10 20:00:09 -0800390 if (!res.isOk()) {
391 return res;
392 }
Emilian Peevf873aa52018-01-26 14:58:28 +0000393
394 String8 requestedPhysicalId(
395 mConfiguredOutputs.valueAt(index).getPhysicalCameraId());
396 requestedPhysicalIds.push_back(requestedPhysicalId.string());
Emilian Peev2295df72021-11-12 18:14:10 -0800397 dynamicProfileBitmap |=
398 mConfiguredOutputs.valueAt(index).getDynamicRangeProfile();
399 }
400 }
401
402 if (dynamicProfileBitmap !=
403 ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD) {
404 for (int i = ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_STANDARD;
405 i < ANDROID_REQUEST_AVAILABLE_DYNAMIC_RANGE_PROFILES_MAP_MAX; i <<= 1) {
406 if ((dynamicProfileBitmap & i) == 0) {
407 continue;
408 }
409
410 const auto& it = mDynamicProfileMap.find(i);
411 if (it != mDynamicProfileMap.end()) {
412 if ((it->second == 0) ||
413 ((it->second & dynamicProfileBitmap) == dynamicProfileBitmap)) {
414 continue;
415 } else {
416 ALOGE("%s: Camera %s: Tried to submit a request with a surfaces that"
417 " reference an unsupported dynamic range profile combination"
Emilian Peevc81a7592022-02-14 17:38:18 -0800418 " 0x%" PRIx64 "!", __FUNCTION__, mCameraIdStr.string(),
Emilian Peev2295df72021-11-12 18:14:10 -0800419 dynamicProfileBitmap);
420 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT,
421 "Request targets an unsupported dynamic range profile"
422 " combination");
423 }
424 } else {
425 ALOGE("%s: Camera %s: Tried to submit a request with a surface that"
426 " references unsupported dynamic range profile 0x%x!",
427 __FUNCTION__, mCameraIdStr.string(), i);
428 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT,
429 "Request targets 10-bit Surface with unsupported dynamic range"
430 " profile");
431 }
Shuzhen Wang0129d522016-10-30 22:43:41 -0700432 }
Jianing Wei90e59c92014-03-12 18:29:36 -0700433 }
434
Emilian Peevf873aa52018-01-26 14:58:28 +0000435 CameraDeviceBase::PhysicalCameraSettingsList physicalSettingsList;
436 for (const auto& it : request.mPhysicalCameraSettings) {
Emilian Peev00420d22018-02-05 21:33:13 +0000437 if (it.settings.isEmpty()) {
438 ALOGE("%s: Camera %s: Sent empty metadata packet. Rejecting request.",
439 __FUNCTION__, mCameraIdStr.string());
440 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT,
441 "Request settings are empty");
442 }
443
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800444 // Check whether the physical / logical stream has settings
445 // consistent with the sensor pixel mode(s) it was configured with.
446 // mCameraIdToStreamSet will only have ids that are high resolution
447 const auto streamIdSetIt = mHighResolutionCameraIdToStreamIdSet.find(it.id);
448 if (streamIdSetIt != mHighResolutionCameraIdToStreamIdSet.end()) {
449 std::list<int> streamIdsUsedInRequest = getIntersection(streamIdSetIt->second,
450 outputStreamIds);
451 if (!request.mIsReprocess &&
452 !isSensorPixelModeConsistent(streamIdsUsedInRequest, it.settings)) {
453 ALOGE("%s: Camera %s: Request settings CONTROL_SENSOR_PIXEL_MODE not "
454 "consistent with configured streams. Rejecting request.",
455 __FUNCTION__, it.id.c_str());
456 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT,
457 "Request settings CONTROL_SENSOR_PIXEL_MODE are not consistent with "
458 "streams configured");
459 }
460 }
461
Emilian Peevf873aa52018-01-26 14:58:28 +0000462 String8 physicalId(it.id.c_str());
Shuzhen Wang911c6a32021-10-27 13:36:03 -0700463 bool hasTestPatternModePhysicalKey = std::find(mSupportedPhysicalRequestKeys.begin(),
464 mSupportedPhysicalRequestKeys.end(), ANDROID_SENSOR_TEST_PATTERN_MODE) !=
465 mSupportedPhysicalRequestKeys.end();
466 bool hasTestPatternDataPhysicalKey = std::find(mSupportedPhysicalRequestKeys.begin(),
467 mSupportedPhysicalRequestKeys.end(), ANDROID_SENSOR_TEST_PATTERN_DATA) !=
468 mSupportedPhysicalRequestKeys.end();
Emilian Peevf873aa52018-01-26 14:58:28 +0000469 if (physicalId != mDevice->getId()) {
470 auto found = std::find(requestedPhysicalIds.begin(), requestedPhysicalIds.end(),
471 it.id);
472 if (found == requestedPhysicalIds.end()) {
473 ALOGE("%s: Camera %s: Physical camera id: %s not part of attached outputs.",
474 __FUNCTION__, mCameraIdStr.string(), physicalId.string());
475 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT,
476 "Invalid physical camera id");
477 }
Emilian Peev00420d22018-02-05 21:33:13 +0000478
479 if (!mSupportedPhysicalRequestKeys.empty()) {
480 // Filter out any unsupported physical request keys.
481 CameraMetadata filteredParams(mSupportedPhysicalRequestKeys.size());
482 camera_metadata_t *meta = const_cast<camera_metadata_t *>(
483 filteredParams.getAndLock());
484 set_camera_metadata_vendor_id(meta, mDevice->getVendorTagId());
485 filteredParams.unlock(meta);
486
487 for (const auto& keyIt : mSupportedPhysicalRequestKeys) {
488 camera_metadata_ro_entry entry = it.settings.find(keyIt);
489 if (entry.count > 0) {
490 filteredParams.update(entry);
491 }
492 }
493
Shuzhen Wang911c6a32021-10-27 13:36:03 -0700494 physicalSettingsList.push_back({it.id, filteredParams,
495 hasTestPatternModePhysicalKey, hasTestPatternDataPhysicalKey});
Emilian Peev00420d22018-02-05 21:33:13 +0000496 }
497 } else {
498 physicalSettingsList.push_back({it.id, it.settings});
Emilian Peevf873aa52018-01-26 14:58:28 +0000499 }
Emilian Peevf873aa52018-01-26 14:58:28 +0000500 }
501
502 if (!enforceRequestPermissions(physicalSettingsList.begin()->metadata)) {
503 // Callee logs
504 return STATUS_ERROR(CameraService::ERROR_PERMISSION_DENIED,
505 "Caller does not have permission to change restricted controls");
506 }
507
Emilian Peevaebbe412018-01-15 13:53:24 +0000508 physicalSettingsList.begin()->metadata.update(ANDROID_REQUEST_OUTPUT_STREAMS,
509 &outputStreamIds[0], outputStreamIds.size());
Jianing Wei90e59c92014-03-12 18:29:36 -0700510
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800511 if (request.mIsReprocess) {
Emilian Peevaebbe412018-01-15 13:53:24 +0000512 physicalSettingsList.begin()->metadata.update(ANDROID_REQUEST_INPUT_STREAMS,
513 &mInputStream.id, 1);
Chien-Yu Chen618ff8a2015-03-13 11:27:17 -0700514 }
515
Emilian Peevaebbe412018-01-15 13:53:24 +0000516 physicalSettingsList.begin()->metadata.update(ANDROID_REQUEST_ID,
517 &(submitInfo->mRequestId), /*size*/1);
Jianing Wei90e59c92014-03-12 18:29:36 -0700518 loopCounter++; // loopCounter starts from 1
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800519 ALOGV("%s: Camera %s: Creating request with ID %d (%d of %zu)",
520 __FUNCTION__, mCameraIdStr.string(), submitInfo->mRequestId,
521 loopCounter, requests.size());
Jianing Wei90e59c92014-03-12 18:29:36 -0700522
Emilian Peevaebbe412018-01-15 13:53:24 +0000523 metadataRequestList.push_back(physicalSettingsList);
Shuzhen Wang0129d522016-10-30 22:43:41 -0700524 surfaceMapList.push_back(surfaceMap);
Shuzhen Wangd26b1862022-03-07 12:05:05 -0800525
Shuzhen Wang9372b0b2022-05-11 18:55:19 -0700526 // Save certain CaptureRequest settings
Shuzhen Wangd26b1862022-03-07 12:05:05 -0800527 if (!request.mUserTag.empty()) {
528 mUserTag = request.mUserTag;
529 }
Shuzhen Wang9372b0b2022-05-11 18:55:19 -0700530 camera_metadata_entry entry =
531 physicalSettingsList.begin()->metadata.find(
532 ANDROID_CONTROL_VIDEO_STABILIZATION_MODE);
533 if (entry.count == 1) {
534 mVideoStabilizationMode = entry.data.u8[0];
535 }
Jianing Wei90e59c92014-03-12 18:29:36 -0700536 }
537 mRequestIdCounter++;
538
539 if (streaming) {
Shuzhen Wang0129d522016-10-30 22:43:41 -0700540 err = mDevice->setStreamingRequestList(metadataRequestList, surfaceMapList,
541 &(submitInfo->mLastFrameNumber));
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800542 if (err != OK) {
543 String8 msg = String8::format(
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800544 "Camera %s: Got error %s (%d) after trying to set streaming request",
545 mCameraIdStr.string(), strerror(-err), err);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800546 ALOGE("%s: %s", __FUNCTION__, msg.string());
547 res = STATUS_ERROR(CameraService::ERROR_INVALID_OPERATION,
548 msg.string());
Jianing Wei90e59c92014-03-12 18:29:36 -0700549 } else {
Shuzhen Wangc9ca6782016-04-26 13:40:31 -0700550 Mutex::Autolock idLock(mStreamingRequestIdLock);
Chien-Yu Chene8c535e2016-04-14 12:18:26 -0700551 mStreamingRequestId = submitInfo->mRequestId;
Jianing Wei90e59c92014-03-12 18:29:36 -0700552 }
553 } else {
Shuzhen Wang0129d522016-10-30 22:43:41 -0700554 err = mDevice->captureList(metadataRequestList, surfaceMapList,
555 &(submitInfo->mLastFrameNumber));
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800556 if (err != OK) {
557 String8 msg = String8::format(
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800558 "Camera %s: Got error %s (%d) after trying to submit capture request",
559 mCameraIdStr.string(), strerror(-err), err);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800560 ALOGE("%s: %s", __FUNCTION__, msg.string());
561 res = STATUS_ERROR(CameraService::ERROR_INVALID_OPERATION,
562 msg.string());
Jianing Wei90e59c92014-03-12 18:29:36 -0700563 }
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800564 ALOGV("%s: requestId = %d ", __FUNCTION__, submitInfo->mRequestId);
Jianing Wei90e59c92014-03-12 18:29:36 -0700565 }
566
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800567 ALOGV("%s: Camera %s: End of function", __FUNCTION__, mCameraIdStr.string());
Jianing Wei90e59c92014-03-12 18:29:36 -0700568 return res;
569}
570
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800571binder::Status CameraDeviceClient::cancelRequest(
572 int requestId,
573 /*out*/
574 int64_t* lastFrameNumber) {
Igor Murashkine7ee7632013-06-11 18:10:18 -0700575 ATRACE_CALL();
576 ALOGV("%s, requestId = %d", __FUNCTION__, requestId);
577
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800578 status_t err;
579 binder::Status res;
Igor Murashkine7ee7632013-06-11 18:10:18 -0700580
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800581 if (!(res = checkPidStatus(__FUNCTION__)).isOk()) return res;
Igor Murashkine7ee7632013-06-11 18:10:18 -0700582
583 Mutex::Autolock icl(mBinderSerializationLock);
584
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800585 if (!mDevice.get()) {
586 return STATUS_ERROR(CameraService::ERROR_DISCONNECTED, "Camera device no longer alive");
587 }
Igor Murashkine7ee7632013-06-11 18:10:18 -0700588
Shuzhen Wangc9ca6782016-04-26 13:40:31 -0700589 Mutex::Autolock idLock(mStreamingRequestIdLock);
Chien-Yu Chene8c535e2016-04-14 12:18:26 -0700590 if (mStreamingRequestId != requestId) {
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800591 String8 msg = String8::format("Camera %s: Canceling request ID %d doesn't match "
592 "current request ID %d", mCameraIdStr.string(), requestId, mStreamingRequestId);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800593 ALOGE("%s: %s", __FUNCTION__, msg.string());
594 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
Igor Murashkine7ee7632013-06-11 18:10:18 -0700595 }
596
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800597 err = mDevice->clearStreamingRequest(lastFrameNumber);
Igor Murashkine7ee7632013-06-11 18:10:18 -0700598
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800599 if (err == OK) {
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800600 ALOGV("%s: Camera %s: Successfully cleared streaming request",
601 __FUNCTION__, mCameraIdStr.string());
Chien-Yu Chene8c535e2016-04-14 12:18:26 -0700602 mStreamingRequestId = REQUEST_ID_NONE;
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800603 } else {
604 res = STATUS_ERROR_FMT(CameraService::ERROR_INVALID_OPERATION,
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800605 "Camera %s: Error clearing streaming request: %s (%d)",
606 mCameraIdStr.string(), strerror(-err), err);
Igor Murashkine7ee7632013-06-11 18:10:18 -0700607 }
608
609 return res;
610}
611
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800612binder::Status CameraDeviceClient::beginConfigure() {
Ruben Brunkb2119af2014-05-09 19:57:56 -0700613 // TODO: Implement this.
Eino-Ville Talvala6aeb8882017-08-07 17:40:49 -0700614 ATRACE_CALL();
Zhijun He1fa89992015-06-01 15:44:31 -0700615 ALOGV("%s: Not implemented yet.", __FUNCTION__);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800616 return binder::Status::ok();
Ruben Brunkb2119af2014-05-09 19:57:56 -0700617}
618
Emilian Peev5fbe0ba2017-10-20 15:45:45 +0100619binder::Status CameraDeviceClient::endConfigure(int operatingMode,
Shuzhen Wang316781a2020-08-18 18:11:01 -0700620 const hardware::camera2::impl::CameraMetadataNative& sessionParams, int64_t startTimeMs,
Emilian Peevcc0b7952020-01-07 13:54:47 -0800621 std::vector<int>* offlineStreamIds /*out*/) {
Eino-Ville Talvala6aeb8882017-08-07 17:40:49 -0700622 ATRACE_CALL();
Shuzhen Wang0129d522016-10-30 22:43:41 -0700623 ALOGV("%s: ending configure (%d input stream, %zu output surfaces)",
624 __FUNCTION__, mInputStream.configured ? 1 : 0,
625 mStreamMap.size());
Igor Murashkine2d167e2014-08-19 16:19:59 -0700626
Zhijun He0effd522016-03-04 10:22:27 -0800627 binder::Status res;
628 if (!(res = checkPidStatus(__FUNCTION__)).isOk()) return res;
629
Emilian Peevcc0b7952020-01-07 13:54:47 -0800630 if (offlineStreamIds == nullptr) {
631 String8 msg = String8::format("Invalid offline stream ids");
632 ALOGE("%s: %s", __FUNCTION__, msg.string());
633 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
634 }
635
Zhijun He0effd522016-03-04 10:22:27 -0800636 Mutex::Autolock icl(mBinderSerializationLock);
637
638 if (!mDevice.get()) {
639 return STATUS_ERROR(CameraService::ERROR_DISCONNECTED, "Camera device no longer alive");
640 }
641
Shuzhen Wangd4abdf72021-05-28 11:22:50 -0700642 res = SessionConfigurationUtils::checkOperatingMode(operatingMode, mDevice->info(),
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000643 mCameraIdStr);
Emilian Peev35ae8262018-11-08 13:11:32 +0000644 if (!res.isOk()) {
645 return res;
646 }
647
648 status_t err = mDevice->configureStreams(sessionParams, operatingMode);
649 if (err == BAD_VALUE) {
650 String8 msg = String8::format("Camera %s: Unsupported set of inputs/outputs provided",
651 mCameraIdStr.string());
652 ALOGE("%s: %s", __FUNCTION__, msg.string());
653 res = STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
654 } else if (err != OK) {
655 String8 msg = String8::format("Camera %s: Error configuring streams: %s (%d)",
656 mCameraIdStr.string(), strerror(-err), err);
657 ALOGE("%s: %s", __FUNCTION__, msg.string());
658 res = STATUS_ERROR(CameraService::ERROR_INVALID_OPERATION, msg.string());
Emilian Peev538c90e2018-12-17 18:03:19 +0000659 } else {
Emilian Peevcc0b7952020-01-07 13:54:47 -0800660 offlineStreamIds->clear();
661 mDevice->getOfflineStreamIds(offlineStreamIds);
662
Emilian Peev2f5d6012022-01-19 16:16:50 -0800663 Mutex::Autolock l(mCompositeLock);
Emilian Peev538c90e2018-12-17 18:03:19 +0000664 for (size_t i = 0; i < mCompositeStreamMap.size(); ++i) {
665 err = mCompositeStreamMap.valueAt(i)->configureStream();
Emilian Peevcc0b7952020-01-07 13:54:47 -0800666 if (err != OK) {
Emilian Peev538c90e2018-12-17 18:03:19 +0000667 String8 msg = String8::format("Camera %s: Error configuring composite "
668 "streams: %s (%d)", mCameraIdStr.string(), strerror(-err), err);
669 ALOGE("%s: %s", __FUNCTION__, msg.string());
670 res = STATUS_ERROR(CameraService::ERROR_INVALID_OPERATION, msg.string());
671 break;
672 }
Emilian Peevcc0b7952020-01-07 13:54:47 -0800673
674 // Composite streams can only support offline mode in case all individual internal
675 // streams are also supported.
676 std::vector<int> internalStreams;
677 mCompositeStreamMap.valueAt(i)->insertCompositeStreamIds(&internalStreams);
Emilian Peevfaa4bde2020-01-23 12:19:37 -0800678 offlineStreamIds->erase(
679 std::remove_if(offlineStreamIds->begin(), offlineStreamIds->end(),
Emilian Peevcc0b7952020-01-07 13:54:47 -0800680 [&internalStreams] (int streamId) {
681 auto it = std::find(internalStreams.begin(), internalStreams.end(),
682 streamId);
683 if (it != internalStreams.end()) {
684 internalStreams.erase(it);
685 return true;
686 }
687
Emilian Peevfaa4bde2020-01-23 12:19:37 -0800688 return false;}), offlineStreamIds->end());
Emilian Peevcc0b7952020-01-07 13:54:47 -0800689 if (internalStreams.empty()) {
690 offlineStreamIds->push_back(mCompositeStreamMap.valueAt(i)->getStreamId());
691 }
692 }
693
694 for (const auto& offlineStreamId : *offlineStreamIds) {
695 mStreamInfoMap[offlineStreamId].supportsOffline = true;
Emilian Peev538c90e2018-12-17 18:03:19 +0000696 }
Shuzhen Wang316781a2020-08-18 18:11:01 -0700697
698 nsecs_t configureEnd = systemTime();
699 int32_t configureDurationMs = ns2ms(configureEnd) - startTimeMs;
Austin Borger74fca042022-05-23 12:41:21 -0700700 mCameraServiceProxyWrapper->logStreamConfigured(mCameraIdStr, operatingMode,
Shuzhen Wang316781a2020-08-18 18:11:01 -0700701 false /*internalReconfig*/, configureDurationMs);
Emilian Peev35ae8262018-11-08 13:11:32 +0000702 }
703
704 return res;
705}
706
Jayant Chowdhary2bbdce42020-01-12 14:55:41 -0800707binder::Status CameraDeviceClient::isSessionConfigurationSupported(
708 const SessionConfiguration& sessionConfiguration, bool *status /*out*/) {
Jayant Chowdhary2bbdce42020-01-12 14:55:41 -0800709
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800710 ATRACE_CALL();
Jayant Chowdhary2bbdce42020-01-12 14:55:41 -0800711 binder::Status res;
712 status_t ret = OK;
713 if (!(res = checkPidStatus(__FUNCTION__)).isOk()) return res;
714
715 Mutex::Autolock icl(mBinderSerializationLock);
716
717 if (!mDevice.get()) {
718 return STATUS_ERROR(CameraService::ERROR_DISCONNECTED, "Camera device no longer alive");
719 }
720
721 auto operatingMode = sessionConfiguration.getOperatingMode();
Shuzhen Wangd4abdf72021-05-28 11:22:50 -0700722 res = SessionConfigurationUtils::checkOperatingMode(operatingMode, mDevice->info(),
Colin Crossb8a9dbb2020-08-27 04:12:26 +0000723 mCameraIdStr);
Jayant Chowdhary2bbdce42020-01-12 14:55:41 -0800724 if (!res.isOk()) {
725 return res;
726 }
727
728 if (status == nullptr) {
729 String8 msg = String8::format( "Camera %s: Invalid status!", mCameraIdStr.string());
730 ALOGE("%s: %s", __FUNCTION__, msg.string());
731 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
732 }
Shuzhen Wangd4abdf72021-05-28 11:22:50 -0700733
Emilian Peev35ae8262018-11-08 13:11:32 +0000734 *status = false;
Shuzhen Wanga79a64d2022-04-24 19:56:30 -0700735 camera3::metadataGetter getMetadata = [this](const String8 &id, bool /*overrideForPerfClass*/) {
736 return mDevice->infoPhysical(id);};
Emilian Peev35ae8262018-11-08 13:11:32 +0000737 ret = mProviderManager->isSessionConfigurationSupported(mCameraIdStr.string(),
Shuzhen Wanga79a64d2022-04-24 19:56:30 -0700738 sessionConfiguration, mOverrideForPerfClass, getMetadata, status);
Emilian Peev35ae8262018-11-08 13:11:32 +0000739 switch (ret) {
740 case OK:
741 // Expected, do nothing.
742 break;
743 case INVALID_OPERATION: {
744 String8 msg = String8::format(
745 "Camera %s: Session configuration query not supported!",
746 mCameraIdStr.string());
747 ALOGD("%s: %s", __FUNCTION__, msg.string());
748 res = STATUS_ERROR(CameraService::ERROR_INVALID_OPERATION, msg.string());
749 }
750
751 break;
752 default: {
753 String8 msg = String8::format( "Camera %s: Error: %s (%d)", mCameraIdStr.string(),
754 strerror(-ret), ret);
755 ALOGE("%s: %s", __FUNCTION__, msg.string());
756 res = STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT,
757 msg.string());
758 }
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800759 }
760
761 return res;
Ruben Brunkb2119af2014-05-09 19:57:56 -0700762}
763
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800764binder::Status CameraDeviceClient::deleteStream(int streamId) {
Igor Murashkine7ee7632013-06-11 18:10:18 -0700765 ATRACE_CALL();
766 ALOGV("%s (streamId = 0x%x)", __FUNCTION__, streamId);
767
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800768 binder::Status res;
769 if (!(res = checkPidStatus(__FUNCTION__)).isOk()) return res;
Igor Murashkine7ee7632013-06-11 18:10:18 -0700770
771 Mutex::Autolock icl(mBinderSerializationLock);
772
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800773 if (!mDevice.get()) {
774 return STATUS_ERROR(CameraService::ERROR_DISCONNECTED, "Camera device no longer alive");
775 }
Igor Murashkine7ee7632013-06-11 18:10:18 -0700776
Chien-Yu Chen618ff8a2015-03-13 11:27:17 -0700777 bool isInput = false;
Shuzhen Wang0129d522016-10-30 22:43:41 -0700778 std::vector<sp<IBinder>> surfaces;
Zhijun He5d677d12016-05-29 16:52:39 -0700779 ssize_t dIndex = NAME_NOT_FOUND;
Emilian Peev538c90e2018-12-17 18:03:19 +0000780 ssize_t compositeIndex = NAME_NOT_FOUND;
Igor Murashkine7ee7632013-06-11 18:10:18 -0700781
Chien-Yu Chen618ff8a2015-03-13 11:27:17 -0700782 if (mInputStream.configured && mInputStream.id == streamId) {
783 isInput = true;
784 } else {
785 // Guard against trying to delete non-created streams
786 for (size_t i = 0; i < mStreamMap.size(); ++i) {
Shuzhen Wang0129d522016-10-30 22:43:41 -0700787 if (streamId == mStreamMap.valueAt(i).streamId()) {
788 surfaces.push_back(mStreamMap.keyAt(i));
789 }
790 }
791
792 // See if this stream is one of the deferred streams.
793 for (size_t i = 0; i < mDeferredStreams.size(); ++i) {
794 if (streamId == mDeferredStreams[i]) {
795 dIndex = i;
Chien-Yu Chen618ff8a2015-03-13 11:27:17 -0700796 break;
797 }
798 }
799
Emilian Peev2f5d6012022-01-19 16:16:50 -0800800 Mutex::Autolock l(mCompositeLock);
Emilian Peev538c90e2018-12-17 18:03:19 +0000801 for (size_t i = 0; i < mCompositeStreamMap.size(); ++i) {
802 if (streamId == mCompositeStreamMap.valueAt(i)->getStreamId()) {
803 compositeIndex = i;
804 break;
805 }
806 }
807
Shuzhen Wang0129d522016-10-30 22:43:41 -0700808 if (surfaces.empty() && dIndex == NAME_NOT_FOUND) {
809 String8 msg = String8::format("Camera %s: Invalid stream ID (%d) specified, no such"
810 " stream created yet", mCameraIdStr.string(), streamId);
811 ALOGW("%s: %s", __FUNCTION__, msg.string());
812 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
Chien-Yu Chen618ff8a2015-03-13 11:27:17 -0700813 }
Igor Murashkine7ee7632013-06-11 18:10:18 -0700814 }
815
816 // Also returns BAD_VALUE if stream ID was not valid
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800817 status_t err = mDevice->deleteStream(streamId);
Igor Murashkine7ee7632013-06-11 18:10:18 -0700818
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800819 if (err != OK) {
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800820 String8 msg = String8::format("Camera %s: Unexpected error %s (%d) when deleting stream %d",
821 mCameraIdStr.string(), strerror(-err), err, streamId);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800822 ALOGE("%s: %s", __FUNCTION__, msg.string());
823 res = STATUS_ERROR(CameraService::ERROR_INVALID_OPERATION, msg.string());
824 } else {
Chien-Yu Chen618ff8a2015-03-13 11:27:17 -0700825 if (isInput) {
826 mInputStream.configured = false;
Zhijun He5d677d12016-05-29 16:52:39 -0700827 } else {
Shuzhen Wang0129d522016-10-30 22:43:41 -0700828 for (auto& surface : surfaces) {
829 mStreamMap.removeItem(surface);
830 }
831
Yin-Chia Yeh4dfa4cc2017-11-10 20:00:09 -0800832 mConfiguredOutputs.removeItem(streamId);
833
Shuzhen Wang0129d522016-10-30 22:43:41 -0700834 if (dIndex != NAME_NOT_FOUND) {
835 mDeferredStreams.removeItemsAt(dIndex);
836 }
Emilian Peev538c90e2018-12-17 18:03:19 +0000837
838 if (compositeIndex != NAME_NOT_FOUND) {
Emilian Peev2f5d6012022-01-19 16:16:50 -0800839 Mutex::Autolock l(mCompositeLock);
Emilian Peev538c90e2018-12-17 18:03:19 +0000840 status_t ret;
841 if ((ret = mCompositeStreamMap.valueAt(compositeIndex)->deleteStream())
842 != OK) {
843 String8 msg = String8::format("Camera %s: Unexpected error %s (%d) when "
844 "deleting composite stream %d", mCameraIdStr.string(), strerror(-err), err,
845 streamId);
846 ALOGE("%s: %s", __FUNCTION__, msg.string());
847 res = STATUS_ERROR(CameraService::ERROR_INVALID_OPERATION, msg.string());
848 }
849 mCompositeStreamMap.removeItemsAt(compositeIndex);
850 }
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800851 for (auto &mapIt: mHighResolutionCameraIdToStreamIdSet) {
852 auto &streamSet = mapIt.second;
853 if (streamSet.find(streamId) != streamSet.end()) {
854 streamSet.erase(streamId);
855 break;
856 }
857 }
Chien-Yu Chen618ff8a2015-03-13 11:27:17 -0700858 }
Igor Murashkine7ee7632013-06-11 18:10:18 -0700859 }
860
861 return res;
862}
863
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800864binder::Status CameraDeviceClient::createStream(
865 const hardware::camera2::params::OutputConfiguration &outputConfiguration,
866 /*out*/
867 int32_t* newStreamId) {
Igor Murashkine7ee7632013-06-11 18:10:18 -0700868 ATRACE_CALL();
Igor Murashkine7ee7632013-06-11 18:10:18 -0700869
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800870 binder::Status res;
871 if (!(res = checkPidStatus(__FUNCTION__)).isOk()) return res;
Igor Murashkine7ee7632013-06-11 18:10:18 -0700872
873 Mutex::Autolock icl(mBinderSerializationLock);
874
Shuzhen Wang0129d522016-10-30 22:43:41 -0700875 const std::vector<sp<IGraphicBufferProducer>>& bufferProducers =
876 outputConfiguration.getGraphicBufferProducers();
877 size_t numBufferProducers = bufferProducers.size();
Shuzhen Wang758c2152017-01-10 18:26:18 -0800878 bool deferredConsumer = outputConfiguration.isDeferred();
879 bool isShared = outputConfiguration.isShared();
Shuzhen Wangc28189a2017-11-27 23:05:10 -0800880 String8 physicalCameraId = String8(outputConfiguration.getPhysicalCameraId());
Shuzhen Wang758c2152017-01-10 18:26:18 -0800881 bool deferredConsumerOnly = deferredConsumer && numBufferProducers == 0;
Shuzhen Wang83bff122020-11-20 15:51:39 -0800882 bool isMultiResolution = outputConfiguration.isMultiResolution();
Emilian Peevc81a7592022-02-14 17:38:18 -0800883 int64_t dynamicRangeProfile = outputConfiguration.getDynamicRangeProfile();
Shuzhen Wang8ed1e872022-03-08 16:34:33 -0800884 int64_t streamUseCase = outputConfiguration.getStreamUseCase();
Shuzhen Wange4208922022-02-01 16:52:48 -0800885 int timestampBase = outputConfiguration.getTimestampBase();
Shuzhen Wang610d7b82022-02-08 14:37:22 -0800886 int mirrorMode = outputConfiguration.getMirrorMode();
Shuzhen Wang0129d522016-10-30 22:43:41 -0700887
Shuzhen Wangd4abdf72021-05-28 11:22:50 -0700888 res = SessionConfigurationUtils::checkSurfaceType(numBufferProducers, deferredConsumer,
Emilian Peev35ae8262018-11-08 13:11:32 +0000889 outputConfiguration.getSurfaceType());
890 if (!res.isOk()) {
891 return res;
Yin-Chia Yeh89f14da2014-06-10 16:05:44 -0700892 }
Zhijun He5d677d12016-05-29 16:52:39 -0700893
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800894 if (!mDevice.get()) {
895 return STATUS_ERROR(CameraService::ERROR_DISCONNECTED, "Camera device no longer alive");
896 }
Shuzhen Wangd4abdf72021-05-28 11:22:50 -0700897 res = SessionConfigurationUtils::checkPhysicalCameraId(mPhysicalCameraIds,
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800898 physicalCameraId, mCameraIdStr);
Emilian Peev35ae8262018-11-08 13:11:32 +0000899 if (!res.isOk()) {
900 return res;
Shuzhen Wangc28189a2017-11-27 23:05:10 -0800901 }
Emilian Peev35ae8262018-11-08 13:11:32 +0000902
Shuzhen Wang0129d522016-10-30 22:43:41 -0700903 std::vector<sp<Surface>> surfaces;
904 std::vector<sp<IBinder>> binders;
Zhijun He5d677d12016-05-29 16:52:39 -0700905 status_t err;
906
907 // Create stream for deferred surface case.
Shuzhen Wang0129d522016-10-30 22:43:41 -0700908 if (deferredConsumerOnly) {
Shuzhen Wang758c2152017-01-10 18:26:18 -0800909 return createDeferredSurfaceStreamLocked(outputConfiguration, isShared, newStreamId);
Zhijun He5d677d12016-05-29 16:52:39 -0700910 }
911
Shuzhen Wang758c2152017-01-10 18:26:18 -0800912 OutputStreamInfo streamInfo;
913 bool isStreamInfoValid = false;
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800914 const std::vector<int32_t> &sensorPixelModesUsed =
915 outputConfiguration.getSensorPixelModesUsed();
Shuzhen Wang0129d522016-10-30 22:43:41 -0700916 for (auto& bufferProducer : bufferProducers) {
Shuzhen Wang0129d522016-10-30 22:43:41 -0700917 // Don't create multiple streams for the same target surface
Shuzhen Wang0129d522016-10-30 22:43:41 -0700918 sp<IBinder> binder = IInterface::asBinder(bufferProducer);
Shuzhen Wang758c2152017-01-10 18:26:18 -0800919 ssize_t index = mStreamMap.indexOfKey(binder);
920 if (index != NAME_NOT_FOUND) {
921 String8 msg = String8::format("Camera %s: Surface already has a stream created for it "
922 "(ID %zd)", mCameraIdStr.string(), index);
923 ALOGW("%s: %s", __FUNCTION__, msg.string());
924 return STATUS_ERROR(CameraService::ERROR_ALREADY_EXISTS, msg.string());
Shuzhen Wang0129d522016-10-30 22:43:41 -0700925 }
Igor Murashkine7ee7632013-06-11 18:10:18 -0700926
Shuzhen Wang758c2152017-01-10 18:26:18 -0800927 sp<Surface> surface;
Shuzhen Wangd4abdf72021-05-28 11:22:50 -0700928 res = SessionConfigurationUtils::createSurfaceFromGbp(streamInfo,
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800929 isStreamInfoValid, surface, bufferProducer, mCameraIdStr,
Shuzhen Wangc8ab4522021-12-14 20:12:42 -0800930 mDevice->infoPhysical(physicalCameraId), sensorPixelModesUsed, dynamicRangeProfile,
Shuzhen Wang610d7b82022-02-08 14:37:22 -0800931 streamUseCase, timestampBase, mirrorMode);
Shuzhen Wang758c2152017-01-10 18:26:18 -0800932
933 if (!res.isOk())
934 return res;
935
936 if (!isStreamInfoValid) {
937 isStreamInfoValid = true;
Shuzhen Wang0129d522016-10-30 22:43:41 -0700938 }
939
Shuzhen Wang758c2152017-01-10 18:26:18 -0800940 binders.push_back(IInterface::asBinder(bufferProducer));
Shuzhen Wang0129d522016-10-30 22:43:41 -0700941 surfaces.push_back(surface);
Ruben Brunkbba75572014-11-20 17:29:50 -0800942 }
Shuzhen Wangd4abdf72021-05-28 11:22:50 -0700943
944 // If mOverrideForPerfClass is true, do not fail createStream() for small
945 // JPEG sizes because existing createSurfaceFromGbp() logic will find the
946 // closest possible supported size.
947
Zhijun He125684a2015-12-26 15:07:30 -0800948 int streamId = camera3::CAMERA3_STREAM_ID_INVALID;
Emilian Peev40ead602017-09-26 15:46:36 +0100949 std::vector<int> surfaceIds;
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800950 bool isDepthCompositeStream =
951 camera3::DepthCompositeStream::isDepthCompositeStream(surfaces[0]);
Shuzhen Wang68ac7ad2019-01-30 14:03:28 -0800952 bool isHeicCompisiteStream = camera3::HeicCompositeStream::isHeicCompositeStream(surfaces[0]);
953 if (isDepthCompositeStream || isHeicCompisiteStream) {
954 sp<CompositeStream> compositeStream;
955 if (isDepthCompositeStream) {
956 compositeStream = new camera3::DepthCompositeStream(mDevice, getRemoteCallback());
957 } else {
958 compositeStream = new camera3::HeicCompositeStream(mDevice, getRemoteCallback());
959 }
960
Emilian Peev538c90e2018-12-17 18:03:19 +0000961 err = compositeStream->createStream(surfaces, deferredConsumer, streamInfo.width,
962 streamInfo.height, streamInfo.format,
Emilian Peevf4816702020-04-03 15:44:51 -0700963 static_cast<camera_stream_rotation_t>(outputConfiguration.getRotation()),
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800964 &streamId, physicalCameraId, streamInfo.sensorPixelModesUsed, &surfaceIds,
965 outputConfiguration.getSurfaceSetID(), isShared, isMultiResolution);
Emilian Peev538c90e2018-12-17 18:03:19 +0000966 if (err == OK) {
Emilian Peev2f5d6012022-01-19 16:16:50 -0800967 Mutex::Autolock l(mCompositeLock);
Emilian Peev538c90e2018-12-17 18:03:19 +0000968 mCompositeStreamMap.add(IInterface::asBinder(surfaces[0]->getIGraphicBufferProducer()),
969 compositeStream);
970 }
Shuzhen Wang68ac7ad2019-01-30 14:03:28 -0800971 } else {
972 err = mDevice->createStream(surfaces, deferredConsumer, streamInfo.width,
973 streamInfo.height, streamInfo.format, streamInfo.dataSpace,
Emilian Peevf4816702020-04-03 15:44:51 -0700974 static_cast<camera_stream_rotation_t>(outputConfiguration.getRotation()),
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -0800975 &streamId, physicalCameraId, streamInfo.sensorPixelModesUsed, &surfaceIds,
Emilian Peev2295df72021-11-12 18:14:10 -0800976 outputConfiguration.getSurfaceSetID(), isShared, isMultiResolution,
Shuzhen Wange4208922022-02-01 16:52:48 -0800977 /*consumerUsage*/0, streamInfo.dynamicRangeProfile, streamInfo.streamUseCase,
Shuzhen Wang610d7b82022-02-08 14:37:22 -0800978 streamInfo.timestampBase, streamInfo.mirrorMode);
Emilian Peev538c90e2018-12-17 18:03:19 +0000979 }
Igor Murashkine7ee7632013-06-11 18:10:18 -0700980
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800981 if (err != OK) {
982 res = STATUS_ERROR_FMT(CameraService::ERROR_INVALID_OPERATION,
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800983 "Camera %s: Error creating output stream (%d x %d, fmt %x, dataSpace %x): %s (%d)",
Shuzhen Wang758c2152017-01-10 18:26:18 -0800984 mCameraIdStr.string(), streamInfo.width, streamInfo.height, streamInfo.format,
985 streamInfo.dataSpace, strerror(-err), err);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -0800986 } else {
Shuzhen Wang0129d522016-10-30 22:43:41 -0700987 int i = 0;
988 for (auto& binder : binders) {
989 ALOGV("%s: mStreamMap add binder %p streamId %d, surfaceId %d",
990 __FUNCTION__, binder.get(), streamId, i);
Emilian Peev40ead602017-09-26 15:46:36 +0100991 mStreamMap.add(binder, StreamSurfaceId(streamId, surfaceIds[i]));
992 i++;
Shuzhen Wang0129d522016-10-30 22:43:41 -0700993 }
Shuzhen Wang758c2152017-01-10 18:26:18 -0800994
Yin-Chia Yeh4dfa4cc2017-11-10 20:00:09 -0800995 mConfiguredOutputs.add(streamId, outputConfiguration);
Shuzhen Wang758c2152017-01-10 18:26:18 -0800996 mStreamInfoMap[streamId] = streamInfo;
997
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -0800998 ALOGV("%s: Camera %s: Successfully created a new stream ID %d for output surface"
Shuzhen Wang0129d522016-10-30 22:43:41 -0700999 " (%d x %d) with format 0x%x.",
Shuzhen Wang758c2152017-01-10 18:26:18 -08001000 __FUNCTION__, mCameraIdStr.string(), streamId, streamInfo.width,
1001 streamInfo.height, streamInfo.format);
Igor Murashkinf8b2a6f2013-09-17 17:03:28 -07001002
Zhijun He5d677d12016-05-29 16:52:39 -07001003 // Set transform flags to ensure preview to be rotated correctly.
Shuzhen Wang610d7b82022-02-08 14:37:22 -08001004 res = setStreamTransformLocked(streamId, streamInfo.mirrorMode);
Igor Murashkinf8b2a6f2013-09-17 17:03:28 -07001005
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -08001006 // Fill in mHighResolutionCameraIdToStreamIdSet map
1007 const String8 &cameraIdUsed =
1008 physicalCameraId.size() != 0 ? physicalCameraId : mCameraIdStr;
1009 const char *cameraIdUsedCStr = cameraIdUsed.string();
1010 // Only needed for high resolution sensors
1011 if (mHighResolutionSensors.find(cameraIdUsedCStr) !=
1012 mHighResolutionSensors.end()) {
1013 mHighResolutionCameraIdToStreamIdSet[cameraIdUsedCStr].insert(streamId);
1014 }
1015
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001016 *newStreamId = streamId;
Igor Murashkine7ee7632013-06-11 18:10:18 -07001017 }
1018
1019 return res;
1020}
1021
Zhijun He5d677d12016-05-29 16:52:39 -07001022binder::Status CameraDeviceClient::createDeferredSurfaceStreamLocked(
1023 const hardware::camera2::params::OutputConfiguration &outputConfiguration,
Shuzhen Wang758c2152017-01-10 18:26:18 -08001024 bool isShared,
Zhijun He5d677d12016-05-29 16:52:39 -07001025 /*out*/
1026 int* newStreamId) {
1027 int width, height, format, surfaceType;
Emilian Peev050f5dc2017-05-18 14:43:56 +01001028 uint64_t consumerUsage;
Zhijun He5d677d12016-05-29 16:52:39 -07001029 android_dataspace dataSpace;
1030 status_t err;
1031 binder::Status res;
1032
1033 if (!mDevice.get()) {
1034 return STATUS_ERROR(CameraService::ERROR_DISCONNECTED, "Camera device no longer alive");
1035 }
1036
1037 // Infer the surface info for deferred surface stream creation.
1038 width = outputConfiguration.getWidth();
1039 height = outputConfiguration.getHeight();
1040 surfaceType = outputConfiguration.getSurfaceType();
1041 format = HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED;
1042 dataSpace = android_dataspace_t::HAL_DATASPACE_UNKNOWN;
1043 // Hardcode consumer usage flags: SurfaceView--0x900, SurfaceTexture--0x100.
1044 consumerUsage = GraphicBuffer::USAGE_HW_TEXTURE;
1045 if (surfaceType == OutputConfiguration::SURFACE_TYPE_SURFACE_VIEW) {
1046 consumerUsage |= GraphicBuffer::USAGE_HW_COMPOSER;
1047 }
1048 int streamId = camera3::CAMERA3_STREAM_ID_INVALID;
Shuzhen Wang0129d522016-10-30 22:43:41 -07001049 std::vector<sp<Surface>> noSurface;
Emilian Peev40ead602017-09-26 15:46:36 +01001050 std::vector<int> surfaceIds;
Shuzhen Wangc28189a2017-11-27 23:05:10 -08001051 String8 physicalCameraId(outputConfiguration.getPhysicalCameraId());
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -08001052 const String8 &cameraIdUsed =
1053 physicalCameraId.size() != 0 ? physicalCameraId : mCameraIdStr;
1054 // Here, we override sensor pixel modes
1055 std::unordered_set<int32_t> overriddenSensorPixelModesUsed;
1056 const std::vector<int32_t> &sensorPixelModesUsed =
1057 outputConfiguration.getSensorPixelModesUsed();
Shuzhen Wangd4abdf72021-05-28 11:22:50 -07001058 if (SessionConfigurationUtils::checkAndOverrideSensorPixelModesUsed(
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -08001059 sensorPixelModesUsed, format, width, height, getStaticInfo(cameraIdUsed),
1060 /*allowRounding*/ false, &overriddenSensorPixelModesUsed) != OK) {
1061 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT,
1062 "sensor pixel modes used not valid for deferred stream");
1063 }
1064
Shuzhen Wang0129d522016-10-30 22:43:41 -07001065 err = mDevice->createStream(noSurface, /*hasDeferredConsumer*/true, width,
1066 height, format, dataSpace,
Emilian Peevf4816702020-04-03 15:44:51 -07001067 static_cast<camera_stream_rotation_t>(outputConfiguration.getRotation()),
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -08001068 &streamId, physicalCameraId,
1069 overriddenSensorPixelModesUsed,
1070 &surfaceIds,
Shuzhen Wangc28189a2017-11-27 23:05:10 -08001071 outputConfiguration.getSurfaceSetID(), isShared,
Emilian Peev2295df72021-11-12 18:14:10 -08001072 outputConfiguration.isMultiResolution(), consumerUsage,
Shuzhen Wangc8ab4522021-12-14 20:12:42 -08001073 outputConfiguration.getDynamicRangeProfile(),
Shuzhen Wang610d7b82022-02-08 14:37:22 -08001074 outputConfiguration.getStreamUseCase(),
1075 outputConfiguration.getMirrorMode());
Zhijun He5d677d12016-05-29 16:52:39 -07001076
1077 if (err != OK) {
1078 res = STATUS_ERROR_FMT(CameraService::ERROR_INVALID_OPERATION,
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -08001079 "Camera %s: Error creating output stream (%d x %d, fmt %x, dataSpace %x): %s (%d)",
1080 mCameraIdStr.string(), width, height, format, dataSpace, strerror(-err), err);
Zhijun He5d677d12016-05-29 16:52:39 -07001081 } else {
1082 // Can not add streamId to mStreamMap here, as the surface is deferred. Add it to
1083 // a separate list to track. Once the deferred surface is set, this id will be
1084 // relocated to mStreamMap.
1085 mDeferredStreams.push_back(streamId);
Shuzhen Wang758c2152017-01-10 18:26:18 -08001086 mStreamInfoMap.emplace(std::piecewise_construct, std::forward_as_tuple(streamId),
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -08001087 std::forward_as_tuple(width, height, format, dataSpace, consumerUsage,
Emilian Peev2295df72021-11-12 18:14:10 -08001088 overriddenSensorPixelModesUsed,
Shuzhen Wangc8ab4522021-12-14 20:12:42 -08001089 outputConfiguration.getDynamicRangeProfile(),
Shuzhen Wange4208922022-02-01 16:52:48 -08001090 outputConfiguration.getStreamUseCase(),
Shuzhen Wang610d7b82022-02-08 14:37:22 -08001091 outputConfiguration.getTimestampBase(),
1092 outputConfiguration.getMirrorMode()));
Shuzhen Wang758c2152017-01-10 18:26:18 -08001093
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -08001094 ALOGV("%s: Camera %s: Successfully created a new stream ID %d for a deferred surface"
Zhijun He5d677d12016-05-29 16:52:39 -07001095 " (%d x %d) stream with format 0x%x.",
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -08001096 __FUNCTION__, mCameraIdStr.string(), streamId, width, height, format);
Zhijun He5d677d12016-05-29 16:52:39 -07001097
1098 // Set transform flags to ensure preview to be rotated correctly.
Shuzhen Wang610d7b82022-02-08 14:37:22 -08001099 res = setStreamTransformLocked(streamId, outputConfiguration.getMirrorMode());
Zhijun He5d677d12016-05-29 16:52:39 -07001100
1101 *newStreamId = streamId;
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -08001102 // Fill in mHighResolutionCameraIdToStreamIdSet
1103 const char *cameraIdUsedCStr = cameraIdUsed.string();
1104 // Only needed for high resolution sensors
1105 if (mHighResolutionSensors.find(cameraIdUsedCStr) !=
1106 mHighResolutionSensors.end()) {
1107 mHighResolutionCameraIdToStreamIdSet[cameraIdUsed.string()].insert(streamId);
1108 }
Zhijun He5d677d12016-05-29 16:52:39 -07001109 }
1110 return res;
1111}
1112
Shuzhen Wang610d7b82022-02-08 14:37:22 -08001113binder::Status CameraDeviceClient::setStreamTransformLocked(int streamId, int mirrorMode) {
Zhijun He5d677d12016-05-29 16:52:39 -07001114 int32_t transform = 0;
1115 status_t err;
1116 binder::Status res;
1117
1118 if (!mDevice.get()) {
1119 return STATUS_ERROR(CameraService::ERROR_DISCONNECTED, "Camera device no longer alive");
1120 }
1121
Shuzhen Wang610d7b82022-02-08 14:37:22 -08001122 err = getRotationTransformLocked(mirrorMode, &transform);
Zhijun He5d677d12016-05-29 16:52:39 -07001123 if (err != OK) {
1124 // Error logged by getRotationTransformLocked.
1125 return STATUS_ERROR(CameraService::ERROR_INVALID_OPERATION,
1126 "Unable to calculate rotation transform for new stream");
1127 }
1128
1129 err = mDevice->setStreamTransform(streamId, transform);
1130 if (err != OK) {
1131 String8 msg = String8::format("Failed to set stream transform (stream id %d)",
1132 streamId);
1133 ALOGE("%s: %s", __FUNCTION__, msg.string());
1134 return STATUS_ERROR(CameraService::ERROR_INVALID_OPERATION, msg.string());
1135 }
1136
1137 return res;
1138}
Ruben Brunkbba75572014-11-20 17:29:50 -08001139
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001140binder::Status CameraDeviceClient::createInputStream(
Shuzhen Wang83bff122020-11-20 15:51:39 -08001141 int width, int height, int format, bool isMultiResolution,
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001142 /*out*/
1143 int32_t* newStreamId) {
Chien-Yu Chen618ff8a2015-03-13 11:27:17 -07001144
1145 ATRACE_CALL();
Shuzhen Wang83bff122020-11-20 15:51:39 -08001146 ALOGV("%s (w = %d, h = %d, f = 0x%x, isMultiResolution %d)", __FUNCTION__,
1147 width, height, format, isMultiResolution);
Chien-Yu Chen618ff8a2015-03-13 11:27:17 -07001148
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001149 binder::Status res;
1150 if (!(res = checkPidStatus(__FUNCTION__)).isOk()) return res;
Chien-Yu Chen618ff8a2015-03-13 11:27:17 -07001151
1152 Mutex::Autolock icl(mBinderSerializationLock);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001153
1154 if (!mDevice.get()) {
1155 return STATUS_ERROR(CameraService::ERROR_DISCONNECTED, "Camera device no longer alive");
1156 }
Chien-Yu Chen618ff8a2015-03-13 11:27:17 -07001157
1158 if (mInputStream.configured) {
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -08001159 String8 msg = String8::format("Camera %s: Already has an input stream "
Yi Kong0f414de2017-12-15 13:48:50 -08001160 "configured (ID %d)", mCameraIdStr.string(), mInputStream.id);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001161 ALOGE("%s: %s", __FUNCTION__, msg.string() );
1162 return STATUS_ERROR(CameraService::ERROR_ALREADY_EXISTS, msg.string());
Chien-Yu Chen618ff8a2015-03-13 11:27:17 -07001163 }
1164
1165 int streamId = -1;
Shuzhen Wang83bff122020-11-20 15:51:39 -08001166 status_t err = mDevice->createInputStream(width, height, format, isMultiResolution, &streamId);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001167 if (err == OK) {
Chien-Yu Chen618ff8a2015-03-13 11:27:17 -07001168 mInputStream.configured = true;
1169 mInputStream.width = width;
1170 mInputStream.height = height;
1171 mInputStream.format = format;
1172 mInputStream.id = streamId;
1173
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -08001174 ALOGV("%s: Camera %s: Successfully created a new input stream ID %d",
1175 __FUNCTION__, mCameraIdStr.string(), streamId);
Chien-Yu Chen618ff8a2015-03-13 11:27:17 -07001176
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001177 *newStreamId = streamId;
1178 } else {
1179 res = STATUS_ERROR_FMT(CameraService::ERROR_INVALID_OPERATION,
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -08001180 "Camera %s: Error creating new input stream: %s (%d)", mCameraIdStr.string(),
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001181 strerror(-err), err);
Chien-Yu Chen618ff8a2015-03-13 11:27:17 -07001182 }
1183
1184 return res;
1185}
1186
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001187binder::Status CameraDeviceClient::getInputSurface(/*out*/ view::Surface *inputSurface) {
Chien-Yu Chen618ff8a2015-03-13 11:27:17 -07001188
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001189 binder::Status res;
1190 if (!(res = checkPidStatus(__FUNCTION__)).isOk()) return res;
1191
1192 if (inputSurface == NULL) {
1193 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, "Null input surface");
Chien-Yu Chen618ff8a2015-03-13 11:27:17 -07001194 }
1195
1196 Mutex::Autolock icl(mBinderSerializationLock);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001197 if (!mDevice.get()) {
1198 return STATUS_ERROR(CameraService::ERROR_DISCONNECTED, "Camera device no longer alive");
1199 }
1200 sp<IGraphicBufferProducer> producer;
1201 status_t err = mDevice->getInputBufferProducer(&producer);
1202 if (err != OK) {
1203 res = STATUS_ERROR_FMT(CameraService::ERROR_INVALID_OPERATION,
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -08001204 "Camera %s: Error getting input Surface: %s (%d)",
1205 mCameraIdStr.string(), strerror(-err), err);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001206 } else {
1207 inputSurface->name = String16("CameraInput");
1208 inputSurface->graphicBufferProducer = producer;
1209 }
1210 return res;
Chien-Yu Chen618ff8a2015-03-13 11:27:17 -07001211}
1212
Emilian Peev40ead602017-09-26 15:46:36 +01001213binder::Status CameraDeviceClient::updateOutputConfiguration(int streamId,
1214 const hardware::camera2::params::OutputConfiguration &outputConfiguration) {
1215 ATRACE_CALL();
1216
1217 binder::Status res;
1218 if (!(res = checkPidStatus(__FUNCTION__)).isOk()) return res;
1219
1220 Mutex::Autolock icl(mBinderSerializationLock);
1221
1222 if (!mDevice.get()) {
1223 return STATUS_ERROR(CameraService::ERROR_DISCONNECTED, "Camera device no longer alive");
1224 }
1225
1226 const std::vector<sp<IGraphicBufferProducer> >& bufferProducers =
1227 outputConfiguration.getGraphicBufferProducers();
Shuzhen Wang2e7f58f2018-07-11 14:00:29 -07001228 String8 physicalCameraId(outputConfiguration.getPhysicalCameraId());
1229
Emilian Peev40ead602017-09-26 15:46:36 +01001230 auto producerCount = bufferProducers.size();
1231 if (producerCount == 0) {
1232 ALOGE("%s: bufferProducers must not be empty", __FUNCTION__);
1233 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT,
1234 "bufferProducers must not be empty");
1235 }
1236
1237 // The first output is the one associated with the output configuration.
1238 // It should always be present, valid and the corresponding stream id should match.
1239 sp<IBinder> binder = IInterface::asBinder(bufferProducers[0]);
1240 ssize_t index = mStreamMap.indexOfKey(binder);
1241 if (index == NAME_NOT_FOUND) {
1242 ALOGE("%s: Outputconfiguration is invalid", __FUNCTION__);
1243 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT,
1244 "OutputConfiguration is invalid");
1245 }
1246 if (mStreamMap.valueFor(binder).streamId() != streamId) {
1247 ALOGE("%s: Stream Id: %d provided doesn't match the id: %d in the stream map",
1248 __FUNCTION__, streamId, mStreamMap.valueFor(binder).streamId());
1249 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT,
1250 "Stream id is invalid");
1251 }
1252
1253 std::vector<size_t> removedSurfaceIds;
1254 std::vector<sp<IBinder>> removedOutputs;
1255 std::vector<sp<Surface>> newOutputs;
1256 std::vector<OutputStreamInfo> streamInfos;
1257 KeyedVector<sp<IBinder>, sp<IGraphicBufferProducer>> newOutputsMap;
1258 for (auto &it : bufferProducers) {
1259 newOutputsMap.add(IInterface::asBinder(it), it);
1260 }
1261
1262 for (size_t i = 0; i < mStreamMap.size(); i++) {
1263 ssize_t idx = newOutputsMap.indexOfKey(mStreamMap.keyAt(i));
1264 if (idx == NAME_NOT_FOUND) {
1265 if (mStreamMap[i].streamId() == streamId) {
1266 removedSurfaceIds.push_back(mStreamMap[i].surfaceId());
1267 removedOutputs.push_back(mStreamMap.keyAt(i));
1268 }
1269 } else {
1270 if (mStreamMap[i].streamId() != streamId) {
1271 ALOGE("%s: Output surface already part of a different stream", __FUNCTION__);
1272 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT,
1273 "Target Surface is invalid");
1274 }
1275 newOutputsMap.removeItemsAt(idx);
1276 }
1277 }
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -08001278 const std::vector<int32_t> &sensorPixelModesUsed =
1279 outputConfiguration.getSensorPixelModesUsed();
Shuzhen Wang8ed1e872022-03-08 16:34:33 -08001280 int64_t streamUseCase = outputConfiguration.getStreamUseCase();
Shuzhen Wange4208922022-02-01 16:52:48 -08001281 int timestampBase = outputConfiguration.getTimestampBase();
Emilian Peevc81a7592022-02-14 17:38:18 -08001282 int64_t dynamicRangeProfile = outputConfiguration.getDynamicRangeProfile();
Shuzhen Wang610d7b82022-02-08 14:37:22 -08001283 int mirrorMode = outputConfiguration.getMirrorMode();
Emilian Peev2295df72021-11-12 18:14:10 -08001284
Emilian Peev40ead602017-09-26 15:46:36 +01001285 for (size_t i = 0; i < newOutputsMap.size(); i++) {
1286 OutputStreamInfo outInfo;
1287 sp<Surface> surface;
Shuzhen Wangd4abdf72021-05-28 11:22:50 -07001288 res = SessionConfigurationUtils::createSurfaceFromGbp(outInfo,
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -08001289 /*isStreamInfoValid*/ false, surface, newOutputsMap.valueAt(i), mCameraIdStr,
Shuzhen Wangc8ab4522021-12-14 20:12:42 -08001290 mDevice->infoPhysical(physicalCameraId), sensorPixelModesUsed, dynamicRangeProfile,
Shuzhen Wang610d7b82022-02-08 14:37:22 -08001291 streamUseCase, timestampBase, mirrorMode);
Emilian Peev40ead602017-09-26 15:46:36 +01001292 if (!res.isOk())
1293 return res;
1294
Emilian Peev40ead602017-09-26 15:46:36 +01001295 streamInfos.push_back(outInfo);
1296 newOutputs.push_back(surface);
1297 }
1298
1299 //Trivial case no changes required
1300 if (removedSurfaceIds.empty() && newOutputs.empty()) {
1301 return binder::Status::ok();
1302 }
1303
1304 KeyedVector<sp<Surface>, size_t> outputMap;
1305 auto ret = mDevice->updateStream(streamId, newOutputs, streamInfos, removedSurfaceIds,
1306 &outputMap);
1307 if (ret != OK) {
1308 switch (ret) {
1309 case NAME_NOT_FOUND:
1310 case BAD_VALUE:
1311 case -EBUSY:
1312 res = STATUS_ERROR_FMT(CameraService::ERROR_ILLEGAL_ARGUMENT,
1313 "Camera %s: Error updating stream: %s (%d)",
1314 mCameraIdStr.string(), strerror(ret), ret);
1315 break;
1316 default:
1317 res = STATUS_ERROR_FMT(CameraService::ERROR_INVALID_OPERATION,
1318 "Camera %s: Error updating stream: %s (%d)",
1319 mCameraIdStr.string(), strerror(ret), ret);
1320 break;
1321 }
1322 } else {
1323 for (const auto &it : removedOutputs) {
1324 mStreamMap.removeItem(it);
1325 }
1326
1327 for (size_t i = 0; i < outputMap.size(); i++) {
1328 mStreamMap.add(IInterface::asBinder(outputMap.keyAt(i)->getIGraphicBufferProducer()),
1329 StreamSurfaceId(streamId, outputMap.valueAt(i)));
1330 }
1331
Yin-Chia Yeh4dfa4cc2017-11-10 20:00:09 -08001332 mConfiguredOutputs.replaceValueFor(streamId, outputConfiguration);
1333
Emilian Peev40ead602017-09-26 15:46:36 +01001334 ALOGV("%s: Camera %s: Successful stream ID %d update",
1335 __FUNCTION__, mCameraIdStr.string(), streamId);
1336 }
1337
1338 return res;
1339}
1340
Igor Murashkine7ee7632013-06-11 18:10:18 -07001341// Create a request object from a template.
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001342binder::Status CameraDeviceClient::createDefaultRequest(int templateId,
1343 /*out*/
1344 hardware::camera2::impl::CameraMetadataNative* request)
Igor Murashkine7ee7632013-06-11 18:10:18 -07001345{
1346 ATRACE_CALL();
1347 ALOGV("%s (templateId = 0x%x)", __FUNCTION__, templateId);
1348
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001349 binder::Status res;
1350 if (!(res = checkPidStatus(__FUNCTION__)).isOk()) return res;
Igor Murashkine7ee7632013-06-11 18:10:18 -07001351
1352 Mutex::Autolock icl(mBinderSerializationLock);
1353
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001354 if (!mDevice.get()) {
1355 return STATUS_ERROR(CameraService::ERROR_DISCONNECTED, "Camera device no longer alive");
1356 }
Igor Murashkine7ee7632013-06-11 18:10:18 -07001357
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001358 status_t err;
Emilian Peevf4816702020-04-03 15:44:51 -07001359 camera_request_template_t tempId = camera_request_template_t::CAMERA_TEMPLATE_COUNT;
1360 if (!(res = mapRequestTemplate(templateId, &tempId)).isOk()) return res;
1361
1362 CameraMetadata metadata;
1363 if ( (err = mDevice->createDefaultRequest(tempId, &metadata) ) == OK &&
Igor Murashkine7ee7632013-06-11 18:10:18 -07001364 request != NULL) {
1365
1366 request->swap(metadata);
Chien-Yu Chen9cd14022016-03-09 12:21:01 -08001367 } else if (err == BAD_VALUE) {
1368 res = STATUS_ERROR_FMT(CameraService::ERROR_ILLEGAL_ARGUMENT,
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -08001369 "Camera %s: Template ID %d is invalid or not supported: %s (%d)",
1370 mCameraIdStr.string(), templateId, strerror(-err), err);
Chien-Yu Chen9cd14022016-03-09 12:21:01 -08001371
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001372 } else {
1373 res = STATUS_ERROR_FMT(CameraService::ERROR_INVALID_OPERATION,
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -08001374 "Camera %s: Error creating default request for template %d: %s (%d)",
1375 mCameraIdStr.string(), templateId, strerror(-err), err);
Igor Murashkine7ee7632013-06-11 18:10:18 -07001376 }
Igor Murashkine7ee7632013-06-11 18:10:18 -07001377 return res;
1378}
1379
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001380binder::Status CameraDeviceClient::getCameraInfo(
1381 /*out*/
1382 hardware::camera2::impl::CameraMetadataNative* info)
Igor Murashkine7ee7632013-06-11 18:10:18 -07001383{
1384 ATRACE_CALL();
1385 ALOGV("%s", __FUNCTION__);
1386
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001387 binder::Status res;
Igor Murashkine7ee7632013-06-11 18:10:18 -07001388
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001389 if (!(res = checkPidStatus(__FUNCTION__)).isOk()) return res;
Igor Murashkine7ee7632013-06-11 18:10:18 -07001390
1391 Mutex::Autolock icl(mBinderSerializationLock);
1392
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001393 if (!mDevice.get()) {
1394 return STATUS_ERROR(CameraService::ERROR_DISCONNECTED, "Camera device no longer alive");
1395 }
Igor Murashkine7ee7632013-06-11 18:10:18 -07001396
Igor Murashkin099b4572013-07-12 17:52:16 -07001397 if (info != NULL) {
1398 *info = mDevice->info(); // static camera metadata
1399 // TODO: merge with device-specific camera metadata
1400 }
Igor Murashkine7ee7632013-06-11 18:10:18 -07001401
1402 return res;
1403}
1404
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001405binder::Status CameraDeviceClient::waitUntilIdle()
Zhijun He2ab500c2013-07-23 08:02:53 -07001406{
1407 ATRACE_CALL();
1408 ALOGV("%s", __FUNCTION__);
1409
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001410 binder::Status res;
1411 if (!(res = checkPidStatus(__FUNCTION__)).isOk()) return res;
Zhijun He2ab500c2013-07-23 08:02:53 -07001412
1413 Mutex::Autolock icl(mBinderSerializationLock);
1414
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001415 if (!mDevice.get()) {
1416 return STATUS_ERROR(CameraService::ERROR_DISCONNECTED, "Camera device no longer alive");
1417 }
Zhijun He2ab500c2013-07-23 08:02:53 -07001418
1419 // FIXME: Also need check repeating burst.
Shuzhen Wangc9ca6782016-04-26 13:40:31 -07001420 Mutex::Autolock idLock(mStreamingRequestIdLock);
Chien-Yu Chene8c535e2016-04-14 12:18:26 -07001421 if (mStreamingRequestId != REQUEST_ID_NONE) {
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001422 String8 msg = String8::format(
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -08001423 "Camera %s: Try to waitUntilIdle when there are active streaming requests",
1424 mCameraIdStr.string());
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001425 ALOGE("%s: %s", __FUNCTION__, msg.string());
1426 return STATUS_ERROR(CameraService::ERROR_INVALID_OPERATION, msg.string());
Zhijun He2ab500c2013-07-23 08:02:53 -07001427 }
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001428 status_t err = mDevice->waitUntilDrained();
1429 if (err != OK) {
1430 res = STATUS_ERROR_FMT(CameraService::ERROR_INVALID_OPERATION,
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -08001431 "Camera %s: Error waiting to drain: %s (%d)",
1432 mCameraIdStr.string(), strerror(-err), err);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001433 }
Zhijun He2ab500c2013-07-23 08:02:53 -07001434 ALOGV("%s Done", __FUNCTION__);
Zhijun He2ab500c2013-07-23 08:02:53 -07001435 return res;
1436}
1437
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001438binder::Status CameraDeviceClient::flush(
1439 /*out*/
1440 int64_t* lastFrameNumber) {
Eino-Ville Talvalaabaa51d2013-08-14 11:37:00 -07001441 ATRACE_CALL();
1442 ALOGV("%s", __FUNCTION__);
1443
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001444 binder::Status res;
1445 if (!(res = checkPidStatus(__FUNCTION__)).isOk()) return res;
Eino-Ville Talvalaabaa51d2013-08-14 11:37:00 -07001446
1447 Mutex::Autolock icl(mBinderSerializationLock);
1448
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001449 if (!mDevice.get()) {
1450 return STATUS_ERROR(CameraService::ERROR_DISCONNECTED, "Camera device no longer alive");
1451 }
Eino-Ville Talvalaabaa51d2013-08-14 11:37:00 -07001452
Shuzhen Wangc9ca6782016-04-26 13:40:31 -07001453 Mutex::Autolock idLock(mStreamingRequestIdLock);
Chien-Yu Chene8c535e2016-04-14 12:18:26 -07001454 mStreamingRequestId = REQUEST_ID_NONE;
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001455 status_t err = mDevice->flush(lastFrameNumber);
1456 if (err != OK) {
1457 res = STATUS_ERROR_FMT(CameraService::ERROR_INVALID_OPERATION,
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -08001458 "Camera %s: Error flushing device: %s (%d)", mCameraIdStr.string(), strerror(-err), err);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001459 }
1460 return res;
Eino-Ville Talvalaabaa51d2013-08-14 11:37:00 -07001461}
1462
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001463binder::Status CameraDeviceClient::prepare(int streamId) {
Eino-Ville Talvala4d44cad2015-04-11 13:15:45 -07001464 ATRACE_CALL();
1465 ALOGV("%s", __FUNCTION__);
1466
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001467 binder::Status res;
1468 if (!(res = checkPidStatus(__FUNCTION__)).isOk()) return res;
Eino-Ville Talvala4d44cad2015-04-11 13:15:45 -07001469
1470 Mutex::Autolock icl(mBinderSerializationLock);
1471
1472 // Guard against trying to prepare non-created streams
1473 ssize_t index = NAME_NOT_FOUND;
1474 for (size_t i = 0; i < mStreamMap.size(); ++i) {
Shuzhen Wang0129d522016-10-30 22:43:41 -07001475 if (streamId == mStreamMap.valueAt(i).streamId()) {
Eino-Ville Talvala4d44cad2015-04-11 13:15:45 -07001476 index = i;
1477 break;
1478 }
1479 }
1480
1481 if (index == NAME_NOT_FOUND) {
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -08001482 String8 msg = String8::format("Camera %s: Invalid stream ID (%d) specified, no stream "
1483 "with that ID exists", mCameraIdStr.string(), streamId);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001484 ALOGW("%s: %s", __FUNCTION__, msg.string());
1485 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
Eino-Ville Talvala4d44cad2015-04-11 13:15:45 -07001486 }
1487
Eino-Ville Talvala261394e2015-05-13 14:28:38 -07001488 // Also returns BAD_VALUE if stream ID was not valid, or stream already
1489 // has been used
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001490 status_t err = mDevice->prepare(streamId);
1491 if (err == BAD_VALUE) {
1492 res = STATUS_ERROR_FMT(CameraService::ERROR_ILLEGAL_ARGUMENT,
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -08001493 "Camera %s: Stream %d has already been used, and cannot be prepared",
1494 mCameraIdStr.string(), streamId);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001495 } else if (err != OK) {
1496 res = STATUS_ERROR_FMT(CameraService::ERROR_INVALID_OPERATION,
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -08001497 "Camera %s: Error preparing stream %d: %s (%d)", mCameraIdStr.string(), streamId,
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001498 strerror(-err), err);
1499 }
Eino-Ville Talvala4d44cad2015-04-11 13:15:45 -07001500 return res;
1501}
1502
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001503binder::Status CameraDeviceClient::prepare2(int maxCount, int streamId) {
Ruben Brunkc78ac262015-08-13 17:58:46 -07001504 ATRACE_CALL();
1505 ALOGV("%s", __FUNCTION__);
1506
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001507 binder::Status res;
1508 if (!(res = checkPidStatus(__FUNCTION__)).isOk()) return res;
Ruben Brunkc78ac262015-08-13 17:58:46 -07001509
1510 Mutex::Autolock icl(mBinderSerializationLock);
1511
1512 // Guard against trying to prepare non-created streams
1513 ssize_t index = NAME_NOT_FOUND;
1514 for (size_t i = 0; i < mStreamMap.size(); ++i) {
Shuzhen Wang0129d522016-10-30 22:43:41 -07001515 if (streamId == mStreamMap.valueAt(i).streamId()) {
Ruben Brunkc78ac262015-08-13 17:58:46 -07001516 index = i;
1517 break;
1518 }
1519 }
1520
1521 if (index == NAME_NOT_FOUND) {
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -08001522 String8 msg = String8::format("Camera %s: Invalid stream ID (%d) specified, no stream "
1523 "with that ID exists", mCameraIdStr.string(), streamId);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001524 ALOGW("%s: %s", __FUNCTION__, msg.string());
1525 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
Ruben Brunkc78ac262015-08-13 17:58:46 -07001526 }
1527
1528 if (maxCount <= 0) {
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -08001529 String8 msg = String8::format("Camera %s: maxCount (%d) must be greater than 0",
1530 mCameraIdStr.string(), maxCount);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001531 ALOGE("%s: %s", __FUNCTION__, msg.string());
1532 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
Ruben Brunkc78ac262015-08-13 17:58:46 -07001533 }
1534
1535 // Also returns BAD_VALUE if stream ID was not valid, or stream already
1536 // has been used
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001537 status_t err = mDevice->prepare(maxCount, streamId);
1538 if (err == BAD_VALUE) {
1539 res = STATUS_ERROR_FMT(CameraService::ERROR_ILLEGAL_ARGUMENT,
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -08001540 "Camera %s: Stream %d has already been used, and cannot be prepared",
1541 mCameraIdStr.string(), streamId);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001542 } else if (err != OK) {
1543 res = STATUS_ERROR_FMT(CameraService::ERROR_INVALID_OPERATION,
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -08001544 "Camera %s: Error preparing stream %d: %s (%d)", mCameraIdStr.string(), streamId,
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001545 strerror(-err), err);
1546 }
Ruben Brunkc78ac262015-08-13 17:58:46 -07001547
1548 return res;
1549}
1550
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001551binder::Status CameraDeviceClient::tearDown(int streamId) {
Eino-Ville Talvalab25e3c82015-07-15 16:04:27 -07001552 ATRACE_CALL();
1553 ALOGV("%s", __FUNCTION__);
1554
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001555 binder::Status res;
1556 if (!(res = checkPidStatus(__FUNCTION__)).isOk()) return res;
Eino-Ville Talvalab25e3c82015-07-15 16:04:27 -07001557
1558 Mutex::Autolock icl(mBinderSerializationLock);
1559
1560 // Guard against trying to prepare non-created streams
1561 ssize_t index = NAME_NOT_FOUND;
1562 for (size_t i = 0; i < mStreamMap.size(); ++i) {
Shuzhen Wang0129d522016-10-30 22:43:41 -07001563 if (streamId == mStreamMap.valueAt(i).streamId()) {
Eino-Ville Talvalab25e3c82015-07-15 16:04:27 -07001564 index = i;
1565 break;
1566 }
1567 }
1568
1569 if (index == NAME_NOT_FOUND) {
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -08001570 String8 msg = String8::format("Camera %s: Invalid stream ID (%d) specified, no stream "
1571 "with that ID exists", mCameraIdStr.string(), streamId);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001572 ALOGW("%s: %s", __FUNCTION__, msg.string());
1573 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
Eino-Ville Talvalab25e3c82015-07-15 16:04:27 -07001574 }
1575
1576 // Also returns BAD_VALUE if stream ID was not valid or if the stream is in
1577 // use
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001578 status_t err = mDevice->tearDown(streamId);
1579 if (err == BAD_VALUE) {
1580 res = STATUS_ERROR_FMT(CameraService::ERROR_ILLEGAL_ARGUMENT,
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -08001581 "Camera %s: Stream %d is still in use, cannot be torn down",
1582 mCameraIdStr.string(), streamId);
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001583 } else if (err != OK) {
1584 res = STATUS_ERROR_FMT(CameraService::ERROR_INVALID_OPERATION,
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -08001585 "Camera %s: Error tearing down stream %d: %s (%d)", mCameraIdStr.string(), streamId,
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001586 strerror(-err), err);
1587 }
Eino-Ville Talvalab25e3c82015-07-15 16:04:27 -07001588
1589 return res;
1590}
1591
Shuzhen Wang758c2152017-01-10 18:26:18 -08001592binder::Status CameraDeviceClient::finalizeOutputConfigurations(int32_t streamId,
Zhijun He5d677d12016-05-29 16:52:39 -07001593 const hardware::camera2::params::OutputConfiguration &outputConfiguration) {
1594 ATRACE_CALL();
1595
1596 binder::Status res;
1597 if (!(res = checkPidStatus(__FUNCTION__)).isOk()) return res;
1598
1599 Mutex::Autolock icl(mBinderSerializationLock);
1600
Shuzhen Wang0129d522016-10-30 22:43:41 -07001601 const std::vector<sp<IGraphicBufferProducer> >& bufferProducers =
1602 outputConfiguration.getGraphicBufferProducers();
Shuzhen Wang2e7f58f2018-07-11 14:00:29 -07001603 String8 physicalId(outputConfiguration.getPhysicalCameraId());
Zhijun He5d677d12016-05-29 16:52:39 -07001604
Shuzhen Wang0129d522016-10-30 22:43:41 -07001605 if (bufferProducers.size() == 0) {
1606 ALOGE("%s: bufferProducers must not be empty", __FUNCTION__);
Zhijun He5d677d12016-05-29 16:52:39 -07001607 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, "Target Surface is invalid");
1608 }
Shuzhen Wang0129d522016-10-30 22:43:41 -07001609
Shuzhen Wang758c2152017-01-10 18:26:18 -08001610 // streamId should be in mStreamMap if this stream already has a surface attached
1611 // to it. Otherwise, it should be in mDeferredStreams.
1612 bool streamIdConfigured = false;
1613 ssize_t deferredStreamIndex = NAME_NOT_FOUND;
1614 for (size_t i = 0; i < mStreamMap.size(); i++) {
1615 if (mStreamMap.valueAt(i).streamId() == streamId) {
1616 streamIdConfigured = true;
1617 break;
1618 }
Zhijun He5d677d12016-05-29 16:52:39 -07001619 }
Shuzhen Wang758c2152017-01-10 18:26:18 -08001620 for (size_t i = 0; i < mDeferredStreams.size(); i++) {
1621 if (streamId == mDeferredStreams[i]) {
1622 deferredStreamIndex = i;
1623 break;
Shuzhen Wang0129d522016-10-30 22:43:41 -07001624 }
1625
Shuzhen Wang758c2152017-01-10 18:26:18 -08001626 }
1627 if (deferredStreamIndex == NAME_NOT_FOUND && !streamIdConfigured) {
1628 String8 msg = String8::format("Camera %s: deferred surface is set to a unknown stream"
1629 "(ID %d)", mCameraIdStr.string(), streamId);
1630 ALOGW("%s: %s", __FUNCTION__, msg.string());
1631 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
Zhijun He5d677d12016-05-29 16:52:39 -07001632 }
1633
Shuzhen Wang88fd0052017-02-09 16:40:07 -08001634 if (mStreamInfoMap[streamId].finalized) {
1635 String8 msg = String8::format("Camera %s: finalizeOutputConfigurations has been called"
1636 " on stream ID %d", mCameraIdStr.string(), streamId);
1637 ALOGW("%s: %s", __FUNCTION__, msg.string());
1638 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
1639 }
1640
Zhijun He5d677d12016-05-29 16:52:39 -07001641 if (!mDevice.get()) {
1642 return STATUS_ERROR(CameraService::ERROR_DISCONNECTED, "Camera device no longer alive");
1643 }
1644
Shuzhen Wang758c2152017-01-10 18:26:18 -08001645 std::vector<sp<Surface>> consumerSurfaces;
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -08001646 const std::vector<int32_t> &sensorPixelModesUsed =
1647 outputConfiguration.getSensorPixelModesUsed();
Emilian Peevc81a7592022-02-14 17:38:18 -08001648 int64_t dynamicRangeProfile = outputConfiguration.getDynamicRangeProfile();
Shuzhen Wang8ed1e872022-03-08 16:34:33 -08001649 int64_t streamUseCase= outputConfiguration.getStreamUseCase();
Shuzhen Wange4208922022-02-01 16:52:48 -08001650 int timestampBase = outputConfiguration.getTimestampBase();
Shuzhen Wang610d7b82022-02-08 14:37:22 -08001651 int mirrorMode = outputConfiguration.getMirrorMode();
Shuzhen Wang758c2152017-01-10 18:26:18 -08001652 for (auto& bufferProducer : bufferProducers) {
1653 // Don't create multiple streams for the same target surface
Zhijun He5d677d12016-05-29 16:52:39 -07001654 ssize_t index = mStreamMap.indexOfKey(IInterface::asBinder(bufferProducer));
1655 if (index != NAME_NOT_FOUND) {
Shuzhen Wang758c2152017-01-10 18:26:18 -08001656 ALOGV("Camera %s: Surface already has a stream created "
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -08001657 " for it (ID %zd)", mCameraIdStr.string(), index);
Shuzhen Wang758c2152017-01-10 18:26:18 -08001658 continue;
Zhijun He5d677d12016-05-29 16:52:39 -07001659 }
Shuzhen Wang758c2152017-01-10 18:26:18 -08001660
1661 sp<Surface> surface;
Shuzhen Wangd4abdf72021-05-28 11:22:50 -07001662 res = SessionConfigurationUtils::createSurfaceFromGbp(mStreamInfoMap[streamId],
Colin Crossb8a9dbb2020-08-27 04:12:26 +00001663 true /*isStreamInfoValid*/, surface, bufferProducer, mCameraIdStr,
Shuzhen Wangc8ab4522021-12-14 20:12:42 -08001664 mDevice->infoPhysical(physicalId), sensorPixelModesUsed, dynamicRangeProfile,
Shuzhen Wang610d7b82022-02-08 14:37:22 -08001665 streamUseCase, timestampBase, mirrorMode);
Shuzhen Wang758c2152017-01-10 18:26:18 -08001666
1667 if (!res.isOk())
1668 return res;
1669
1670 consumerSurfaces.push_back(surface);
Zhijun He5d677d12016-05-29 16:52:39 -07001671 }
1672
Shuzhen Wanga81ce342017-04-13 15:18:36 -07001673 // Gracefully handle case where finalizeOutputConfigurations is called
1674 // without any new surface.
1675 if (consumerSurfaces.size() == 0) {
1676 mStreamInfoMap[streamId].finalized = true;
1677 return res;
1678 }
1679
Zhijun He5d677d12016-05-29 16:52:39 -07001680 // Finish the deferred stream configuration with the surface.
Shuzhen Wang758c2152017-01-10 18:26:18 -08001681 status_t err;
Emilian Peev40ead602017-09-26 15:46:36 +01001682 std::vector<int> consumerSurfaceIds;
1683 err = mDevice->setConsumerSurfaces(streamId, consumerSurfaces, &consumerSurfaceIds);
Zhijun He5d677d12016-05-29 16:52:39 -07001684 if (err == OK) {
Shuzhen Wang758c2152017-01-10 18:26:18 -08001685 for (size_t i = 0; i < consumerSurfaces.size(); i++) {
1686 sp<IBinder> binder = IInterface::asBinder(
1687 consumerSurfaces[i]->getIGraphicBufferProducer());
Emilian Peev40ead602017-09-26 15:46:36 +01001688 ALOGV("%s: mStreamMap add binder %p streamId %d, surfaceId %d", __FUNCTION__,
Shuzhen Wang758c2152017-01-10 18:26:18 -08001689 binder.get(), streamId, consumerSurfaceIds[i]);
1690 mStreamMap.add(binder, StreamSurfaceId(streamId, consumerSurfaceIds[i]));
1691 }
1692 if (deferredStreamIndex != NAME_NOT_FOUND) {
1693 mDeferredStreams.removeItemsAt(deferredStreamIndex);
Shuzhen Wang0129d522016-10-30 22:43:41 -07001694 }
Shuzhen Wang88fd0052017-02-09 16:40:07 -08001695 mStreamInfoMap[streamId].finalized = true;
Yin-Chia Yeh4dfa4cc2017-11-10 20:00:09 -08001696 mConfiguredOutputs.replaceValueFor(streamId, outputConfiguration);
Zhijun He5d677d12016-05-29 16:52:39 -07001697 } else if (err == NO_INIT) {
1698 res = STATUS_ERROR_FMT(CameraService::ERROR_ILLEGAL_ARGUMENT,
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -08001699 "Camera %s: Deferred surface is invalid: %s (%d)",
1700 mCameraIdStr.string(), strerror(-err), err);
Zhijun He5d677d12016-05-29 16:52:39 -07001701 } else {
1702 res = STATUS_ERROR_FMT(CameraService::ERROR_INVALID_OPERATION,
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -08001703 "Camera %s: Error setting output stream deferred surface: %s (%d)",
1704 mCameraIdStr.string(), strerror(-err), err);
Zhijun He5d677d12016-05-29 16:52:39 -07001705 }
1706
1707 return res;
1708}
1709
Yin-Chia Yehcfab4e12019-09-09 13:08:28 -07001710binder::Status CameraDeviceClient::setCameraAudioRestriction(int32_t mode) {
Yin-Chia Yehdba03232019-08-19 15:54:28 -07001711 ATRACE_CALL();
1712 binder::Status res;
1713 if (!(res = checkPidStatus(__FUNCTION__)).isOk()) return res;
1714
1715 if (!isValidAudioRestriction(mode)) {
1716 String8 msg = String8::format("Camera %s: invalid audio restriction mode %d",
1717 mCameraIdStr.string(), mode);
1718 ALOGW("%s: %s", __FUNCTION__, msg.string());
1719 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
1720 }
1721
1722 Mutex::Autolock icl(mBinderSerializationLock);
Yin-Chia Yehcfab4e12019-09-09 13:08:28 -07001723 BasicClient::setAudioRestriction(mode);
1724 return binder::Status::ok();
1725}
1726
1727binder::Status CameraDeviceClient::getGlobalAudioRestriction(/*out*/ int32_t* outMode) {
1728 ATRACE_CALL();
1729 binder::Status res;
1730 if (!(res = checkPidStatus(__FUNCTION__)).isOk()) return res;
1731 Mutex::Autolock icl(mBinderSerializationLock);
Yin-Chia Yehdba03232019-08-19 15:54:28 -07001732 if (outMode != nullptr) {
Yin-Chia Yehcfab4e12019-09-09 13:08:28 -07001733 *outMode = BasicClient::getServiceAudioRestriction();
Yin-Chia Yehdba03232019-08-19 15:54:28 -07001734 }
1735 return binder::Status::ok();
1736}
1737
Ravneetaeb20dc2022-03-30 05:33:03 +00001738status_t CameraDeviceClient::setCameraServiceWatchdog(bool enabled) {
1739 return mDevice->setCameraServiceWatchdog(enabled);
1740}
1741
Eino-Ville Talvalaf2e37092020-01-07 15:32:32 -08001742status_t CameraDeviceClient::setRotateAndCropOverride(uint8_t rotateAndCrop) {
1743 if (rotateAndCrop > ANDROID_SCALER_ROTATE_AND_CROP_AUTO) return BAD_VALUE;
1744
1745 return mDevice->setRotateAndCropAutoBehavior(
1746 static_cast<camera_metadata_enum_android_scaler_rotate_and_crop_t>(rotateAndCrop));
1747}
1748
Eino-Ville Talvala305cec62020-11-12 14:18:17 -08001749bool CameraDeviceClient::supportsCameraMute() {
1750 return mDevice->supportsCameraMute();
1751}
1752
1753status_t CameraDeviceClient::setCameraMute(bool enabled) {
1754 return mDevice->setCameraMute(enabled);
1755}
1756
Yin-Chia Yehb978c382019-10-30 00:22:37 -07001757binder::Status CameraDeviceClient::switchToOffline(
1758 const sp<hardware::camera2::ICameraDeviceCallbacks>& cameraCb,
Emilian Peevb2bc5a42019-11-20 16:02:14 -08001759 const std::vector<int>& offlineOutputIds,
Yin-Chia Yehb978c382019-10-30 00:22:37 -07001760 /*out*/
1761 sp<hardware::camera2::ICameraOfflineSession>* session) {
1762 ATRACE_CALL();
1763
1764 binder::Status res;
1765 if (!(res = checkPidStatus(__FUNCTION__)).isOk()) return res;
1766
1767 Mutex::Autolock icl(mBinderSerializationLock);
1768
1769 if (!mDevice.get()) {
1770 return STATUS_ERROR(CameraService::ERROR_DISCONNECTED, "Camera device no longer alive");
1771 }
1772
Emilian Peevb2bc5a42019-11-20 16:02:14 -08001773 if (offlineOutputIds.empty()) {
Emilian Peevcc0b7952020-01-07 13:54:47 -08001774 String8 msg = String8::format("Offline surfaces must not be empty");
Yin-Chia Yehb978c382019-10-30 00:22:37 -07001775 ALOGE("%s: %s", __FUNCTION__, msg.string());
1776 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
1777 }
1778
1779 if (session == nullptr) {
1780 String8 msg = String8::format("Invalid offline session");
1781 ALOGE("%s: %s", __FUNCTION__, msg.string());
1782 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
1783 }
1784
Yin-Chia Yeh87fccca2020-01-28 09:37:18 -08001785 std::vector<int32_t> offlineStreamIds;
1786 offlineStreamIds.reserve(offlineOutputIds.size());
Emilian Peev4697b642019-11-19 17:11:14 -08001787 KeyedVector<sp<IBinder>, sp<CompositeStream>> offlineCompositeStreamMap;
Emilian Peevb2bc5a42019-11-20 16:02:14 -08001788 for (const auto& streamId : offlineOutputIds) {
1789 ssize_t index = mConfiguredOutputs.indexOfKey(streamId);
Yin-Chia Yehb978c382019-10-30 00:22:37 -07001790 if (index == NAME_NOT_FOUND) {
Emilian Peevcc0b7952020-01-07 13:54:47 -08001791 String8 msg = String8::format("Offline surface with id: %d is not registered",
1792 streamId);
Yin-Chia Yehb978c382019-10-30 00:22:37 -07001793 ALOGE("%s: %s", __FUNCTION__, msg.string());
1794 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
1795 }
Emilian Peevcc0b7952020-01-07 13:54:47 -08001796
1797 if (!mStreamInfoMap[streamId].supportsOffline) {
1798 String8 msg = String8::format("Offline surface with id: %d doesn't support "
1799 "offline mode", streamId);
1800 ALOGE("%s: %s", __FUNCTION__, msg.string());
1801 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
1802 }
Yin-Chia Yehb978c382019-10-30 00:22:37 -07001803
Emilian Peev2f5d6012022-01-19 16:16:50 -08001804 Mutex::Autolock l(mCompositeLock);
Emilian Peevb2bc5a42019-11-20 16:02:14 -08001805 bool isCompositeStream = false;
Emilian Peev2f5d6012022-01-19 16:16:50 -08001806 for (const auto& gbp : mConfiguredOutputs.valueAt(index).getGraphicBufferProducers()) {
Emilian Peevb2bc5a42019-11-20 16:02:14 -08001807 sp<Surface> s = new Surface(gbp, false /*controlledByApp*/);
Pirama Arumuga Nainar8db21062022-01-28 10:15:12 -08001808 isCompositeStream = camera3::DepthCompositeStream::isDepthCompositeStream(s) ||
Emilian Peevb2bc5a42019-11-20 16:02:14 -08001809 camera3::HeicCompositeStream::isHeicCompositeStream(s);
Emilian Peev4697b642019-11-19 17:11:14 -08001810 if (isCompositeStream) {
1811 auto compositeIdx = mCompositeStreamMap.indexOfKey(IInterface::asBinder(gbp));
1812 if (compositeIdx == NAME_NOT_FOUND) {
1813 ALOGE("%s: Unknown composite stream", __FUNCTION__);
1814 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT,
1815 "Unknown composite stream");
1816 }
1817
1818 mCompositeStreamMap.valueAt(compositeIdx)->insertCompositeStreamIds(
1819 &offlineStreamIds);
1820 offlineCompositeStreamMap.add(mCompositeStreamMap.keyAt(compositeIdx),
1821 mCompositeStreamMap.valueAt(compositeIdx));
1822 break;
1823 }
Emilian Peevb2bc5a42019-11-20 16:02:14 -08001824 }
1825
Emilian Peev4697b642019-11-19 17:11:14 -08001826 if (!isCompositeStream) {
Emilian Peevb2bc5a42019-11-20 16:02:14 -08001827 offlineStreamIds.push_back(streamId);
Yin-Chia Yehb978c382019-10-30 00:22:37 -07001828 }
1829 }
1830
1831 sp<CameraOfflineSessionBase> offlineSession;
1832 auto ret = mDevice->switchToOffline(offlineStreamIds, &offlineSession);
1833 if (ret != OK) {
1834 return STATUS_ERROR_FMT(CameraService::ERROR_ILLEGAL_ARGUMENT,
1835 "Camera %s: Error switching to offline mode: %s (%d)",
1836 mCameraIdStr.string(), strerror(ret), ret);
1837 }
1838
Emilian Peevcc0b7952020-01-07 13:54:47 -08001839 sp<CameraOfflineSessionClient> offlineClient;
1840 if (offlineSession.get() != nullptr) {
1841 offlineClient = new CameraOfflineSessionClient(sCameraService,
1842 offlineSession, offlineCompositeStreamMap, cameraCb, mClientPackageName,
Emilian Peev8b64f282021-03-25 16:49:57 -07001843 mClientFeatureId, mCameraIdStr, mCameraFacing, mOrientation, mClientPid, mClientUid,
1844 mServicePid);
Emilian Peevcc0b7952020-01-07 13:54:47 -08001845 ret = sCameraService->addOfflineClient(mCameraIdStr, offlineClient);
1846 }
1847
Yin-Chia Yehb978c382019-10-30 00:22:37 -07001848 if (ret == OK) {
Emilian Peevd99c8ae2019-11-26 13:19:13 -08001849 // A successful offline session switch must reset the current camera client
1850 // and release any resources occupied by previously configured streams.
1851 mStreamMap.clear();
1852 mConfiguredOutputs.clear();
1853 mDeferredStreams.clear();
1854 mStreamInfoMap.clear();
Emilian Peev2f5d6012022-01-19 16:16:50 -08001855 Mutex::Autolock l(mCompositeLock);
Emilian Peevd99c8ae2019-11-26 13:19:13 -08001856 mCompositeStreamMap.clear();
1857 mInputStream = {false, 0, 0, 0, 0};
Yin-Chia Yehb978c382019-10-30 00:22:37 -07001858 } else {
Emilian Peevb2bc5a42019-11-20 16:02:14 -08001859 switch(ret) {
1860 case BAD_VALUE:
1861 return STATUS_ERROR_FMT(CameraService::ERROR_ILLEGAL_ARGUMENT,
1862 "Illegal argument to HAL module for camera \"%s\"", mCameraIdStr.c_str());
1863 case TIMED_OUT:
1864 return STATUS_ERROR_FMT(CameraService::ERROR_CAMERA_IN_USE,
1865 "Camera \"%s\" is already open", mCameraIdStr.c_str());
1866 default:
1867 return STATUS_ERROR_FMT(CameraService::ERROR_INVALID_OPERATION,
1868 "Failed to initialize camera \"%s\": %s (%d)", mCameraIdStr.c_str(),
1869 strerror(-ret), ret);
1870 }
Yin-Chia Yehb978c382019-10-30 00:22:37 -07001871 }
1872
1873 *session = offlineClient;
1874
1875 return binder::Status::ok();
1876}
1877
Igor Murashkine7ee7632013-06-11 18:10:18 -07001878status_t CameraDeviceClient::dump(int fd, const Vector<String16>& args) {
Eino-Ville Talvalac4003962016-01-13 10:07:04 -08001879 return BasicClient::dump(fd, args);
1880}
1881
1882status_t CameraDeviceClient::dumpClient(int fd, const Vector<String16>& args) {
Eino-Ville Talvalad00111e2017-01-31 11:59:12 -08001883 dprintf(fd, " CameraDeviceClient[%s] (%p) dump:\n",
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -08001884 mCameraIdStr.string(),
Eino-Ville Talvalae992e752014-11-07 16:17:48 -08001885 (getRemoteCallback() != NULL ?
Marco Nelissenf8880202014-11-14 07:58:25 -08001886 IInterface::asBinder(getRemoteCallback()).get() : NULL) );
Eino-Ville Talvalad00111e2017-01-31 11:59:12 -08001887 dprintf(fd, " Current client UID %u\n", mClientUid);
Igor Murashkine7ee7632013-06-11 18:10:18 -07001888
Eino-Ville Talvalad00111e2017-01-31 11:59:12 -08001889 dprintf(fd, " State:\n");
1890 dprintf(fd, " Request ID counter: %d\n", mRequestIdCounter);
Chien-Yu Chen618ff8a2015-03-13 11:27:17 -07001891 if (mInputStream.configured) {
Eino-Ville Talvalad00111e2017-01-31 11:59:12 -08001892 dprintf(fd, " Current input stream ID: %d\n", mInputStream.id);
Chien-Yu Chen618ff8a2015-03-13 11:27:17 -07001893 } else {
Eino-Ville Talvalad00111e2017-01-31 11:59:12 -08001894 dprintf(fd, " No input stream configured.\n");
Chien-Yu Chen618ff8a2015-03-13 11:27:17 -07001895 }
Eino-Ville Talvala67489d22014-09-18 15:52:02 -07001896 if (!mStreamMap.isEmpty()) {
Eino-Ville Talvalad00111e2017-01-31 11:59:12 -08001897 dprintf(fd, " Current output stream/surface IDs:\n");
Eino-Ville Talvala67489d22014-09-18 15:52:02 -07001898 for (size_t i = 0; i < mStreamMap.size(); i++) {
Eino-Ville Talvalad00111e2017-01-31 11:59:12 -08001899 dprintf(fd, " Stream %d Surface %d\n",
Shuzhen Wang0129d522016-10-30 22:43:41 -07001900 mStreamMap.valueAt(i).streamId(),
1901 mStreamMap.valueAt(i).surfaceId());
Eino-Ville Talvala67489d22014-09-18 15:52:02 -07001902 }
Zhijun He5d677d12016-05-29 16:52:39 -07001903 } else if (!mDeferredStreams.isEmpty()) {
Eino-Ville Talvalad00111e2017-01-31 11:59:12 -08001904 dprintf(fd, " Current deferred surface output stream IDs:\n");
Zhijun He5d677d12016-05-29 16:52:39 -07001905 for (auto& streamId : mDeferredStreams) {
Eino-Ville Talvalad00111e2017-01-31 11:59:12 -08001906 dprintf(fd, " Stream %d\n", streamId);
Zhijun He5d677d12016-05-29 16:52:39 -07001907 }
Eino-Ville Talvala67489d22014-09-18 15:52:02 -07001908 } else {
Eino-Ville Talvalad00111e2017-01-31 11:59:12 -08001909 dprintf(fd, " No output streams configured.\n");
Eino-Ville Talvala67489d22014-09-18 15:52:02 -07001910 }
Igor Murashkine7ee7632013-06-11 18:10:18 -07001911 // TODO: print dynamic/request section from most recent requests
1912 mFrameProcessor->dump(fd, args);
1913
1914 return dumpDevice(fd, args);
1915}
1916
Avichal Rakesh7e53cad2021-10-05 13:46:30 -07001917status_t CameraDeviceClient::startWatchingTags(const String8 &tags, int out) {
1918 sp<CameraDeviceBase> device = mDevice;
1919 if (!device) {
1920 dprintf(out, " Device is detached.");
1921 return OK;
1922 }
1923 device->startWatchingTags(tags);
1924 return OK;
1925}
1926
1927status_t CameraDeviceClient::stopWatchingTags(int out) {
1928 sp<CameraDeviceBase> device = mDevice;
1929 if (!device) {
1930 dprintf(out, " Device is detached.");
1931 return OK;
1932 }
1933 device->stopWatchingTags();
1934 return OK;
1935}
1936
1937status_t CameraDeviceClient::dumpWatchedEventsToVector(std::vector<std::string> &out) {
1938 sp<CameraDeviceBase> device = mDevice;
1939 if (!device) {
1940 return OK;
1941 }
1942 device->dumpWatchedEventsToVector(out);
1943 return OK;
1944}
1945
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001946void CameraDeviceClient::notifyError(int32_t errorCode,
Jianing Weicb0652e2014-03-12 18:29:36 -07001947 const CaptureResultExtras& resultExtras) {
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07001948 // Thread safe. Don't bother locking.
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001949 sp<hardware::camera2::ICameraDeviceCallbacks> remoteCb = getRemoteCallback();
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07001950
Emilian Peev538c90e2018-12-17 18:03:19 +00001951 bool skipClientNotification = false;
Emilian Peev2f5d6012022-01-19 16:16:50 -08001952 {
1953 // Access to the composite stream map must be synchronized
1954 Mutex::Autolock l(mCompositeLock);
1955 // Composites can have multiple internal streams. Error notifications coming from such
1956 // internal streams may need to remain within camera service.
1957 for (size_t i = 0; i < mCompositeStreamMap.size(); i++) {
1958 skipClientNotification |= mCompositeStreamMap.valueAt(i)->onError(errorCode,
1959 resultExtras);
1960 }
Emilian Peev538c90e2018-12-17 18:03:19 +00001961 }
1962
1963 if ((remoteCb != 0) && (!skipClientNotification)) {
Jianing Weicb0652e2014-03-12 18:29:36 -07001964 remoteCb->onDeviceError(errorCode, resultExtras);
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07001965 }
1966}
1967
Chien-Yu Chene8c535e2016-04-14 12:18:26 -07001968void CameraDeviceClient::notifyRepeatingRequestError(long lastFrameNumber) {
1969 sp<hardware::camera2::ICameraDeviceCallbacks> remoteCb = getRemoteCallback();
1970
1971 if (remoteCb != 0) {
Yin-Chia Yeh8ca23dc2017-09-05 18:15:56 -07001972 remoteCb->onRepeatingRequestError(lastFrameNumber, mStreamingRequestId);
Chien-Yu Chene8c535e2016-04-14 12:18:26 -07001973 }
1974
Shuzhen Wangc9ca6782016-04-26 13:40:31 -07001975 Mutex::Autolock idLock(mStreamingRequestIdLock);
Chien-Yu Chene8c535e2016-04-14 12:18:26 -07001976 mStreamingRequestId = REQUEST_ID_NONE;
1977}
1978
Shuzhen Wang316781a2020-08-18 18:11:01 -07001979void CameraDeviceClient::notifyIdle(
1980 int64_t requestCount, int64_t resultErrorCount, bool deviceError,
1981 const std::vector<hardware::CameraStreamStats>& streamStats) {
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07001982 // Thread safe. Don't bother locking.
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001983 sp<hardware::camera2::ICameraDeviceCallbacks> remoteCb = getRemoteCallback();
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07001984
1985 if (remoteCb != 0) {
1986 remoteCb->onDeviceIdle();
1987 }
Shuzhen Wangd26b1862022-03-07 12:05:05 -08001988 Camera2ClientBase::notifyIdleWithUserTag(requestCount, resultErrorCount, deviceError,
Shuzhen Wang9372b0b2022-05-11 18:55:19 -07001989 streamStats, mUserTag, mVideoStabilizationMode);
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07001990}
1991
Jianing Weicb0652e2014-03-12 18:29:36 -07001992void CameraDeviceClient::notifyShutter(const CaptureResultExtras& resultExtras,
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07001993 nsecs_t timestamp) {
1994 // Thread safe. Don't bother locking.
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08001995 sp<hardware::camera2::ICameraDeviceCallbacks> remoteCb = getRemoteCallback();
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07001996 if (remoteCb != 0) {
Jianing Weicb0652e2014-03-12 18:29:36 -07001997 remoteCb->onCaptureStarted(resultExtras, timestamp);
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07001998 }
Eino-Ville Talvala412fe562015-08-20 17:08:32 -07001999 Camera2ClientBase::notifyShutter(resultExtras, timestamp);
Shuzhen Wang68ac7ad2019-01-30 14:03:28 -08002000
Emilian Peev2f5d6012022-01-19 16:16:50 -08002001 // Access to the composite stream map must be synchronized
2002 Mutex::Autolock l(mCompositeLock);
Shuzhen Wang68ac7ad2019-01-30 14:03:28 -08002003 for (size_t i = 0; i < mCompositeStreamMap.size(); i++) {
2004 mCompositeStreamMap.valueAt(i)->onShutter(resultExtras, timestamp);
2005 }
Eino-Ville Talvalaf1e98d82013-09-06 09:32:43 -07002006}
2007
Eino-Ville Talvala4d44cad2015-04-11 13:15:45 -07002008void CameraDeviceClient::notifyPrepared(int streamId) {
2009 // Thread safe. Don't bother locking.
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08002010 sp<hardware::camera2::ICameraDeviceCallbacks> remoteCb = getRemoteCallback();
Eino-Ville Talvala4d44cad2015-04-11 13:15:45 -07002011 if (remoteCb != 0) {
2012 remoteCb->onPrepared(streamId);
2013 }
2014}
2015
Shuzhen Wang9d066012016-09-30 11:30:20 -07002016void CameraDeviceClient::notifyRequestQueueEmpty() {
2017 // Thread safe. Don't bother locking.
2018 sp<hardware::camera2::ICameraDeviceCallbacks> remoteCb = getRemoteCallback();
2019 if (remoteCb != 0) {
2020 remoteCb->onRequestQueueEmpty();
2021 }
2022}
2023
Igor Murashkine7ee7632013-06-11 18:10:18 -07002024void CameraDeviceClient::detachDevice() {
2025 if (mDevice == 0) return;
2026
Shuzhen Wang316781a2020-08-18 18:11:01 -07002027 nsecs_t startTime = systemTime();
Eino-Ville Talvala2f09bac2016-12-13 11:29:54 -08002028 ALOGV("Camera %s: Stopping processors", mCameraIdStr.string());
Igor Murashkine7ee7632013-06-11 18:10:18 -07002029
Emilian Peev7ee731f2022-02-08 14:55:52 -08002030 if (mFrameProcessor.get() != nullptr) {
2031 mFrameProcessor->removeListener(
2032 camera2::FrameProcessorBase::FRAME_PROCESSOR_LISTENER_MIN_ID,
2033 camera2::FrameProcessorBase::FRAME_PROCESSOR_LISTENER_MAX_ID, /*listener*/this);
2034 mFrameProcessor->requestExit();
2035 ALOGV("Camera %s: Waiting for threads", mCameraIdStr.string());
2036 mFrameProcessor->join();
2037 ALOGV("Camera %s: Disconnecting device", mCameraIdStr.string());
2038 }
Igor Murashkine7ee7632013-06-11 18:10:18 -07002039
2040 // WORKAROUND: HAL refuses to disconnect while there's streams in flight
2041 {
Emilian Peev6b51d7d2018-07-23 11:41:44 +01002042 int64_t lastFrameNumber;
Igor Murashkine7ee7632013-06-11 18:10:18 -07002043 status_t code;
Emilian Peev6b51d7d2018-07-23 11:41:44 +01002044 if ((code = mDevice->flush(&lastFrameNumber)) != OK) {
2045 ALOGE("%s: flush failed with code 0x%x", __FUNCTION__, code);
2046 }
2047
Igor Murashkine7ee7632013-06-11 18:10:18 -07002048 if ((code = mDevice->waitUntilDrained()) != OK) {
2049 ALOGE("%s: waitUntilDrained failed with code 0x%x", __FUNCTION__,
2050 code);
2051 }
2052 }
2053
Emilian Peev2f5d6012022-01-19 16:16:50 -08002054 {
2055 Mutex::Autolock l(mCompositeLock);
2056 for (size_t i = 0; i < mCompositeStreamMap.size(); i++) {
2057 auto ret = mCompositeStreamMap.valueAt(i)->deleteInternalStreams();
2058 if (ret != OK) {
2059 ALOGE("%s: Failed removing composite stream %s (%d)", __FUNCTION__,
2060 strerror(-ret), ret);
2061 }
Emilian Peev5e4c7322019-10-22 14:20:52 -07002062 }
Emilian Peev2f5d6012022-01-19 16:16:50 -08002063 mCompositeStreamMap.clear();
Emilian Peev5e4c7322019-10-22 14:20:52 -07002064 }
Emilian Peev5e4c7322019-10-22 14:20:52 -07002065
Igor Murashkine7ee7632013-06-11 18:10:18 -07002066 Camera2ClientBase::detachDevice();
Shuzhen Wang316781a2020-08-18 18:11:01 -07002067
2068 int32_t closeLatencyMs = ns2ms(systemTime() - startTime);
Austin Borger74fca042022-05-23 12:41:21 -07002069 mCameraServiceProxyWrapper->logClose(mCameraIdStr, closeLatencyMs);
Igor Murashkine7ee7632013-06-11 18:10:18 -07002070}
2071
2072/** Device-related methods */
Jianing Weicb0652e2014-03-12 18:29:36 -07002073void CameraDeviceClient::onResultAvailable(const CaptureResult& result) {
Igor Murashkine7ee7632013-06-11 18:10:18 -07002074 ATRACE_CALL();
2075 ALOGV("%s", __FUNCTION__);
2076
Igor Murashkin4fb55c12013-08-29 17:43:01 -07002077 // Thread-safe. No lock necessary.
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08002078 sp<hardware::camera2::ICameraDeviceCallbacks> remoteCb = mRemoteCallback;
Igor Murashkin4fb55c12013-08-29 17:43:01 -07002079 if (remoteCb != NULL) {
Shuzhen Wang5c22c152017-12-31 17:12:25 -08002080 remoteCb->onResultReceived(result.mMetadata, result.mResultExtras,
2081 result.mPhysicalMetadatas);
Igor Murashkine7ee7632013-06-11 18:10:18 -07002082 }
Emilian Peev538c90e2018-12-17 18:03:19 +00002083
Emilian Peev2f5d6012022-01-19 16:16:50 -08002084 // Access to the composite stream map must be synchronized
2085 Mutex::Autolock l(mCompositeLock);
Emilian Peev538c90e2018-12-17 18:03:19 +00002086 for (size_t i = 0; i < mCompositeStreamMap.size(); i++) {
2087 mCompositeStreamMap.valueAt(i)->onResultAvailable(result);
2088 }
Igor Murashkine7ee7632013-06-11 18:10:18 -07002089}
2090
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08002091binder::Status CameraDeviceClient::checkPidStatus(const char* checkLocation) {
Eino-Ville Talvala6192b892016-04-04 12:31:18 -07002092 if (mDisconnected) {
2093 return STATUS_ERROR(CameraService::ERROR_DISCONNECTED,
2094 "The camera device has been disconnected");
2095 }
Eino-Ville Talvalad56db1d2015-12-17 16:50:35 -08002096 status_t res = checkPid(checkLocation);
2097 return (res == OK) ? binder::Status::ok() :
2098 STATUS_ERROR(CameraService::ERROR_PERMISSION_DENIED,
2099 "Attempt to use camera from a different process than original client");
2100}
2101
Igor Murashkine7ee7632013-06-11 18:10:18 -07002102// TODO: move to Camera2ClientBase
2103bool CameraDeviceClient::enforceRequestPermissions(CameraMetadata& metadata) {
2104
Jayant Chowdhary12361932018-08-27 14:46:13 -07002105 const int pid = CameraThreadState::getCallingPid();
Igor Murashkine7ee7632013-06-11 18:10:18 -07002106 const int selfPid = getpid();
2107 camera_metadata_entry_t entry;
2108
2109 /**
2110 * Mixin default important security values
2111 * - android.led.transmit = defaulted ON
2112 */
2113 CameraMetadata staticInfo = mDevice->info();
2114 entry = staticInfo.find(ANDROID_LED_AVAILABLE_LEDS);
2115 for(size_t i = 0; i < entry.count; ++i) {
2116 uint8_t led = entry.data.u8[i];
2117
2118 switch(led) {
2119 case ANDROID_LED_AVAILABLE_LEDS_TRANSMIT: {
2120 uint8_t transmitDefault = ANDROID_LED_TRANSMIT_ON;
2121 if (!metadata.exists(ANDROID_LED_TRANSMIT)) {
2122 metadata.update(ANDROID_LED_TRANSMIT,
2123 &transmitDefault, 1);
2124 }
2125 break;
2126 }
2127 }
2128 }
2129
2130 // We can do anything!
2131 if (pid == selfPid) {
2132 return true;
2133 }
2134
2135 /**
2136 * Permission check special fields in the request
2137 * - android.led.transmit = android.permission.CAMERA_DISABLE_TRANSMIT
2138 */
2139 entry = metadata.find(ANDROID_LED_TRANSMIT);
2140 if (entry.count > 0 && entry.data.u8[0] != ANDROID_LED_TRANSMIT_ON) {
2141 String16 permissionString =
2142 String16("android.permission.CAMERA_DISABLE_TRANSMIT_LED");
2143 if (!checkCallingPermission(permissionString)) {
Jayant Chowdhary12361932018-08-27 14:46:13 -07002144 const int uid = CameraThreadState::getCallingUid();
Igor Murashkine7ee7632013-06-11 18:10:18 -07002145 ALOGE("Permission Denial: "
2146 "can't disable transmit LED pid=%d, uid=%d", pid, uid);
2147 return false;
2148 }
2149 }
2150
2151 return true;
2152}
2153
Shuzhen Wang610d7b82022-02-08 14:37:22 -08002154status_t CameraDeviceClient::getRotationTransformLocked(int mirrorMode,
2155 int32_t* transform) {
Igor Murashkinf8b2a6f2013-09-17 17:03:28 -07002156 ALOGV("%s: begin", __FUNCTION__);
2157
Igor Murashkinf8b2a6f2013-09-17 17:03:28 -07002158 const CameraMetadata& staticInfo = mDevice->info();
Shuzhen Wang610d7b82022-02-08 14:37:22 -08002159 return CameraUtils::getRotationTransform(staticInfo, mirrorMode, transform);
Igor Murashkinf8b2a6f2013-09-17 17:03:28 -07002160}
2161
Emilian Peevf4816702020-04-03 15:44:51 -07002162binder::Status CameraDeviceClient::mapRequestTemplate(int templateId,
2163 camera_request_template_t* tempId /*out*/) {
2164 binder::Status ret = binder::Status::ok();
2165
2166 if (tempId == nullptr) {
2167 ret = STATUS_ERROR_FMT(CameraService::ERROR_ILLEGAL_ARGUMENT,
2168 "Camera %s: Invalid template argument", mCameraIdStr.string());
2169 return ret;
2170 }
2171 switch(templateId) {
2172 case ICameraDeviceUser::TEMPLATE_PREVIEW:
2173 *tempId = camera_request_template_t::CAMERA_TEMPLATE_PREVIEW;
2174 break;
2175 case ICameraDeviceUser::TEMPLATE_RECORD:
2176 *tempId = camera_request_template_t::CAMERA_TEMPLATE_VIDEO_RECORD;
2177 break;
2178 case ICameraDeviceUser::TEMPLATE_STILL_CAPTURE:
2179 *tempId = camera_request_template_t::CAMERA_TEMPLATE_STILL_CAPTURE;
2180 break;
2181 case ICameraDeviceUser::TEMPLATE_VIDEO_SNAPSHOT:
2182 *tempId = camera_request_template_t::CAMERA_TEMPLATE_VIDEO_SNAPSHOT;
2183 break;
2184 case ICameraDeviceUser::TEMPLATE_ZERO_SHUTTER_LAG:
2185 *tempId = camera_request_template_t::CAMERA_TEMPLATE_ZERO_SHUTTER_LAG;
2186 break;
2187 case ICameraDeviceUser::TEMPLATE_MANUAL:
2188 *tempId = camera_request_template_t::CAMERA_TEMPLATE_MANUAL;
2189 break;
2190 default:
2191 ret = STATUS_ERROR_FMT(CameraService::ERROR_ILLEGAL_ARGUMENT,
2192 "Camera %s: Template ID %d is invalid or not supported",
2193 mCameraIdStr.string(), templateId);
2194 return ret;
2195 }
2196
2197 return ret;
2198}
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -08002199
2200const CameraMetadata &CameraDeviceClient::getStaticInfo(const String8 &cameraId) {
2201 if (mDevice->getId() == cameraId) {
2202 return mDevice->info();
2203 }
2204 return mDevice->infoPhysical(cameraId);
2205}
2206
2207bool CameraDeviceClient::isUltraHighResolutionSensor(const String8 &cameraId) {
2208 const CameraMetadata &deviceInfo = getStaticInfo(cameraId);
Shuzhen Wangd4abdf72021-05-28 11:22:50 -07002209 return SessionConfigurationUtils::isUltraHighResolutionSensor(deviceInfo);
Jayant Chowdhary13f9b2f2020-12-02 22:46:15 -08002210}
2211
2212bool CameraDeviceClient::isSensorPixelModeConsistent(
2213 const std::list<int> &streamIdList, const CameraMetadata &settings) {
2214 // First we get the sensorPixelMode from the settings metadata.
2215 int32_t sensorPixelMode = ANDROID_SENSOR_PIXEL_MODE_DEFAULT;
2216 camera_metadata_ro_entry sensorPixelModeEntry = settings.find(ANDROID_SENSOR_PIXEL_MODE);
2217 if (sensorPixelModeEntry.count != 0) {
2218 sensorPixelMode = sensorPixelModeEntry.data.u8[0];
2219 if (sensorPixelMode != ANDROID_SENSOR_PIXEL_MODE_DEFAULT &&
2220 sensorPixelMode != ANDROID_SENSOR_PIXEL_MODE_MAXIMUM_RESOLUTION) {
2221 ALOGE("%s: Request sensor pixel mode not is not one of the valid values %d",
2222 __FUNCTION__, sensorPixelMode);
2223 return false;
2224 }
2225 }
2226 // Check whether each stream has max resolution allowed.
2227 bool consistent = true;
2228 for (auto it : streamIdList) {
2229 auto const streamInfoIt = mStreamInfoMap.find(it);
2230 if (streamInfoIt == mStreamInfoMap.end()) {
2231 ALOGE("%s: stream id %d not created, skipping", __FUNCTION__, it);
2232 return false;
2233 }
2234 consistent =
2235 streamInfoIt->second.sensorPixelModesUsed.find(sensorPixelMode) !=
2236 streamInfoIt->second.sensorPixelModesUsed.end();
2237 if (!consistent) {
2238 ALOGE("sensorPixelMode used %i not consistent with configured modes", sensorPixelMode);
2239 for (auto m : streamInfoIt->second.sensorPixelModesUsed) {
2240 ALOGE("sensor pixel mode used list: %i", m);
2241 }
2242 break;
2243 }
2244 }
2245
2246 return consistent;
2247}
2248
Igor Murashkine7ee7632013-06-11 18:10:18 -07002249} // namespace android