1 /*
2 * Copyright (C) 2013-2018 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #define LOG_TAG "CameraDeviceClient"
18 #define ATRACE_TAG ATRACE_TAG_CAMERA
19 //#define LOG_NDEBUG 0
20
21 #include <cutils/properties.h>
22 #include <utils/CameraThreadState.h>
23 #include <utils/Log.h>
24 #include <utils/SessionConfigurationUtils.h>
25 #include <utils/Trace.h>
26 #include <gui/Surface.h>
27 #include <camera/camera2/CaptureRequest.h>
28 #include <camera/CameraUtils.h>
29
30 #include "common/CameraDeviceBase.h"
31 #include "device3/Camera3Device.h"
32 #include "device3/Camera3OutputStream.h"
33 #include "api2/CameraDeviceClient.h"
34 #include "utils/CameraServiceProxyWrapper.h"
35
36 #include <camera_metadata_hidden.h>
37
38 #include "DepthCompositeStream.h"
39 #include "HeicCompositeStream.h"
40
41 // Convenience methods for constructing binder::Status objects for error returns
42
43 #define STATUS_ERROR(errorCode, errorString) \
44 binder::Status::fromServiceSpecificError(errorCode, \
45 String8::format("%s:%d: %s", __FUNCTION__, __LINE__, errorString))
46
47 #define STATUS_ERROR_FMT(errorCode, errorString, ...) \
48 binder::Status::fromServiceSpecificError(errorCode, \
49 String8::format("%s:%d: " errorString, __FUNCTION__, __LINE__, \
50 __VA_ARGS__))
51
52 namespace android {
53 using namespace camera2;
54 using camera3::camera_stream_rotation_t::CAMERA_STREAM_ROTATION_0;
55 using camera3::SessionConfigurationUtils;
56
CameraDeviceClientBase(const sp<CameraService> & cameraService,const sp<hardware::camera2::ICameraDeviceCallbacks> & remoteCallback,const String16 & clientPackageName,const std::optional<String16> & clientFeatureId,const String8 & cameraId,int api1CameraId,int cameraFacing,int sensorOrientation,int clientPid,uid_t clientUid,int servicePid)57 CameraDeviceClientBase::CameraDeviceClientBase(
58 const sp<CameraService>& cameraService,
59 const sp<hardware::camera2::ICameraDeviceCallbacks>& remoteCallback,
60 const String16& clientPackageName,
61 const std::optional<String16>& clientFeatureId,
62 const String8& cameraId,
63 int api1CameraId,
64 int cameraFacing,
65 int sensorOrientation,
66 int clientPid,
67 uid_t clientUid,
68 int servicePid) :
69 BasicClient(cameraService,
70 IInterface::asBinder(remoteCallback),
71 clientPackageName,
72 clientFeatureId,
73 cameraId,
74 cameraFacing,
75 sensorOrientation,
76 clientPid,
77 clientUid,
78 servicePid),
79 mRemoteCallback(remoteCallback) {
80 // We don't need it for API2 clients, but Camera2ClientBase requires it.
81 (void) api1CameraId;
82 }
83
84 // Interface used by CameraService
85
CameraDeviceClient(const sp<CameraService> & cameraService,const sp<hardware::camera2::ICameraDeviceCallbacks> & remoteCallback,const String16 & clientPackageName,const std::optional<String16> & clientFeatureId,const String8 & cameraId,int cameraFacing,int sensorOrientation,int clientPid,uid_t clientUid,int servicePid,bool overrideForPerfClass)86 CameraDeviceClient::CameraDeviceClient(const sp<CameraService>& cameraService,
87 const sp<hardware::camera2::ICameraDeviceCallbacks>& remoteCallback,
88 const String16& clientPackageName,
89 const std::optional<String16>& clientFeatureId,
90 const String8& cameraId,
91 int cameraFacing,
92 int sensorOrientation,
93 int clientPid,
94 uid_t clientUid,
95 int servicePid,
96 bool overrideForPerfClass) :
97 Camera2ClientBase(cameraService, remoteCallback, clientPackageName, clientFeatureId,
98 cameraId, /*API1 camera ID*/ -1, cameraFacing, sensorOrientation,
99 clientPid, clientUid, servicePid, overrideForPerfClass),
100 mInputStream(),
101 mStreamingRequestId(REQUEST_ID_NONE),
102 mRequestIdCounter(0),
103 mOverrideForPerfClass(overrideForPerfClass) {
104
105 ATRACE_CALL();
106 ALOGI("CameraDeviceClient %s: Opened", cameraId.string());
107 }
108
initialize(sp<CameraProviderManager> manager,const String8 & monitorTags)109 status_t CameraDeviceClient::initialize(sp<CameraProviderManager> manager,
110 const String8& monitorTags) {
111 return initializeImpl(manager, monitorTags);
112 }
113
114 template<typename TProviderPtr>
initializeImpl(TProviderPtr providerPtr,const String8 & monitorTags)115 status_t CameraDeviceClient::initializeImpl(TProviderPtr providerPtr, const String8& monitorTags) {
116 ATRACE_CALL();
117 status_t res;
118
119 res = Camera2ClientBase::initialize(providerPtr, monitorTags);
120 if (res != OK) {
121 return res;
122 }
123
124 String8 threadName;
125 mFrameProcessor = new FrameProcessorBase(mDevice);
126 threadName = String8::format("CDU-%s-FrameProc", mCameraIdStr.string());
127 mFrameProcessor->run(threadName.string());
128
129 mFrameProcessor->registerListener(camera2::FrameProcessorBase::FRAME_PROCESSOR_LISTENER_MIN_ID,
130 camera2::FrameProcessorBase::FRAME_PROCESSOR_LISTENER_MAX_ID,
131 /*listener*/this,
132 /*sendPartials*/true);
133
134 const CameraMetadata &deviceInfo = mDevice->info();
135 camera_metadata_ro_entry_t physicalKeysEntry = deviceInfo.find(
136 ANDROID_REQUEST_AVAILABLE_PHYSICAL_CAMERA_REQUEST_KEYS);
137 if (physicalKeysEntry.count > 0) {
138 mSupportedPhysicalRequestKeys.insert(mSupportedPhysicalRequestKeys.begin(),
139 physicalKeysEntry.data.i32,
140 physicalKeysEntry.data.i32 + physicalKeysEntry.count);
141 }
142
143 mProviderManager = providerPtr;
144 // Cache physical camera ids corresponding to this device and also the high
145 // resolution sensors in this device + physical camera ids
146 mProviderManager->isLogicalCamera(mCameraIdStr.string(), &mPhysicalCameraIds);
147 if (isUltraHighResolutionSensor(mCameraIdStr)) {
148 mHighResolutionSensors.insert(mCameraIdStr.string());
149 }
150 for (auto &physicalId : mPhysicalCameraIds) {
151 if (isUltraHighResolutionSensor(String8(physicalId.c_str()))) {
152 mHighResolutionSensors.insert(physicalId.c_str());
153 }
154 }
155 return OK;
156 }
157
~CameraDeviceClient()158 CameraDeviceClient::~CameraDeviceClient() {
159 }
160
submitRequest(const hardware::camera2::CaptureRequest & request,bool streaming,hardware::camera2::utils::SubmitInfo * submitInfo)161 binder::Status CameraDeviceClient::submitRequest(
162 const hardware::camera2::CaptureRequest& request,
163 bool streaming,
164 /*out*/
165 hardware::camera2::utils::SubmitInfo *submitInfo) {
166 std::vector<hardware::camera2::CaptureRequest> requestList = { request };
167 return submitRequestList(requestList, streaming, submitInfo);
168 }
169
insertGbpLocked(const sp<IGraphicBufferProducer> & gbp,SurfaceMap * outSurfaceMap,Vector<int32_t> * outputStreamIds,int32_t * currentStreamId)170 binder::Status CameraDeviceClient::insertGbpLocked(const sp<IGraphicBufferProducer>& gbp,
171 SurfaceMap* outSurfaceMap, Vector<int32_t>* outputStreamIds, int32_t *currentStreamId) {
172 int compositeIdx;
173 int idx = mStreamMap.indexOfKey(IInterface::asBinder(gbp));
174
175 // Trying to submit request with surface that wasn't created
176 if (idx == NAME_NOT_FOUND) {
177 ALOGE("%s: Camera %s: Tried to submit a request with a surface that"
178 " we have not called createStream on",
179 __FUNCTION__, mCameraIdStr.string());
180 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT,
181 "Request targets Surface that is not part of current capture session");
182 } else if ((compositeIdx = mCompositeStreamMap.indexOfKey(IInterface::asBinder(gbp)))
183 != NAME_NOT_FOUND) {
184 mCompositeStreamMap.valueAt(compositeIdx)->insertGbp(outSurfaceMap, outputStreamIds,
185 currentStreamId);
186 return binder::Status::ok();
187 }
188
189 const StreamSurfaceId& streamSurfaceId = mStreamMap.valueAt(idx);
190 if (outSurfaceMap->find(streamSurfaceId.streamId()) == outSurfaceMap->end()) {
191 outputStreamIds->push_back(streamSurfaceId.streamId());
192 }
193 (*outSurfaceMap)[streamSurfaceId.streamId()].push_back(streamSurfaceId.surfaceId());
194
195 ALOGV("%s: Camera %s: Appending output stream %d surface %d to request",
196 __FUNCTION__, mCameraIdStr.string(), streamSurfaceId.streamId(),
197 streamSurfaceId.surfaceId());
198
199 if (currentStreamId != nullptr) {
200 *currentStreamId = streamSurfaceId.streamId();
201 }
202
203 return binder::Status::ok();
204 }
205
getIntersection(const std::unordered_set<int> & streamIdsForThisCamera,const Vector<int> & streamIdsForThisRequest)206 static std::list<int> getIntersection(const std::unordered_set<int> &streamIdsForThisCamera,
207 const Vector<int> &streamIdsForThisRequest) {
208 std::list<int> intersection;
209 for (auto &streamId : streamIdsForThisRequest) {
210 if (streamIdsForThisCamera.find(streamId) != streamIdsForThisCamera.end()) {
211 intersection.emplace_back(streamId);
212 }
213 }
214 return intersection;
215 }
216
submitRequestList(const std::vector<hardware::camera2::CaptureRequest> & requests,bool streaming,hardware::camera2::utils::SubmitInfo * submitInfo)217 binder::Status CameraDeviceClient::submitRequestList(
218 const std::vector<hardware::camera2::CaptureRequest>& requests,
219 bool streaming,
220 /*out*/
221 hardware::camera2::utils::SubmitInfo *submitInfo) {
222 ATRACE_CALL();
223 ALOGV("%s-start of function. Request list size %zu", __FUNCTION__, requests.size());
224
225 binder::Status res = binder::Status::ok();
226 status_t err;
227 if ( !(res = checkPidStatus(__FUNCTION__) ).isOk()) {
228 return res;
229 }
230
231 Mutex::Autolock icl(mBinderSerializationLock);
232
233 if (!mDevice.get()) {
234 return STATUS_ERROR(CameraService::ERROR_DISCONNECTED, "Camera device no longer alive");
235 }
236
237 if (requests.empty()) {
238 ALOGE("%s: Camera %s: Sent null request. Rejecting request.",
239 __FUNCTION__, mCameraIdStr.string());
240 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, "Empty request list");
241 }
242
243 List<const CameraDeviceBase::PhysicalCameraSettingsList> metadataRequestList;
244 std::list<const SurfaceMap> surfaceMapList;
245 submitInfo->mRequestId = mRequestIdCounter;
246 uint32_t loopCounter = 0;
247
248 for (auto&& request: requests) {
249 if (request.mIsReprocess) {
250 if (!mInputStream.configured) {
251 ALOGE("%s: Camera %s: no input stream is configured.", __FUNCTION__,
252 mCameraIdStr.string());
253 return STATUS_ERROR_FMT(CameraService::ERROR_ILLEGAL_ARGUMENT,
254 "No input configured for camera %s but request is for reprocessing",
255 mCameraIdStr.string());
256 } else if (streaming) {
257 ALOGE("%s: Camera %s: streaming reprocess requests not supported.", __FUNCTION__,
258 mCameraIdStr.string());
259 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT,
260 "Repeating reprocess requests not supported");
261 } else if (request.mPhysicalCameraSettings.size() > 1) {
262 ALOGE("%s: Camera %s: reprocess requests not supported for "
263 "multiple physical cameras.", __FUNCTION__,
264 mCameraIdStr.string());
265 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT,
266 "Reprocess requests not supported for multiple cameras");
267 }
268 }
269
270 if (request.mPhysicalCameraSettings.empty()) {
271 ALOGE("%s: Camera %s: request doesn't contain any settings.", __FUNCTION__,
272 mCameraIdStr.string());
273 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT,
274 "Request doesn't contain any settings");
275 }
276
277 //The first capture settings should always match the logical camera id
278 String8 logicalId(request.mPhysicalCameraSettings.begin()->id.c_str());
279 if (mDevice->getId() != logicalId) {
280 ALOGE("%s: Camera %s: Invalid camera request settings.", __FUNCTION__,
281 mCameraIdStr.string());
282 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT,
283 "Invalid camera request settings");
284 }
285
286 if (request.mSurfaceList.isEmpty() && request.mStreamIdxList.size() == 0) {
287 ALOGE("%s: Camera %s: Requests must have at least one surface target. "
288 "Rejecting request.", __FUNCTION__, mCameraIdStr.string());
289 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT,
290 "Request has no output targets");
291 }
292
293 /**
294 * Write in the output stream IDs and map from stream ID to surface ID
295 * which we calculate from the capture request's list of surface target
296 */
297 SurfaceMap surfaceMap;
298 Vector<int32_t> outputStreamIds;
299 std::vector<std::string> requestedPhysicalIds;
300 if (request.mSurfaceList.size() > 0) {
301 for (const sp<Surface>& surface : request.mSurfaceList) {
302 if (surface == 0) continue;
303
304 int32_t streamId;
305 sp<IGraphicBufferProducer> gbp = surface->getIGraphicBufferProducer();
306 res = insertGbpLocked(gbp, &surfaceMap, &outputStreamIds, &streamId);
307 if (!res.isOk()) {
308 return res;
309 }
310
311 ssize_t index = mConfiguredOutputs.indexOfKey(streamId);
312 if (index >= 0) {
313 String8 requestedPhysicalId(
314 mConfiguredOutputs.valueAt(index).getPhysicalCameraId());
315 requestedPhysicalIds.push_back(requestedPhysicalId.string());
316 } else {
317 ALOGW("%s: Output stream Id not found among configured outputs!", __FUNCTION__);
318 }
319 }
320 } else {
321 for (size_t i = 0; i < request.mStreamIdxList.size(); i++) {
322 int streamId = request.mStreamIdxList.itemAt(i);
323 int surfaceIdx = request.mSurfaceIdxList.itemAt(i);
324
325 ssize_t index = mConfiguredOutputs.indexOfKey(streamId);
326 if (index < 0) {
327 ALOGE("%s: Camera %s: Tried to submit a request with a surface that"
328 " we have not called createStream on: stream %d",
329 __FUNCTION__, mCameraIdStr.string(), streamId);
330 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT,
331 "Request targets Surface that is not part of current capture session");
332 }
333
334 const auto& gbps = mConfiguredOutputs.valueAt(index).getGraphicBufferProducers();
335 if ((size_t)surfaceIdx >= gbps.size()) {
336 ALOGE("%s: Camera %s: Tried to submit a request with a surface that"
337 " we have not called createStream on: stream %d, surfaceIdx %d",
338 __FUNCTION__, mCameraIdStr.string(), streamId, surfaceIdx);
339 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT,
340 "Request targets Surface has invalid surface index");
341 }
342
343 res = insertGbpLocked(gbps[surfaceIdx], &surfaceMap, &outputStreamIds, nullptr);
344 if (!res.isOk()) {
345 return res;
346 }
347
348 String8 requestedPhysicalId(
349 mConfiguredOutputs.valueAt(index).getPhysicalCameraId());
350 requestedPhysicalIds.push_back(requestedPhysicalId.string());
351 }
352 }
353
354 CameraDeviceBase::PhysicalCameraSettingsList physicalSettingsList;
355 for (const auto& it : request.mPhysicalCameraSettings) {
356 if (it.settings.isEmpty()) {
357 ALOGE("%s: Camera %s: Sent empty metadata packet. Rejecting request.",
358 __FUNCTION__, mCameraIdStr.string());
359 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT,
360 "Request settings are empty");
361 }
362
363 // Check whether the physical / logical stream has settings
364 // consistent with the sensor pixel mode(s) it was configured with.
365 // mCameraIdToStreamSet will only have ids that are high resolution
366 const auto streamIdSetIt = mHighResolutionCameraIdToStreamIdSet.find(it.id);
367 if (streamIdSetIt != mHighResolutionCameraIdToStreamIdSet.end()) {
368 std::list<int> streamIdsUsedInRequest = getIntersection(streamIdSetIt->second,
369 outputStreamIds);
370 if (!request.mIsReprocess &&
371 !isSensorPixelModeConsistent(streamIdsUsedInRequest, it.settings)) {
372 ALOGE("%s: Camera %s: Request settings CONTROL_SENSOR_PIXEL_MODE not "
373 "consistent with configured streams. Rejecting request.",
374 __FUNCTION__, it.id.c_str());
375 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT,
376 "Request settings CONTROL_SENSOR_PIXEL_MODE are not consistent with "
377 "streams configured");
378 }
379 }
380
381 String8 physicalId(it.id.c_str());
382 bool hasTestPatternModePhysicalKey = std::find(mSupportedPhysicalRequestKeys.begin(),
383 mSupportedPhysicalRequestKeys.end(), ANDROID_SENSOR_TEST_PATTERN_MODE) !=
384 mSupportedPhysicalRequestKeys.end();
385 bool hasTestPatternDataPhysicalKey = std::find(mSupportedPhysicalRequestKeys.begin(),
386 mSupportedPhysicalRequestKeys.end(), ANDROID_SENSOR_TEST_PATTERN_DATA) !=
387 mSupportedPhysicalRequestKeys.end();
388 if (physicalId != mDevice->getId()) {
389 auto found = std::find(requestedPhysicalIds.begin(), requestedPhysicalIds.end(),
390 it.id);
391 if (found == requestedPhysicalIds.end()) {
392 ALOGE("%s: Camera %s: Physical camera id: %s not part of attached outputs.",
393 __FUNCTION__, mCameraIdStr.string(), physicalId.string());
394 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT,
395 "Invalid physical camera id");
396 }
397
398 if (!mSupportedPhysicalRequestKeys.empty()) {
399 // Filter out any unsupported physical request keys.
400 CameraMetadata filteredParams(mSupportedPhysicalRequestKeys.size());
401 camera_metadata_t *meta = const_cast<camera_metadata_t *>(
402 filteredParams.getAndLock());
403 set_camera_metadata_vendor_id(meta, mDevice->getVendorTagId());
404 filteredParams.unlock(meta);
405
406 for (const auto& keyIt : mSupportedPhysicalRequestKeys) {
407 camera_metadata_ro_entry entry = it.settings.find(keyIt);
408 if (entry.count > 0) {
409 filteredParams.update(entry);
410 }
411 }
412
413 physicalSettingsList.push_back({it.id, filteredParams,
414 hasTestPatternModePhysicalKey, hasTestPatternDataPhysicalKey});
415 }
416 } else {
417 physicalSettingsList.push_back({it.id, it.settings});
418 }
419 }
420
421 if (!enforceRequestPermissions(physicalSettingsList.begin()->metadata)) {
422 // Callee logs
423 return STATUS_ERROR(CameraService::ERROR_PERMISSION_DENIED,
424 "Caller does not have permission to change restricted controls");
425 }
426
427 physicalSettingsList.begin()->metadata.update(ANDROID_REQUEST_OUTPUT_STREAMS,
428 &outputStreamIds[0], outputStreamIds.size());
429
430 if (request.mIsReprocess) {
431 physicalSettingsList.begin()->metadata.update(ANDROID_REQUEST_INPUT_STREAMS,
432 &mInputStream.id, 1);
433 }
434
435 physicalSettingsList.begin()->metadata.update(ANDROID_REQUEST_ID,
436 &(submitInfo->mRequestId), /*size*/1);
437 loopCounter++; // loopCounter starts from 1
438 ALOGV("%s: Camera %s: Creating request with ID %d (%d of %zu)",
439 __FUNCTION__, mCameraIdStr.string(), submitInfo->mRequestId,
440 loopCounter, requests.size());
441
442 metadataRequestList.push_back(physicalSettingsList);
443 surfaceMapList.push_back(surfaceMap);
444 }
445 mRequestIdCounter++;
446
447 if (streaming) {
448 err = mDevice->setStreamingRequestList(metadataRequestList, surfaceMapList,
449 &(submitInfo->mLastFrameNumber));
450 if (err != OK) {
451 String8 msg = String8::format(
452 "Camera %s: Got error %s (%d) after trying to set streaming request",
453 mCameraIdStr.string(), strerror(-err), err);
454 ALOGE("%s: %s", __FUNCTION__, msg.string());
455 res = STATUS_ERROR(CameraService::ERROR_INVALID_OPERATION,
456 msg.string());
457 } else {
458 Mutex::Autolock idLock(mStreamingRequestIdLock);
459 mStreamingRequestId = submitInfo->mRequestId;
460 }
461 } else {
462 err = mDevice->captureList(metadataRequestList, surfaceMapList,
463 &(submitInfo->mLastFrameNumber));
464 if (err != OK) {
465 String8 msg = String8::format(
466 "Camera %s: Got error %s (%d) after trying to submit capture request",
467 mCameraIdStr.string(), strerror(-err), err);
468 ALOGE("%s: %s", __FUNCTION__, msg.string());
469 res = STATUS_ERROR(CameraService::ERROR_INVALID_OPERATION,
470 msg.string());
471 }
472 ALOGV("%s: requestId = %d ", __FUNCTION__, submitInfo->mRequestId);
473 }
474
475 ALOGV("%s: Camera %s: End of function", __FUNCTION__, mCameraIdStr.string());
476 return res;
477 }
478
cancelRequest(int requestId,int64_t * lastFrameNumber)479 binder::Status CameraDeviceClient::cancelRequest(
480 int requestId,
481 /*out*/
482 int64_t* lastFrameNumber) {
483 ATRACE_CALL();
484 ALOGV("%s, requestId = %d", __FUNCTION__, requestId);
485
486 status_t err;
487 binder::Status res;
488
489 if (!(res = checkPidStatus(__FUNCTION__)).isOk()) return res;
490
491 Mutex::Autolock icl(mBinderSerializationLock);
492
493 if (!mDevice.get()) {
494 return STATUS_ERROR(CameraService::ERROR_DISCONNECTED, "Camera device no longer alive");
495 }
496
497 Mutex::Autolock idLock(mStreamingRequestIdLock);
498 if (mStreamingRequestId != requestId) {
499 String8 msg = String8::format("Camera %s: Canceling request ID %d doesn't match "
500 "current request ID %d", mCameraIdStr.string(), requestId, mStreamingRequestId);
501 ALOGE("%s: %s", __FUNCTION__, msg.string());
502 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
503 }
504
505 err = mDevice->clearStreamingRequest(lastFrameNumber);
506
507 if (err == OK) {
508 ALOGV("%s: Camera %s: Successfully cleared streaming request",
509 __FUNCTION__, mCameraIdStr.string());
510 mStreamingRequestId = REQUEST_ID_NONE;
511 } else {
512 res = STATUS_ERROR_FMT(CameraService::ERROR_INVALID_OPERATION,
513 "Camera %s: Error clearing streaming request: %s (%d)",
514 mCameraIdStr.string(), strerror(-err), err);
515 }
516
517 return res;
518 }
519
beginConfigure()520 binder::Status CameraDeviceClient::beginConfigure() {
521 // TODO: Implement this.
522 ATRACE_CALL();
523 ALOGV("%s: Not implemented yet.", __FUNCTION__);
524 return binder::Status::ok();
525 }
526
endConfigure(int operatingMode,const hardware::camera2::impl::CameraMetadataNative & sessionParams,int64_t startTimeMs,std::vector<int> * offlineStreamIds)527 binder::Status CameraDeviceClient::endConfigure(int operatingMode,
528 const hardware::camera2::impl::CameraMetadataNative& sessionParams, int64_t startTimeMs,
529 std::vector<int>* offlineStreamIds /*out*/) {
530 ATRACE_CALL();
531 ALOGV("%s: ending configure (%d input stream, %zu output surfaces)",
532 __FUNCTION__, mInputStream.configured ? 1 : 0,
533 mStreamMap.size());
534
535 binder::Status res;
536 if (!(res = checkPidStatus(__FUNCTION__)).isOk()) return res;
537
538 if (offlineStreamIds == nullptr) {
539 String8 msg = String8::format("Invalid offline stream ids");
540 ALOGE("%s: %s", __FUNCTION__, msg.string());
541 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
542 }
543
544 Mutex::Autolock icl(mBinderSerializationLock);
545
546 if (!mDevice.get()) {
547 return STATUS_ERROR(CameraService::ERROR_DISCONNECTED, "Camera device no longer alive");
548 }
549
550 res = SessionConfigurationUtils::checkOperatingMode(operatingMode, mDevice->info(),
551 mCameraIdStr);
552 if (!res.isOk()) {
553 return res;
554 }
555
556 status_t err = mDevice->configureStreams(sessionParams, operatingMode);
557 if (err == BAD_VALUE) {
558 String8 msg = String8::format("Camera %s: Unsupported set of inputs/outputs provided",
559 mCameraIdStr.string());
560 ALOGE("%s: %s", __FUNCTION__, msg.string());
561 res = STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
562 } else if (err != OK) {
563 String8 msg = String8::format("Camera %s: Error configuring streams: %s (%d)",
564 mCameraIdStr.string(), strerror(-err), err);
565 ALOGE("%s: %s", __FUNCTION__, msg.string());
566 res = STATUS_ERROR(CameraService::ERROR_INVALID_OPERATION, msg.string());
567 } else {
568 offlineStreamIds->clear();
569 mDevice->getOfflineStreamIds(offlineStreamIds);
570
571 for (size_t i = 0; i < mCompositeStreamMap.size(); ++i) {
572 err = mCompositeStreamMap.valueAt(i)->configureStream();
573 if (err != OK) {
574 String8 msg = String8::format("Camera %s: Error configuring composite "
575 "streams: %s (%d)", mCameraIdStr.string(), strerror(-err), err);
576 ALOGE("%s: %s", __FUNCTION__, msg.string());
577 res = STATUS_ERROR(CameraService::ERROR_INVALID_OPERATION, msg.string());
578 break;
579 }
580
581 // Composite streams can only support offline mode in case all individual internal
582 // streams are also supported.
583 std::vector<int> internalStreams;
584 mCompositeStreamMap.valueAt(i)->insertCompositeStreamIds(&internalStreams);
585 offlineStreamIds->erase(
586 std::remove_if(offlineStreamIds->begin(), offlineStreamIds->end(),
587 [&internalStreams] (int streamId) {
588 auto it = std::find(internalStreams.begin(), internalStreams.end(),
589 streamId);
590 if (it != internalStreams.end()) {
591 internalStreams.erase(it);
592 return true;
593 }
594
595 return false;}), offlineStreamIds->end());
596 if (internalStreams.empty()) {
597 offlineStreamIds->push_back(mCompositeStreamMap.valueAt(i)->getStreamId());
598 }
599 }
600
601 for (const auto& offlineStreamId : *offlineStreamIds) {
602 mStreamInfoMap[offlineStreamId].supportsOffline = true;
603 }
604
605 nsecs_t configureEnd = systemTime();
606 int32_t configureDurationMs = ns2ms(configureEnd) - startTimeMs;
607 CameraServiceProxyWrapper::logStreamConfigured(mCameraIdStr, operatingMode,
608 false /*internalReconfig*/, configureDurationMs);
609 }
610
611 return res;
612 }
613
isSessionConfigurationSupported(const SessionConfiguration & sessionConfiguration,bool * status)614 binder::Status CameraDeviceClient::isSessionConfigurationSupported(
615 const SessionConfiguration& sessionConfiguration, bool *status /*out*/) {
616
617 ATRACE_CALL();
618 binder::Status res;
619 status_t ret = OK;
620 if (!(res = checkPidStatus(__FUNCTION__)).isOk()) return res;
621
622 Mutex::Autolock icl(mBinderSerializationLock);
623
624 if (!mDevice.get()) {
625 return STATUS_ERROR(CameraService::ERROR_DISCONNECTED, "Camera device no longer alive");
626 }
627
628 auto operatingMode = sessionConfiguration.getOperatingMode();
629 res = SessionConfigurationUtils::checkOperatingMode(operatingMode, mDevice->info(),
630 mCameraIdStr);
631 if (!res.isOk()) {
632 return res;
633 }
634
635 if (status == nullptr) {
636 String8 msg = String8::format( "Camera %s: Invalid status!", mCameraIdStr.string());
637 ALOGE("%s: %s", __FUNCTION__, msg.string());
638 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
639 }
640
641 hardware::camera::device::V3_7::StreamConfiguration streamConfiguration;
642 bool earlyExit = false;
643 camera3::metadataGetter getMetadata = [this](const String8 &id, bool /*overrideForPerfClass*/) {
644 return mDevice->infoPhysical(id);};
645 std::vector<std::string> physicalCameraIds;
646 mProviderManager->isLogicalCamera(mCameraIdStr.string(), &physicalCameraIds);
647 res = SessionConfigurationUtils::convertToHALStreamCombination(sessionConfiguration,
648 mCameraIdStr, mDevice->info(), getMetadata, physicalCameraIds, streamConfiguration,
649 mOverrideForPerfClass, &earlyExit);
650 if (!res.isOk()) {
651 return res;
652 }
653
654 if (earlyExit) {
655 *status = false;
656 return binder::Status::ok();
657 }
658
659 *status = false;
660 ret = mProviderManager->isSessionConfigurationSupported(mCameraIdStr.string(),
661 streamConfiguration, status);
662 switch (ret) {
663 case OK:
664 // Expected, do nothing.
665 break;
666 case INVALID_OPERATION: {
667 String8 msg = String8::format(
668 "Camera %s: Session configuration query not supported!",
669 mCameraIdStr.string());
670 ALOGD("%s: %s", __FUNCTION__, msg.string());
671 res = STATUS_ERROR(CameraService::ERROR_INVALID_OPERATION, msg.string());
672 }
673
674 break;
675 default: {
676 String8 msg = String8::format( "Camera %s: Error: %s (%d)", mCameraIdStr.string(),
677 strerror(-ret), ret);
678 ALOGE("%s: %s", __FUNCTION__, msg.string());
679 res = STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT,
680 msg.string());
681 }
682 }
683
684 return res;
685 }
686
deleteStream(int streamId)687 binder::Status CameraDeviceClient::deleteStream(int streamId) {
688 ATRACE_CALL();
689 ALOGV("%s (streamId = 0x%x)", __FUNCTION__, streamId);
690
691 binder::Status res;
692 if (!(res = checkPidStatus(__FUNCTION__)).isOk()) return res;
693
694 Mutex::Autolock icl(mBinderSerializationLock);
695
696 if (!mDevice.get()) {
697 return STATUS_ERROR(CameraService::ERROR_DISCONNECTED, "Camera device no longer alive");
698 }
699
700 bool isInput = false;
701 std::vector<sp<IBinder>> surfaces;
702 ssize_t dIndex = NAME_NOT_FOUND;
703 ssize_t compositeIndex = NAME_NOT_FOUND;
704
705 if (mInputStream.configured && mInputStream.id == streamId) {
706 isInput = true;
707 } else {
708 // Guard against trying to delete non-created streams
709 for (size_t i = 0; i < mStreamMap.size(); ++i) {
710 if (streamId == mStreamMap.valueAt(i).streamId()) {
711 surfaces.push_back(mStreamMap.keyAt(i));
712 }
713 }
714
715 // See if this stream is one of the deferred streams.
716 for (size_t i = 0; i < mDeferredStreams.size(); ++i) {
717 if (streamId == mDeferredStreams[i]) {
718 dIndex = i;
719 break;
720 }
721 }
722
723 for (size_t i = 0; i < mCompositeStreamMap.size(); ++i) {
724 if (streamId == mCompositeStreamMap.valueAt(i)->getStreamId()) {
725 compositeIndex = i;
726 break;
727 }
728 }
729
730 if (surfaces.empty() && dIndex == NAME_NOT_FOUND) {
731 String8 msg = String8::format("Camera %s: Invalid stream ID (%d) specified, no such"
732 " stream created yet", mCameraIdStr.string(), streamId);
733 ALOGW("%s: %s", __FUNCTION__, msg.string());
734 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
735 }
736 }
737
738 // Also returns BAD_VALUE if stream ID was not valid
739 status_t err = mDevice->deleteStream(streamId);
740
741 if (err != OK) {
742 String8 msg = String8::format("Camera %s: Unexpected error %s (%d) when deleting stream %d",
743 mCameraIdStr.string(), strerror(-err), err, streamId);
744 ALOGE("%s: %s", __FUNCTION__, msg.string());
745 res = STATUS_ERROR(CameraService::ERROR_INVALID_OPERATION, msg.string());
746 } else {
747 if (isInput) {
748 mInputStream.configured = false;
749 } else {
750 for (auto& surface : surfaces) {
751 mStreamMap.removeItem(surface);
752 }
753
754 mConfiguredOutputs.removeItem(streamId);
755
756 if (dIndex != NAME_NOT_FOUND) {
757 mDeferredStreams.removeItemsAt(dIndex);
758 }
759
760 if (compositeIndex != NAME_NOT_FOUND) {
761 status_t ret;
762 if ((ret = mCompositeStreamMap.valueAt(compositeIndex)->deleteStream())
763 != OK) {
764 String8 msg = String8::format("Camera %s: Unexpected error %s (%d) when "
765 "deleting composite stream %d", mCameraIdStr.string(), strerror(-err), err,
766 streamId);
767 ALOGE("%s: %s", __FUNCTION__, msg.string());
768 res = STATUS_ERROR(CameraService::ERROR_INVALID_OPERATION, msg.string());
769 }
770 mCompositeStreamMap.removeItemsAt(compositeIndex);
771 }
772 for (auto &mapIt: mHighResolutionCameraIdToStreamIdSet) {
773 auto &streamSet = mapIt.second;
774 if (streamSet.find(streamId) != streamSet.end()) {
775 streamSet.erase(streamId);
776 break;
777 }
778 }
779 }
780 }
781
782 return res;
783 }
784
createStream(const hardware::camera2::params::OutputConfiguration & outputConfiguration,int32_t * newStreamId)785 binder::Status CameraDeviceClient::createStream(
786 const hardware::camera2::params::OutputConfiguration &outputConfiguration,
787 /*out*/
788 int32_t* newStreamId) {
789 ATRACE_CALL();
790
791 binder::Status res;
792 if (!(res = checkPidStatus(__FUNCTION__)).isOk()) return res;
793
794 Mutex::Autolock icl(mBinderSerializationLock);
795
796 const std::vector<sp<IGraphicBufferProducer>>& bufferProducers =
797 outputConfiguration.getGraphicBufferProducers();
798 size_t numBufferProducers = bufferProducers.size();
799 bool deferredConsumer = outputConfiguration.isDeferred();
800 bool isShared = outputConfiguration.isShared();
801 String8 physicalCameraId = String8(outputConfiguration.getPhysicalCameraId());
802 bool deferredConsumerOnly = deferredConsumer && numBufferProducers == 0;
803 bool isMultiResolution = outputConfiguration.isMultiResolution();
804
805 res = SessionConfigurationUtils::checkSurfaceType(numBufferProducers, deferredConsumer,
806 outputConfiguration.getSurfaceType());
807 if (!res.isOk()) {
808 return res;
809 }
810
811 if (!mDevice.get()) {
812 return STATUS_ERROR(CameraService::ERROR_DISCONNECTED, "Camera device no longer alive");
813 }
814 res = SessionConfigurationUtils::checkPhysicalCameraId(mPhysicalCameraIds,
815 physicalCameraId, mCameraIdStr);
816 if (!res.isOk()) {
817 return res;
818 }
819
820 std::vector<sp<Surface>> surfaces;
821 std::vector<sp<IBinder>> binders;
822 status_t err;
823
824 // Create stream for deferred surface case.
825 if (deferredConsumerOnly) {
826 return createDeferredSurfaceStreamLocked(outputConfiguration, isShared, newStreamId);
827 }
828
829 OutputStreamInfo streamInfo;
830 bool isStreamInfoValid = false;
831 const std::vector<int32_t> &sensorPixelModesUsed =
832 outputConfiguration.getSensorPixelModesUsed();
833 for (auto& bufferProducer : bufferProducers) {
834 // Don't create multiple streams for the same target surface
835 sp<IBinder> binder = IInterface::asBinder(bufferProducer);
836 ssize_t index = mStreamMap.indexOfKey(binder);
837 if (index != NAME_NOT_FOUND) {
838 String8 msg = String8::format("Camera %s: Surface already has a stream created for it "
839 "(ID %zd)", mCameraIdStr.string(), index);
840 ALOGW("%s: %s", __FUNCTION__, msg.string());
841 return STATUS_ERROR(CameraService::ERROR_ALREADY_EXISTS, msg.string());
842 }
843
844 sp<Surface> surface;
845 res = SessionConfigurationUtils::createSurfaceFromGbp(streamInfo,
846 isStreamInfoValid, surface, bufferProducer, mCameraIdStr,
847 mDevice->infoPhysical(physicalCameraId), sensorPixelModesUsed);
848
849 if (!res.isOk())
850 return res;
851
852 if (!isStreamInfoValid) {
853 isStreamInfoValid = true;
854 }
855
856 binders.push_back(IInterface::asBinder(bufferProducer));
857 surfaces.push_back(surface);
858 }
859
860 // If mOverrideForPerfClass is true, do not fail createStream() for small
861 // JPEG sizes because existing createSurfaceFromGbp() logic will find the
862 // closest possible supported size.
863
864 int streamId = camera3::CAMERA3_STREAM_ID_INVALID;
865 std::vector<int> surfaceIds;
866 bool isDepthCompositeStream =
867 camera3::DepthCompositeStream::isDepthCompositeStream(surfaces[0]);
868 bool isHeicCompisiteStream = camera3::HeicCompositeStream::isHeicCompositeStream(surfaces[0]);
869 if (isDepthCompositeStream || isHeicCompisiteStream) {
870 sp<CompositeStream> compositeStream;
871 if (isDepthCompositeStream) {
872 compositeStream = new camera3::DepthCompositeStream(mDevice, getRemoteCallback());
873 } else {
874 compositeStream = new camera3::HeicCompositeStream(mDevice, getRemoteCallback());
875 }
876
877 err = compositeStream->createStream(surfaces, deferredConsumer, streamInfo.width,
878 streamInfo.height, streamInfo.format,
879 static_cast<camera_stream_rotation_t>(outputConfiguration.getRotation()),
880 &streamId, physicalCameraId, streamInfo.sensorPixelModesUsed, &surfaceIds,
881 outputConfiguration.getSurfaceSetID(), isShared, isMultiResolution);
882 if (err == OK) {
883 mCompositeStreamMap.add(IInterface::asBinder(surfaces[0]->getIGraphicBufferProducer()),
884 compositeStream);
885 }
886 } else {
887 err = mDevice->createStream(surfaces, deferredConsumer, streamInfo.width,
888 streamInfo.height, streamInfo.format, streamInfo.dataSpace,
889 static_cast<camera_stream_rotation_t>(outputConfiguration.getRotation()),
890 &streamId, physicalCameraId, streamInfo.sensorPixelModesUsed, &surfaceIds,
891 outputConfiguration.getSurfaceSetID(), isShared, isMultiResolution);
892 }
893
894 if (err != OK) {
895 res = STATUS_ERROR_FMT(CameraService::ERROR_INVALID_OPERATION,
896 "Camera %s: Error creating output stream (%d x %d, fmt %x, dataSpace %x): %s (%d)",
897 mCameraIdStr.string(), streamInfo.width, streamInfo.height, streamInfo.format,
898 streamInfo.dataSpace, strerror(-err), err);
899 } else {
900 int i = 0;
901 for (auto& binder : binders) {
902 ALOGV("%s: mStreamMap add binder %p streamId %d, surfaceId %d",
903 __FUNCTION__, binder.get(), streamId, i);
904 mStreamMap.add(binder, StreamSurfaceId(streamId, surfaceIds[i]));
905 i++;
906 }
907
908 mConfiguredOutputs.add(streamId, outputConfiguration);
909 mStreamInfoMap[streamId] = streamInfo;
910
911 ALOGV("%s: Camera %s: Successfully created a new stream ID %d for output surface"
912 " (%d x %d) with format 0x%x.",
913 __FUNCTION__, mCameraIdStr.string(), streamId, streamInfo.width,
914 streamInfo.height, streamInfo.format);
915
916 // Set transform flags to ensure preview to be rotated correctly.
917 res = setStreamTransformLocked(streamId);
918
919 // Fill in mHighResolutionCameraIdToStreamIdSet map
920 const String8 &cameraIdUsed =
921 physicalCameraId.size() != 0 ? physicalCameraId : mCameraIdStr;
922 const char *cameraIdUsedCStr = cameraIdUsed.string();
923 // Only needed for high resolution sensors
924 if (mHighResolutionSensors.find(cameraIdUsedCStr) !=
925 mHighResolutionSensors.end()) {
926 mHighResolutionCameraIdToStreamIdSet[cameraIdUsedCStr].insert(streamId);
927 }
928
929 *newStreamId = streamId;
930 }
931
932 return res;
933 }
934
createDeferredSurfaceStreamLocked(const hardware::camera2::params::OutputConfiguration & outputConfiguration,bool isShared,int * newStreamId)935 binder::Status CameraDeviceClient::createDeferredSurfaceStreamLocked(
936 const hardware::camera2::params::OutputConfiguration &outputConfiguration,
937 bool isShared,
938 /*out*/
939 int* newStreamId) {
940 int width, height, format, surfaceType;
941 uint64_t consumerUsage;
942 android_dataspace dataSpace;
943 status_t err;
944 binder::Status res;
945
946 if (!mDevice.get()) {
947 return STATUS_ERROR(CameraService::ERROR_DISCONNECTED, "Camera device no longer alive");
948 }
949
950 // Infer the surface info for deferred surface stream creation.
951 width = outputConfiguration.getWidth();
952 height = outputConfiguration.getHeight();
953 surfaceType = outputConfiguration.getSurfaceType();
954 format = HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED;
955 dataSpace = android_dataspace_t::HAL_DATASPACE_UNKNOWN;
956 // Hardcode consumer usage flags: SurfaceView--0x900, SurfaceTexture--0x100.
957 consumerUsage = GraphicBuffer::USAGE_HW_TEXTURE;
958 if (surfaceType == OutputConfiguration::SURFACE_TYPE_SURFACE_VIEW) {
959 consumerUsage |= GraphicBuffer::USAGE_HW_COMPOSER;
960 }
961 int streamId = camera3::CAMERA3_STREAM_ID_INVALID;
962 std::vector<sp<Surface>> noSurface;
963 std::vector<int> surfaceIds;
964 String8 physicalCameraId(outputConfiguration.getPhysicalCameraId());
965 const String8 &cameraIdUsed =
966 physicalCameraId.size() != 0 ? physicalCameraId : mCameraIdStr;
967 // Here, we override sensor pixel modes
968 std::unordered_set<int32_t> overriddenSensorPixelModesUsed;
969 const std::vector<int32_t> &sensorPixelModesUsed =
970 outputConfiguration.getSensorPixelModesUsed();
971 if (SessionConfigurationUtils::checkAndOverrideSensorPixelModesUsed(
972 sensorPixelModesUsed, format, width, height, getStaticInfo(cameraIdUsed),
973 /*allowRounding*/ false, &overriddenSensorPixelModesUsed) != OK) {
974 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT,
975 "sensor pixel modes used not valid for deferred stream");
976 }
977
978 err = mDevice->createStream(noSurface, /*hasDeferredConsumer*/true, width,
979 height, format, dataSpace,
980 static_cast<camera_stream_rotation_t>(outputConfiguration.getRotation()),
981 &streamId, physicalCameraId,
982 overriddenSensorPixelModesUsed,
983 &surfaceIds,
984 outputConfiguration.getSurfaceSetID(), isShared,
985 outputConfiguration.isMultiResolution(), consumerUsage);
986
987 if (err != OK) {
988 res = STATUS_ERROR_FMT(CameraService::ERROR_INVALID_OPERATION,
989 "Camera %s: Error creating output stream (%d x %d, fmt %x, dataSpace %x): %s (%d)",
990 mCameraIdStr.string(), width, height, format, dataSpace, strerror(-err), err);
991 } else {
992 // Can not add streamId to mStreamMap here, as the surface is deferred. Add it to
993 // a separate list to track. Once the deferred surface is set, this id will be
994 // relocated to mStreamMap.
995 mDeferredStreams.push_back(streamId);
996 mStreamInfoMap.emplace(std::piecewise_construct, std::forward_as_tuple(streamId),
997 std::forward_as_tuple(width, height, format, dataSpace, consumerUsage,
998 overriddenSensorPixelModesUsed));
999
1000 ALOGV("%s: Camera %s: Successfully created a new stream ID %d for a deferred surface"
1001 " (%d x %d) stream with format 0x%x.",
1002 __FUNCTION__, mCameraIdStr.string(), streamId, width, height, format);
1003
1004 // Set transform flags to ensure preview to be rotated correctly.
1005 res = setStreamTransformLocked(streamId);
1006
1007 *newStreamId = streamId;
1008 // Fill in mHighResolutionCameraIdToStreamIdSet
1009 const char *cameraIdUsedCStr = cameraIdUsed.string();
1010 // Only needed for high resolution sensors
1011 if (mHighResolutionSensors.find(cameraIdUsedCStr) !=
1012 mHighResolutionSensors.end()) {
1013 mHighResolutionCameraIdToStreamIdSet[cameraIdUsed.string()].insert(streamId);
1014 }
1015 }
1016 return res;
1017 }
1018
setStreamTransformLocked(int streamId)1019 binder::Status CameraDeviceClient::setStreamTransformLocked(int streamId) {
1020 int32_t transform = 0;
1021 status_t err;
1022 binder::Status res;
1023
1024 if (!mDevice.get()) {
1025 return STATUS_ERROR(CameraService::ERROR_DISCONNECTED, "Camera device no longer alive");
1026 }
1027
1028 err = getRotationTransformLocked(&transform);
1029 if (err != OK) {
1030 // Error logged by getRotationTransformLocked.
1031 return STATUS_ERROR(CameraService::ERROR_INVALID_OPERATION,
1032 "Unable to calculate rotation transform for new stream");
1033 }
1034
1035 err = mDevice->setStreamTransform(streamId, transform);
1036 if (err != OK) {
1037 String8 msg = String8::format("Failed to set stream transform (stream id %d)",
1038 streamId);
1039 ALOGE("%s: %s", __FUNCTION__, msg.string());
1040 return STATUS_ERROR(CameraService::ERROR_INVALID_OPERATION, msg.string());
1041 }
1042
1043 return res;
1044 }
1045
createInputStream(int width,int height,int format,bool isMultiResolution,int32_t * newStreamId)1046 binder::Status CameraDeviceClient::createInputStream(
1047 int width, int height, int format, bool isMultiResolution,
1048 /*out*/
1049 int32_t* newStreamId) {
1050
1051 ATRACE_CALL();
1052 ALOGV("%s (w = %d, h = %d, f = 0x%x, isMultiResolution %d)", __FUNCTION__,
1053 width, height, format, isMultiResolution);
1054
1055 binder::Status res;
1056 if (!(res = checkPidStatus(__FUNCTION__)).isOk()) return res;
1057
1058 Mutex::Autolock icl(mBinderSerializationLock);
1059
1060 if (!mDevice.get()) {
1061 return STATUS_ERROR(CameraService::ERROR_DISCONNECTED, "Camera device no longer alive");
1062 }
1063
1064 if (mInputStream.configured) {
1065 String8 msg = String8::format("Camera %s: Already has an input stream "
1066 "configured (ID %d)", mCameraIdStr.string(), mInputStream.id);
1067 ALOGE("%s: %s", __FUNCTION__, msg.string() );
1068 return STATUS_ERROR(CameraService::ERROR_ALREADY_EXISTS, msg.string());
1069 }
1070
1071 int streamId = -1;
1072 status_t err = mDevice->createInputStream(width, height, format, isMultiResolution, &streamId);
1073 if (err == OK) {
1074 mInputStream.configured = true;
1075 mInputStream.width = width;
1076 mInputStream.height = height;
1077 mInputStream.format = format;
1078 mInputStream.id = streamId;
1079
1080 ALOGV("%s: Camera %s: Successfully created a new input stream ID %d",
1081 __FUNCTION__, mCameraIdStr.string(), streamId);
1082
1083 *newStreamId = streamId;
1084 } else {
1085 res = STATUS_ERROR_FMT(CameraService::ERROR_INVALID_OPERATION,
1086 "Camera %s: Error creating new input stream: %s (%d)", mCameraIdStr.string(),
1087 strerror(-err), err);
1088 }
1089
1090 return res;
1091 }
1092
getInputSurface(view::Surface * inputSurface)1093 binder::Status CameraDeviceClient::getInputSurface(/*out*/ view::Surface *inputSurface) {
1094
1095 binder::Status res;
1096 if (!(res = checkPidStatus(__FUNCTION__)).isOk()) return res;
1097
1098 if (inputSurface == NULL) {
1099 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, "Null input surface");
1100 }
1101
1102 Mutex::Autolock icl(mBinderSerializationLock);
1103 if (!mDevice.get()) {
1104 return STATUS_ERROR(CameraService::ERROR_DISCONNECTED, "Camera device no longer alive");
1105 }
1106 sp<IGraphicBufferProducer> producer;
1107 status_t err = mDevice->getInputBufferProducer(&producer);
1108 if (err != OK) {
1109 res = STATUS_ERROR_FMT(CameraService::ERROR_INVALID_OPERATION,
1110 "Camera %s: Error getting input Surface: %s (%d)",
1111 mCameraIdStr.string(), strerror(-err), err);
1112 } else {
1113 inputSurface->name = String16("CameraInput");
1114 inputSurface->graphicBufferProducer = producer;
1115 }
1116 return res;
1117 }
1118
updateOutputConfiguration(int streamId,const hardware::camera2::params::OutputConfiguration & outputConfiguration)1119 binder::Status CameraDeviceClient::updateOutputConfiguration(int streamId,
1120 const hardware::camera2::params::OutputConfiguration &outputConfiguration) {
1121 ATRACE_CALL();
1122
1123 binder::Status res;
1124 if (!(res = checkPidStatus(__FUNCTION__)).isOk()) return res;
1125
1126 Mutex::Autolock icl(mBinderSerializationLock);
1127
1128 if (!mDevice.get()) {
1129 return STATUS_ERROR(CameraService::ERROR_DISCONNECTED, "Camera device no longer alive");
1130 }
1131
1132 const std::vector<sp<IGraphicBufferProducer> >& bufferProducers =
1133 outputConfiguration.getGraphicBufferProducers();
1134 String8 physicalCameraId(outputConfiguration.getPhysicalCameraId());
1135
1136 auto producerCount = bufferProducers.size();
1137 if (producerCount == 0) {
1138 ALOGE("%s: bufferProducers must not be empty", __FUNCTION__);
1139 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT,
1140 "bufferProducers must not be empty");
1141 }
1142
1143 // The first output is the one associated with the output configuration.
1144 // It should always be present, valid and the corresponding stream id should match.
1145 sp<IBinder> binder = IInterface::asBinder(bufferProducers[0]);
1146 ssize_t index = mStreamMap.indexOfKey(binder);
1147 if (index == NAME_NOT_FOUND) {
1148 ALOGE("%s: Outputconfiguration is invalid", __FUNCTION__);
1149 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT,
1150 "OutputConfiguration is invalid");
1151 }
1152 if (mStreamMap.valueFor(binder).streamId() != streamId) {
1153 ALOGE("%s: Stream Id: %d provided doesn't match the id: %d in the stream map",
1154 __FUNCTION__, streamId, mStreamMap.valueFor(binder).streamId());
1155 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT,
1156 "Stream id is invalid");
1157 }
1158
1159 std::vector<size_t> removedSurfaceIds;
1160 std::vector<sp<IBinder>> removedOutputs;
1161 std::vector<sp<Surface>> newOutputs;
1162 std::vector<OutputStreamInfo> streamInfos;
1163 KeyedVector<sp<IBinder>, sp<IGraphicBufferProducer>> newOutputsMap;
1164 for (auto &it : bufferProducers) {
1165 newOutputsMap.add(IInterface::asBinder(it), it);
1166 }
1167
1168 for (size_t i = 0; i < mStreamMap.size(); i++) {
1169 ssize_t idx = newOutputsMap.indexOfKey(mStreamMap.keyAt(i));
1170 if (idx == NAME_NOT_FOUND) {
1171 if (mStreamMap[i].streamId() == streamId) {
1172 removedSurfaceIds.push_back(mStreamMap[i].surfaceId());
1173 removedOutputs.push_back(mStreamMap.keyAt(i));
1174 }
1175 } else {
1176 if (mStreamMap[i].streamId() != streamId) {
1177 ALOGE("%s: Output surface already part of a different stream", __FUNCTION__);
1178 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT,
1179 "Target Surface is invalid");
1180 }
1181 newOutputsMap.removeItemsAt(idx);
1182 }
1183 }
1184 const std::vector<int32_t> &sensorPixelModesUsed =
1185 outputConfiguration.getSensorPixelModesUsed();
1186
1187 for (size_t i = 0; i < newOutputsMap.size(); i++) {
1188 OutputStreamInfo outInfo;
1189 sp<Surface> surface;
1190 res = SessionConfigurationUtils::createSurfaceFromGbp(outInfo,
1191 /*isStreamInfoValid*/ false, surface, newOutputsMap.valueAt(i), mCameraIdStr,
1192 mDevice->infoPhysical(physicalCameraId), sensorPixelModesUsed);
1193 if (!res.isOk())
1194 return res;
1195
1196 streamInfos.push_back(outInfo);
1197 newOutputs.push_back(surface);
1198 }
1199
1200 //Trivial case no changes required
1201 if (removedSurfaceIds.empty() && newOutputs.empty()) {
1202 return binder::Status::ok();
1203 }
1204
1205 KeyedVector<sp<Surface>, size_t> outputMap;
1206 auto ret = mDevice->updateStream(streamId, newOutputs, streamInfos, removedSurfaceIds,
1207 &outputMap);
1208 if (ret != OK) {
1209 switch (ret) {
1210 case NAME_NOT_FOUND:
1211 case BAD_VALUE:
1212 case -EBUSY:
1213 res = STATUS_ERROR_FMT(CameraService::ERROR_ILLEGAL_ARGUMENT,
1214 "Camera %s: Error updating stream: %s (%d)",
1215 mCameraIdStr.string(), strerror(ret), ret);
1216 break;
1217 default:
1218 res = STATUS_ERROR_FMT(CameraService::ERROR_INVALID_OPERATION,
1219 "Camera %s: Error updating stream: %s (%d)",
1220 mCameraIdStr.string(), strerror(ret), ret);
1221 break;
1222 }
1223 } else {
1224 for (const auto &it : removedOutputs) {
1225 mStreamMap.removeItem(it);
1226 }
1227
1228 for (size_t i = 0; i < outputMap.size(); i++) {
1229 mStreamMap.add(IInterface::asBinder(outputMap.keyAt(i)->getIGraphicBufferProducer()),
1230 StreamSurfaceId(streamId, outputMap.valueAt(i)));
1231 }
1232
1233 mConfiguredOutputs.replaceValueFor(streamId, outputConfiguration);
1234
1235 ALOGV("%s: Camera %s: Successful stream ID %d update",
1236 __FUNCTION__, mCameraIdStr.string(), streamId);
1237 }
1238
1239 return res;
1240 }
1241
1242 // Create a request object from a template.
createDefaultRequest(int templateId,hardware::camera2::impl::CameraMetadataNative * request)1243 binder::Status CameraDeviceClient::createDefaultRequest(int templateId,
1244 /*out*/
1245 hardware::camera2::impl::CameraMetadataNative* request)
1246 {
1247 ATRACE_CALL();
1248 ALOGV("%s (templateId = 0x%x)", __FUNCTION__, templateId);
1249
1250 binder::Status res;
1251 if (!(res = checkPidStatus(__FUNCTION__)).isOk()) return res;
1252
1253 Mutex::Autolock icl(mBinderSerializationLock);
1254
1255 if (!mDevice.get()) {
1256 return STATUS_ERROR(CameraService::ERROR_DISCONNECTED, "Camera device no longer alive");
1257 }
1258
1259 status_t err;
1260 camera_request_template_t tempId = camera_request_template_t::CAMERA_TEMPLATE_COUNT;
1261 if (!(res = mapRequestTemplate(templateId, &tempId)).isOk()) return res;
1262
1263 CameraMetadata metadata;
1264 if ( (err = mDevice->createDefaultRequest(tempId, &metadata) ) == OK &&
1265 request != NULL) {
1266
1267 request->swap(metadata);
1268 } else if (err == BAD_VALUE) {
1269 res = STATUS_ERROR_FMT(CameraService::ERROR_ILLEGAL_ARGUMENT,
1270 "Camera %s: Template ID %d is invalid or not supported: %s (%d)",
1271 mCameraIdStr.string(), templateId, strerror(-err), err);
1272
1273 } else {
1274 res = STATUS_ERROR_FMT(CameraService::ERROR_INVALID_OPERATION,
1275 "Camera %s: Error creating default request for template %d: %s (%d)",
1276 mCameraIdStr.string(), templateId, strerror(-err), err);
1277 }
1278 return res;
1279 }
1280
getCameraInfo(hardware::camera2::impl::CameraMetadataNative * info)1281 binder::Status CameraDeviceClient::getCameraInfo(
1282 /*out*/
1283 hardware::camera2::impl::CameraMetadataNative* info)
1284 {
1285 ATRACE_CALL();
1286 ALOGV("%s", __FUNCTION__);
1287
1288 binder::Status res;
1289
1290 if (!(res = checkPidStatus(__FUNCTION__)).isOk()) return res;
1291
1292 Mutex::Autolock icl(mBinderSerializationLock);
1293
1294 if (!mDevice.get()) {
1295 return STATUS_ERROR(CameraService::ERROR_DISCONNECTED, "Camera device no longer alive");
1296 }
1297
1298 if (info != NULL) {
1299 *info = mDevice->info(); // static camera metadata
1300 // TODO: merge with device-specific camera metadata
1301 }
1302
1303 return res;
1304 }
1305
waitUntilIdle()1306 binder::Status CameraDeviceClient::waitUntilIdle()
1307 {
1308 ATRACE_CALL();
1309 ALOGV("%s", __FUNCTION__);
1310
1311 binder::Status res;
1312 if (!(res = checkPidStatus(__FUNCTION__)).isOk()) return res;
1313
1314 Mutex::Autolock icl(mBinderSerializationLock);
1315
1316 if (!mDevice.get()) {
1317 return STATUS_ERROR(CameraService::ERROR_DISCONNECTED, "Camera device no longer alive");
1318 }
1319
1320 // FIXME: Also need check repeating burst.
1321 Mutex::Autolock idLock(mStreamingRequestIdLock);
1322 if (mStreamingRequestId != REQUEST_ID_NONE) {
1323 String8 msg = String8::format(
1324 "Camera %s: Try to waitUntilIdle when there are active streaming requests",
1325 mCameraIdStr.string());
1326 ALOGE("%s: %s", __FUNCTION__, msg.string());
1327 return STATUS_ERROR(CameraService::ERROR_INVALID_OPERATION, msg.string());
1328 }
1329 status_t err = mDevice->waitUntilDrained();
1330 if (err != OK) {
1331 res = STATUS_ERROR_FMT(CameraService::ERROR_INVALID_OPERATION,
1332 "Camera %s: Error waiting to drain: %s (%d)",
1333 mCameraIdStr.string(), strerror(-err), err);
1334 }
1335 ALOGV("%s Done", __FUNCTION__);
1336 return res;
1337 }
1338
flush(int64_t * lastFrameNumber)1339 binder::Status CameraDeviceClient::flush(
1340 /*out*/
1341 int64_t* lastFrameNumber) {
1342 ATRACE_CALL();
1343 ALOGV("%s", __FUNCTION__);
1344
1345 binder::Status res;
1346 if (!(res = checkPidStatus(__FUNCTION__)).isOk()) return res;
1347
1348 Mutex::Autolock icl(mBinderSerializationLock);
1349
1350 if (!mDevice.get()) {
1351 return STATUS_ERROR(CameraService::ERROR_DISCONNECTED, "Camera device no longer alive");
1352 }
1353
1354 Mutex::Autolock idLock(mStreamingRequestIdLock);
1355 mStreamingRequestId = REQUEST_ID_NONE;
1356 status_t err = mDevice->flush(lastFrameNumber);
1357 if (err != OK) {
1358 res = STATUS_ERROR_FMT(CameraService::ERROR_INVALID_OPERATION,
1359 "Camera %s: Error flushing device: %s (%d)", mCameraIdStr.string(), strerror(-err), err);
1360 }
1361 return res;
1362 }
1363
prepare(int streamId)1364 binder::Status CameraDeviceClient::prepare(int streamId) {
1365 ATRACE_CALL();
1366 ALOGV("%s", __FUNCTION__);
1367
1368 binder::Status res;
1369 if (!(res = checkPidStatus(__FUNCTION__)).isOk()) return res;
1370
1371 Mutex::Autolock icl(mBinderSerializationLock);
1372
1373 // Guard against trying to prepare non-created streams
1374 ssize_t index = NAME_NOT_FOUND;
1375 for (size_t i = 0; i < mStreamMap.size(); ++i) {
1376 if (streamId == mStreamMap.valueAt(i).streamId()) {
1377 index = i;
1378 break;
1379 }
1380 }
1381
1382 if (index == NAME_NOT_FOUND) {
1383 String8 msg = String8::format("Camera %s: Invalid stream ID (%d) specified, no stream "
1384 "with that ID exists", mCameraIdStr.string(), streamId);
1385 ALOGW("%s: %s", __FUNCTION__, msg.string());
1386 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
1387 }
1388
1389 // Also returns BAD_VALUE if stream ID was not valid, or stream already
1390 // has been used
1391 status_t err = mDevice->prepare(streamId);
1392 if (err == BAD_VALUE) {
1393 res = STATUS_ERROR_FMT(CameraService::ERROR_ILLEGAL_ARGUMENT,
1394 "Camera %s: Stream %d has already been used, and cannot be prepared",
1395 mCameraIdStr.string(), streamId);
1396 } else if (err != OK) {
1397 res = STATUS_ERROR_FMT(CameraService::ERROR_INVALID_OPERATION,
1398 "Camera %s: Error preparing stream %d: %s (%d)", mCameraIdStr.string(), streamId,
1399 strerror(-err), err);
1400 }
1401 return res;
1402 }
1403
prepare2(int maxCount,int streamId)1404 binder::Status CameraDeviceClient::prepare2(int maxCount, int streamId) {
1405 ATRACE_CALL();
1406 ALOGV("%s", __FUNCTION__);
1407
1408 binder::Status res;
1409 if (!(res = checkPidStatus(__FUNCTION__)).isOk()) return res;
1410
1411 Mutex::Autolock icl(mBinderSerializationLock);
1412
1413 // Guard against trying to prepare non-created streams
1414 ssize_t index = NAME_NOT_FOUND;
1415 for (size_t i = 0; i < mStreamMap.size(); ++i) {
1416 if (streamId == mStreamMap.valueAt(i).streamId()) {
1417 index = i;
1418 break;
1419 }
1420 }
1421
1422 if (index == NAME_NOT_FOUND) {
1423 String8 msg = String8::format("Camera %s: Invalid stream ID (%d) specified, no stream "
1424 "with that ID exists", mCameraIdStr.string(), streamId);
1425 ALOGW("%s: %s", __FUNCTION__, msg.string());
1426 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
1427 }
1428
1429 if (maxCount <= 0) {
1430 String8 msg = String8::format("Camera %s: maxCount (%d) must be greater than 0",
1431 mCameraIdStr.string(), maxCount);
1432 ALOGE("%s: %s", __FUNCTION__, msg.string());
1433 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
1434 }
1435
1436 // Also returns BAD_VALUE if stream ID was not valid, or stream already
1437 // has been used
1438 status_t err = mDevice->prepare(maxCount, streamId);
1439 if (err == BAD_VALUE) {
1440 res = STATUS_ERROR_FMT(CameraService::ERROR_ILLEGAL_ARGUMENT,
1441 "Camera %s: Stream %d has already been used, and cannot be prepared",
1442 mCameraIdStr.string(), streamId);
1443 } else if (err != OK) {
1444 res = STATUS_ERROR_FMT(CameraService::ERROR_INVALID_OPERATION,
1445 "Camera %s: Error preparing stream %d: %s (%d)", mCameraIdStr.string(), streamId,
1446 strerror(-err), err);
1447 }
1448
1449 return res;
1450 }
1451
tearDown(int streamId)1452 binder::Status CameraDeviceClient::tearDown(int streamId) {
1453 ATRACE_CALL();
1454 ALOGV("%s", __FUNCTION__);
1455
1456 binder::Status res;
1457 if (!(res = checkPidStatus(__FUNCTION__)).isOk()) return res;
1458
1459 Mutex::Autolock icl(mBinderSerializationLock);
1460
1461 // Guard against trying to prepare non-created streams
1462 ssize_t index = NAME_NOT_FOUND;
1463 for (size_t i = 0; i < mStreamMap.size(); ++i) {
1464 if (streamId == mStreamMap.valueAt(i).streamId()) {
1465 index = i;
1466 break;
1467 }
1468 }
1469
1470 if (index == NAME_NOT_FOUND) {
1471 String8 msg = String8::format("Camera %s: Invalid stream ID (%d) specified, no stream "
1472 "with that ID exists", mCameraIdStr.string(), streamId);
1473 ALOGW("%s: %s", __FUNCTION__, msg.string());
1474 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
1475 }
1476
1477 // Also returns BAD_VALUE if stream ID was not valid or if the stream is in
1478 // use
1479 status_t err = mDevice->tearDown(streamId);
1480 if (err == BAD_VALUE) {
1481 res = STATUS_ERROR_FMT(CameraService::ERROR_ILLEGAL_ARGUMENT,
1482 "Camera %s: Stream %d is still in use, cannot be torn down",
1483 mCameraIdStr.string(), streamId);
1484 } else if (err != OK) {
1485 res = STATUS_ERROR_FMT(CameraService::ERROR_INVALID_OPERATION,
1486 "Camera %s: Error tearing down stream %d: %s (%d)", mCameraIdStr.string(), streamId,
1487 strerror(-err), err);
1488 }
1489
1490 return res;
1491 }
1492
finalizeOutputConfigurations(int32_t streamId,const hardware::camera2::params::OutputConfiguration & outputConfiguration)1493 binder::Status CameraDeviceClient::finalizeOutputConfigurations(int32_t streamId,
1494 const hardware::camera2::params::OutputConfiguration &outputConfiguration) {
1495 ATRACE_CALL();
1496
1497 binder::Status res;
1498 if (!(res = checkPidStatus(__FUNCTION__)).isOk()) return res;
1499
1500 Mutex::Autolock icl(mBinderSerializationLock);
1501
1502 const std::vector<sp<IGraphicBufferProducer> >& bufferProducers =
1503 outputConfiguration.getGraphicBufferProducers();
1504 String8 physicalId(outputConfiguration.getPhysicalCameraId());
1505
1506 if (bufferProducers.size() == 0) {
1507 ALOGE("%s: bufferProducers must not be empty", __FUNCTION__);
1508 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, "Target Surface is invalid");
1509 }
1510
1511 // streamId should be in mStreamMap if this stream already has a surface attached
1512 // to it. Otherwise, it should be in mDeferredStreams.
1513 bool streamIdConfigured = false;
1514 ssize_t deferredStreamIndex = NAME_NOT_FOUND;
1515 for (size_t i = 0; i < mStreamMap.size(); i++) {
1516 if (mStreamMap.valueAt(i).streamId() == streamId) {
1517 streamIdConfigured = true;
1518 break;
1519 }
1520 }
1521 for (size_t i = 0; i < mDeferredStreams.size(); i++) {
1522 if (streamId == mDeferredStreams[i]) {
1523 deferredStreamIndex = i;
1524 break;
1525 }
1526
1527 }
1528 if (deferredStreamIndex == NAME_NOT_FOUND && !streamIdConfigured) {
1529 String8 msg = String8::format("Camera %s: deferred surface is set to a unknown stream"
1530 "(ID %d)", mCameraIdStr.string(), streamId);
1531 ALOGW("%s: %s", __FUNCTION__, msg.string());
1532 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
1533 }
1534
1535 if (mStreamInfoMap[streamId].finalized) {
1536 String8 msg = String8::format("Camera %s: finalizeOutputConfigurations has been called"
1537 " on stream ID %d", mCameraIdStr.string(), streamId);
1538 ALOGW("%s: %s", __FUNCTION__, msg.string());
1539 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
1540 }
1541
1542 if (!mDevice.get()) {
1543 return STATUS_ERROR(CameraService::ERROR_DISCONNECTED, "Camera device no longer alive");
1544 }
1545
1546 std::vector<sp<Surface>> consumerSurfaces;
1547 const std::vector<int32_t> &sensorPixelModesUsed =
1548 outputConfiguration.getSensorPixelModesUsed();
1549 for (auto& bufferProducer : bufferProducers) {
1550 // Don't create multiple streams for the same target surface
1551 ssize_t index = mStreamMap.indexOfKey(IInterface::asBinder(bufferProducer));
1552 if (index != NAME_NOT_FOUND) {
1553 ALOGV("Camera %s: Surface already has a stream created "
1554 " for it (ID %zd)", mCameraIdStr.string(), index);
1555 continue;
1556 }
1557
1558 sp<Surface> surface;
1559 res = SessionConfigurationUtils::createSurfaceFromGbp(mStreamInfoMap[streamId],
1560 true /*isStreamInfoValid*/, surface, bufferProducer, mCameraIdStr,
1561 mDevice->infoPhysical(physicalId), sensorPixelModesUsed);
1562
1563 if (!res.isOk())
1564 return res;
1565
1566 consumerSurfaces.push_back(surface);
1567 }
1568
1569 // Gracefully handle case where finalizeOutputConfigurations is called
1570 // without any new surface.
1571 if (consumerSurfaces.size() == 0) {
1572 mStreamInfoMap[streamId].finalized = true;
1573 return res;
1574 }
1575
1576 // Finish the deferred stream configuration with the surface.
1577 status_t err;
1578 std::vector<int> consumerSurfaceIds;
1579 err = mDevice->setConsumerSurfaces(streamId, consumerSurfaces, &consumerSurfaceIds);
1580 if (err == OK) {
1581 for (size_t i = 0; i < consumerSurfaces.size(); i++) {
1582 sp<IBinder> binder = IInterface::asBinder(
1583 consumerSurfaces[i]->getIGraphicBufferProducer());
1584 ALOGV("%s: mStreamMap add binder %p streamId %d, surfaceId %d", __FUNCTION__,
1585 binder.get(), streamId, consumerSurfaceIds[i]);
1586 mStreamMap.add(binder, StreamSurfaceId(streamId, consumerSurfaceIds[i]));
1587 }
1588 if (deferredStreamIndex != NAME_NOT_FOUND) {
1589 mDeferredStreams.removeItemsAt(deferredStreamIndex);
1590 }
1591 mStreamInfoMap[streamId].finalized = true;
1592 mConfiguredOutputs.replaceValueFor(streamId, outputConfiguration);
1593 } else if (err == NO_INIT) {
1594 res = STATUS_ERROR_FMT(CameraService::ERROR_ILLEGAL_ARGUMENT,
1595 "Camera %s: Deferred surface is invalid: %s (%d)",
1596 mCameraIdStr.string(), strerror(-err), err);
1597 } else {
1598 res = STATUS_ERROR_FMT(CameraService::ERROR_INVALID_OPERATION,
1599 "Camera %s: Error setting output stream deferred surface: %s (%d)",
1600 mCameraIdStr.string(), strerror(-err), err);
1601 }
1602
1603 return res;
1604 }
1605
setCameraAudioRestriction(int32_t mode)1606 binder::Status CameraDeviceClient::setCameraAudioRestriction(int32_t mode) {
1607 ATRACE_CALL();
1608 binder::Status res;
1609 if (!(res = checkPidStatus(__FUNCTION__)).isOk()) return res;
1610
1611 if (!isValidAudioRestriction(mode)) {
1612 String8 msg = String8::format("Camera %s: invalid audio restriction mode %d",
1613 mCameraIdStr.string(), mode);
1614 ALOGW("%s: %s", __FUNCTION__, msg.string());
1615 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
1616 }
1617
1618 Mutex::Autolock icl(mBinderSerializationLock);
1619 BasicClient::setAudioRestriction(mode);
1620 return binder::Status::ok();
1621 }
1622
getGlobalAudioRestriction(int32_t * outMode)1623 binder::Status CameraDeviceClient::getGlobalAudioRestriction(/*out*/ int32_t* outMode) {
1624 ATRACE_CALL();
1625 binder::Status res;
1626 if (!(res = checkPidStatus(__FUNCTION__)).isOk()) return res;
1627 Mutex::Autolock icl(mBinderSerializationLock);
1628 if (outMode != nullptr) {
1629 *outMode = BasicClient::getServiceAudioRestriction();
1630 }
1631 return binder::Status::ok();
1632 }
1633
setRotateAndCropOverride(uint8_t rotateAndCrop)1634 status_t CameraDeviceClient::setRotateAndCropOverride(uint8_t rotateAndCrop) {
1635 if (rotateAndCrop > ANDROID_SCALER_ROTATE_AND_CROP_AUTO) return BAD_VALUE;
1636
1637 return mDevice->setRotateAndCropAutoBehavior(
1638 static_cast<camera_metadata_enum_android_scaler_rotate_and_crop_t>(rotateAndCrop));
1639 }
1640
supportsCameraMute()1641 bool CameraDeviceClient::supportsCameraMute() {
1642 return mDevice->supportsCameraMute();
1643 }
1644
setCameraMute(bool enabled)1645 status_t CameraDeviceClient::setCameraMute(bool enabled) {
1646 return mDevice->setCameraMute(enabled);
1647 }
1648
switchToOffline(const sp<hardware::camera2::ICameraDeviceCallbacks> & cameraCb,const std::vector<int> & offlineOutputIds,sp<hardware::camera2::ICameraOfflineSession> * session)1649 binder::Status CameraDeviceClient::switchToOffline(
1650 const sp<hardware::camera2::ICameraDeviceCallbacks>& cameraCb,
1651 const std::vector<int>& offlineOutputIds,
1652 /*out*/
1653 sp<hardware::camera2::ICameraOfflineSession>* session) {
1654 ATRACE_CALL();
1655
1656 binder::Status res;
1657 if (!(res = checkPidStatus(__FUNCTION__)).isOk()) return res;
1658
1659 Mutex::Autolock icl(mBinderSerializationLock);
1660
1661 if (!mDevice.get()) {
1662 return STATUS_ERROR(CameraService::ERROR_DISCONNECTED, "Camera device no longer alive");
1663 }
1664
1665 if (offlineOutputIds.empty()) {
1666 String8 msg = String8::format("Offline surfaces must not be empty");
1667 ALOGE("%s: %s", __FUNCTION__, msg.string());
1668 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
1669 }
1670
1671 if (session == nullptr) {
1672 String8 msg = String8::format("Invalid offline session");
1673 ALOGE("%s: %s", __FUNCTION__, msg.string());
1674 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
1675 }
1676
1677 std::vector<int32_t> offlineStreamIds;
1678 offlineStreamIds.reserve(offlineOutputIds.size());
1679 KeyedVector<sp<IBinder>, sp<CompositeStream>> offlineCompositeStreamMap;
1680 for (const auto& streamId : offlineOutputIds) {
1681 ssize_t index = mConfiguredOutputs.indexOfKey(streamId);
1682 if (index == NAME_NOT_FOUND) {
1683 String8 msg = String8::format("Offline surface with id: %d is not registered",
1684 streamId);
1685 ALOGE("%s: %s", __FUNCTION__, msg.string());
1686 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
1687 }
1688
1689 if (!mStreamInfoMap[streamId].supportsOffline) {
1690 String8 msg = String8::format("Offline surface with id: %d doesn't support "
1691 "offline mode", streamId);
1692 ALOGE("%s: %s", __FUNCTION__, msg.string());
1693 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT, msg.string());
1694 }
1695
1696 bool isCompositeStream = false;
1697 for (const auto& gbp : mConfiguredOutputs[streamId].getGraphicBufferProducers()) {
1698 sp<Surface> s = new Surface(gbp, false /*controlledByApp*/);
1699 isCompositeStream = camera3::DepthCompositeStream::isDepthCompositeStream(s) |
1700 camera3::HeicCompositeStream::isHeicCompositeStream(s);
1701 if (isCompositeStream) {
1702 auto compositeIdx = mCompositeStreamMap.indexOfKey(IInterface::asBinder(gbp));
1703 if (compositeIdx == NAME_NOT_FOUND) {
1704 ALOGE("%s: Unknown composite stream", __FUNCTION__);
1705 return STATUS_ERROR(CameraService::ERROR_ILLEGAL_ARGUMENT,
1706 "Unknown composite stream");
1707 }
1708
1709 mCompositeStreamMap.valueAt(compositeIdx)->insertCompositeStreamIds(
1710 &offlineStreamIds);
1711 offlineCompositeStreamMap.add(mCompositeStreamMap.keyAt(compositeIdx),
1712 mCompositeStreamMap.valueAt(compositeIdx));
1713 break;
1714 }
1715 }
1716
1717 if (!isCompositeStream) {
1718 offlineStreamIds.push_back(streamId);
1719 }
1720 }
1721
1722 sp<CameraOfflineSessionBase> offlineSession;
1723 auto ret = mDevice->switchToOffline(offlineStreamIds, &offlineSession);
1724 if (ret != OK) {
1725 return STATUS_ERROR_FMT(CameraService::ERROR_ILLEGAL_ARGUMENT,
1726 "Camera %s: Error switching to offline mode: %s (%d)",
1727 mCameraIdStr.string(), strerror(ret), ret);
1728 }
1729
1730 sp<CameraOfflineSessionClient> offlineClient;
1731 if (offlineSession.get() != nullptr) {
1732 offlineClient = new CameraOfflineSessionClient(sCameraService,
1733 offlineSession, offlineCompositeStreamMap, cameraCb, mClientPackageName,
1734 mClientFeatureId, mCameraIdStr, mCameraFacing, mOrientation, mClientPid, mClientUid,
1735 mServicePid);
1736 ret = sCameraService->addOfflineClient(mCameraIdStr, offlineClient);
1737 }
1738
1739 if (ret == OK) {
1740 // A successful offline session switch must reset the current camera client
1741 // and release any resources occupied by previously configured streams.
1742 mStreamMap.clear();
1743 mConfiguredOutputs.clear();
1744 mDeferredStreams.clear();
1745 mStreamInfoMap.clear();
1746 mCompositeStreamMap.clear();
1747 mInputStream = {false, 0, 0, 0, 0};
1748 } else {
1749 switch(ret) {
1750 case BAD_VALUE:
1751 return STATUS_ERROR_FMT(CameraService::ERROR_ILLEGAL_ARGUMENT,
1752 "Illegal argument to HAL module for camera \"%s\"", mCameraIdStr.c_str());
1753 case TIMED_OUT:
1754 return STATUS_ERROR_FMT(CameraService::ERROR_CAMERA_IN_USE,
1755 "Camera \"%s\" is already open", mCameraIdStr.c_str());
1756 default:
1757 return STATUS_ERROR_FMT(CameraService::ERROR_INVALID_OPERATION,
1758 "Failed to initialize camera \"%s\": %s (%d)", mCameraIdStr.c_str(),
1759 strerror(-ret), ret);
1760 }
1761 }
1762
1763 *session = offlineClient;
1764
1765 return binder::Status::ok();
1766 }
1767
dump(int fd,const Vector<String16> & args)1768 status_t CameraDeviceClient::dump(int fd, const Vector<String16>& args) {
1769 return BasicClient::dump(fd, args);
1770 }
1771
dumpClient(int fd,const Vector<String16> & args)1772 status_t CameraDeviceClient::dumpClient(int fd, const Vector<String16>& args) {
1773 dprintf(fd, " CameraDeviceClient[%s] (%p) dump:\n",
1774 mCameraIdStr.string(),
1775 (getRemoteCallback() != NULL ?
1776 IInterface::asBinder(getRemoteCallback()).get() : NULL) );
1777 dprintf(fd, " Current client UID %u\n", mClientUid);
1778
1779 dprintf(fd, " State:\n");
1780 dprintf(fd, " Request ID counter: %d\n", mRequestIdCounter);
1781 if (mInputStream.configured) {
1782 dprintf(fd, " Current input stream ID: %d\n", mInputStream.id);
1783 } else {
1784 dprintf(fd, " No input stream configured.\n");
1785 }
1786 if (!mStreamMap.isEmpty()) {
1787 dprintf(fd, " Current output stream/surface IDs:\n");
1788 for (size_t i = 0; i < mStreamMap.size(); i++) {
1789 dprintf(fd, " Stream %d Surface %d\n",
1790 mStreamMap.valueAt(i).streamId(),
1791 mStreamMap.valueAt(i).surfaceId());
1792 }
1793 } else if (!mDeferredStreams.isEmpty()) {
1794 dprintf(fd, " Current deferred surface output stream IDs:\n");
1795 for (auto& streamId : mDeferredStreams) {
1796 dprintf(fd, " Stream %d\n", streamId);
1797 }
1798 } else {
1799 dprintf(fd, " No output streams configured.\n");
1800 }
1801 // TODO: print dynamic/request section from most recent requests
1802 mFrameProcessor->dump(fd, args);
1803
1804 return dumpDevice(fd, args);
1805 }
1806
notifyError(int32_t errorCode,const CaptureResultExtras & resultExtras)1807 void CameraDeviceClient::notifyError(int32_t errorCode,
1808 const CaptureResultExtras& resultExtras) {
1809 // Thread safe. Don't bother locking.
1810 sp<hardware::camera2::ICameraDeviceCallbacks> remoteCb = getRemoteCallback();
1811
1812 // Composites can have multiple internal streams. Error notifications coming from such internal
1813 // streams may need to remain within camera service.
1814 bool skipClientNotification = false;
1815 for (size_t i = 0; i < mCompositeStreamMap.size(); i++) {
1816 skipClientNotification |= mCompositeStreamMap.valueAt(i)->onError(errorCode, resultExtras);
1817 }
1818
1819 if ((remoteCb != 0) && (!skipClientNotification)) {
1820 remoteCb->onDeviceError(errorCode, resultExtras);
1821 }
1822 }
1823
notifyRepeatingRequestError(long lastFrameNumber)1824 void CameraDeviceClient::notifyRepeatingRequestError(long lastFrameNumber) {
1825 sp<hardware::camera2::ICameraDeviceCallbacks> remoteCb = getRemoteCallback();
1826
1827 if (remoteCb != 0) {
1828 remoteCb->onRepeatingRequestError(lastFrameNumber, mStreamingRequestId);
1829 }
1830
1831 Mutex::Autolock idLock(mStreamingRequestIdLock);
1832 mStreamingRequestId = REQUEST_ID_NONE;
1833 }
1834
notifyIdle(int64_t requestCount,int64_t resultErrorCount,bool deviceError,const std::vector<hardware::CameraStreamStats> & streamStats)1835 void CameraDeviceClient::notifyIdle(
1836 int64_t requestCount, int64_t resultErrorCount, bool deviceError,
1837 const std::vector<hardware::CameraStreamStats>& streamStats) {
1838 // Thread safe. Don't bother locking.
1839 sp<hardware::camera2::ICameraDeviceCallbacks> remoteCb = getRemoteCallback();
1840
1841 if (remoteCb != 0) {
1842 remoteCb->onDeviceIdle();
1843 }
1844 Camera2ClientBase::notifyIdle(requestCount, resultErrorCount, deviceError, streamStats);
1845 }
1846
notifyShutter(const CaptureResultExtras & resultExtras,nsecs_t timestamp)1847 void CameraDeviceClient::notifyShutter(const CaptureResultExtras& resultExtras,
1848 nsecs_t timestamp) {
1849 // Thread safe. Don't bother locking.
1850 sp<hardware::camera2::ICameraDeviceCallbacks> remoteCb = getRemoteCallback();
1851 if (remoteCb != 0) {
1852 remoteCb->onCaptureStarted(resultExtras, timestamp);
1853 }
1854 Camera2ClientBase::notifyShutter(resultExtras, timestamp);
1855
1856 for (size_t i = 0; i < mCompositeStreamMap.size(); i++) {
1857 mCompositeStreamMap.valueAt(i)->onShutter(resultExtras, timestamp);
1858 }
1859 }
1860
notifyPrepared(int streamId)1861 void CameraDeviceClient::notifyPrepared(int streamId) {
1862 // Thread safe. Don't bother locking.
1863 sp<hardware::camera2::ICameraDeviceCallbacks> remoteCb = getRemoteCallback();
1864 if (remoteCb != 0) {
1865 remoteCb->onPrepared(streamId);
1866 }
1867 }
1868
notifyRequestQueueEmpty()1869 void CameraDeviceClient::notifyRequestQueueEmpty() {
1870 // Thread safe. Don't bother locking.
1871 sp<hardware::camera2::ICameraDeviceCallbacks> remoteCb = getRemoteCallback();
1872 if (remoteCb != 0) {
1873 remoteCb->onRequestQueueEmpty();
1874 }
1875 }
1876
detachDevice()1877 void CameraDeviceClient::detachDevice() {
1878 if (mDevice == 0) return;
1879
1880 nsecs_t startTime = systemTime();
1881 ALOGV("Camera %s: Stopping processors", mCameraIdStr.string());
1882
1883 mFrameProcessor->removeListener(camera2::FrameProcessorBase::FRAME_PROCESSOR_LISTENER_MIN_ID,
1884 camera2::FrameProcessorBase::FRAME_PROCESSOR_LISTENER_MAX_ID,
1885 /*listener*/this);
1886 mFrameProcessor->requestExit();
1887 ALOGV("Camera %s: Waiting for threads", mCameraIdStr.string());
1888 mFrameProcessor->join();
1889 ALOGV("Camera %s: Disconnecting device", mCameraIdStr.string());
1890
1891 // WORKAROUND: HAL refuses to disconnect while there's streams in flight
1892 {
1893 int64_t lastFrameNumber;
1894 status_t code;
1895 if ((code = mDevice->flush(&lastFrameNumber)) != OK) {
1896 ALOGE("%s: flush failed with code 0x%x", __FUNCTION__, code);
1897 }
1898
1899 if ((code = mDevice->waitUntilDrained()) != OK) {
1900 ALOGE("%s: waitUntilDrained failed with code 0x%x", __FUNCTION__,
1901 code);
1902 }
1903 }
1904
1905 for (size_t i = 0; i < mCompositeStreamMap.size(); i++) {
1906 auto ret = mCompositeStreamMap.valueAt(i)->deleteInternalStreams();
1907 if (ret != OK) {
1908 ALOGE("%s: Failed removing composite stream %s (%d)", __FUNCTION__,
1909 strerror(-ret), ret);
1910 }
1911 }
1912 mCompositeStreamMap.clear();
1913
1914 Camera2ClientBase::detachDevice();
1915
1916 int32_t closeLatencyMs = ns2ms(systemTime() - startTime);
1917 CameraServiceProxyWrapper::logClose(mCameraIdStr, closeLatencyMs);
1918 }
1919
1920 /** Device-related methods */
onResultAvailable(const CaptureResult & result)1921 void CameraDeviceClient::onResultAvailable(const CaptureResult& result) {
1922 ATRACE_CALL();
1923 ALOGV("%s", __FUNCTION__);
1924
1925 // Thread-safe. No lock necessary.
1926 sp<hardware::camera2::ICameraDeviceCallbacks> remoteCb = mRemoteCallback;
1927 if (remoteCb != NULL) {
1928 remoteCb->onResultReceived(result.mMetadata, result.mResultExtras,
1929 result.mPhysicalMetadatas);
1930 }
1931
1932 for (size_t i = 0; i < mCompositeStreamMap.size(); i++) {
1933 mCompositeStreamMap.valueAt(i)->onResultAvailable(result);
1934 }
1935 }
1936
checkPidStatus(const char * checkLocation)1937 binder::Status CameraDeviceClient::checkPidStatus(const char* checkLocation) {
1938 if (mDisconnected) {
1939 return STATUS_ERROR(CameraService::ERROR_DISCONNECTED,
1940 "The camera device has been disconnected");
1941 }
1942 status_t res = checkPid(checkLocation);
1943 return (res == OK) ? binder::Status::ok() :
1944 STATUS_ERROR(CameraService::ERROR_PERMISSION_DENIED,
1945 "Attempt to use camera from a different process than original client");
1946 }
1947
1948 // TODO: move to Camera2ClientBase
enforceRequestPermissions(CameraMetadata & metadata)1949 bool CameraDeviceClient::enforceRequestPermissions(CameraMetadata& metadata) {
1950
1951 const int pid = CameraThreadState::getCallingPid();
1952 const int selfPid = getpid();
1953 camera_metadata_entry_t entry;
1954
1955 /**
1956 * Mixin default important security values
1957 * - android.led.transmit = defaulted ON
1958 */
1959 CameraMetadata staticInfo = mDevice->info();
1960 entry = staticInfo.find(ANDROID_LED_AVAILABLE_LEDS);
1961 for(size_t i = 0; i < entry.count; ++i) {
1962 uint8_t led = entry.data.u8[i];
1963
1964 switch(led) {
1965 case ANDROID_LED_AVAILABLE_LEDS_TRANSMIT: {
1966 uint8_t transmitDefault = ANDROID_LED_TRANSMIT_ON;
1967 if (!metadata.exists(ANDROID_LED_TRANSMIT)) {
1968 metadata.update(ANDROID_LED_TRANSMIT,
1969 &transmitDefault, 1);
1970 }
1971 break;
1972 }
1973 }
1974 }
1975
1976 // We can do anything!
1977 if (pid == selfPid) {
1978 return true;
1979 }
1980
1981 /**
1982 * Permission check special fields in the request
1983 * - android.led.transmit = android.permission.CAMERA_DISABLE_TRANSMIT
1984 */
1985 entry = metadata.find(ANDROID_LED_TRANSMIT);
1986 if (entry.count > 0 && entry.data.u8[0] != ANDROID_LED_TRANSMIT_ON) {
1987 String16 permissionString =
1988 String16("android.permission.CAMERA_DISABLE_TRANSMIT_LED");
1989 if (!checkCallingPermission(permissionString)) {
1990 const int uid = CameraThreadState::getCallingUid();
1991 ALOGE("Permission Denial: "
1992 "can't disable transmit LED pid=%d, uid=%d", pid, uid);
1993 return false;
1994 }
1995 }
1996
1997 return true;
1998 }
1999
getRotationTransformLocked(int32_t * transform)2000 status_t CameraDeviceClient::getRotationTransformLocked(int32_t* transform) {
2001 ALOGV("%s: begin", __FUNCTION__);
2002
2003 const CameraMetadata& staticInfo = mDevice->info();
2004 return CameraUtils::getRotationTransform(staticInfo, transform);
2005 }
2006
mapRequestTemplate(int templateId,camera_request_template_t * tempId)2007 binder::Status CameraDeviceClient::mapRequestTemplate(int templateId,
2008 camera_request_template_t* tempId /*out*/) {
2009 binder::Status ret = binder::Status::ok();
2010
2011 if (tempId == nullptr) {
2012 ret = STATUS_ERROR_FMT(CameraService::ERROR_ILLEGAL_ARGUMENT,
2013 "Camera %s: Invalid template argument", mCameraIdStr.string());
2014 return ret;
2015 }
2016 switch(templateId) {
2017 case ICameraDeviceUser::TEMPLATE_PREVIEW:
2018 *tempId = camera_request_template_t::CAMERA_TEMPLATE_PREVIEW;
2019 break;
2020 case ICameraDeviceUser::TEMPLATE_RECORD:
2021 *tempId = camera_request_template_t::CAMERA_TEMPLATE_VIDEO_RECORD;
2022 break;
2023 case ICameraDeviceUser::TEMPLATE_STILL_CAPTURE:
2024 *tempId = camera_request_template_t::CAMERA_TEMPLATE_STILL_CAPTURE;
2025 break;
2026 case ICameraDeviceUser::TEMPLATE_VIDEO_SNAPSHOT:
2027 *tempId = camera_request_template_t::CAMERA_TEMPLATE_VIDEO_SNAPSHOT;
2028 break;
2029 case ICameraDeviceUser::TEMPLATE_ZERO_SHUTTER_LAG:
2030 *tempId = camera_request_template_t::CAMERA_TEMPLATE_ZERO_SHUTTER_LAG;
2031 break;
2032 case ICameraDeviceUser::TEMPLATE_MANUAL:
2033 *tempId = camera_request_template_t::CAMERA_TEMPLATE_MANUAL;
2034 break;
2035 default:
2036 ret = STATUS_ERROR_FMT(CameraService::ERROR_ILLEGAL_ARGUMENT,
2037 "Camera %s: Template ID %d is invalid or not supported",
2038 mCameraIdStr.string(), templateId);
2039 return ret;
2040 }
2041
2042 return ret;
2043 }
2044
getStaticInfo(const String8 & cameraId)2045 const CameraMetadata &CameraDeviceClient::getStaticInfo(const String8 &cameraId) {
2046 if (mDevice->getId() == cameraId) {
2047 return mDevice->info();
2048 }
2049 return mDevice->infoPhysical(cameraId);
2050 }
2051
isUltraHighResolutionSensor(const String8 & cameraId)2052 bool CameraDeviceClient::isUltraHighResolutionSensor(const String8 &cameraId) {
2053 const CameraMetadata &deviceInfo = getStaticInfo(cameraId);
2054 return SessionConfigurationUtils::isUltraHighResolutionSensor(deviceInfo);
2055 }
2056
isSensorPixelModeConsistent(const std::list<int> & streamIdList,const CameraMetadata & settings)2057 bool CameraDeviceClient::isSensorPixelModeConsistent(
2058 const std::list<int> &streamIdList, const CameraMetadata &settings) {
2059 // First we get the sensorPixelMode from the settings metadata.
2060 int32_t sensorPixelMode = ANDROID_SENSOR_PIXEL_MODE_DEFAULT;
2061 camera_metadata_ro_entry sensorPixelModeEntry = settings.find(ANDROID_SENSOR_PIXEL_MODE);
2062 if (sensorPixelModeEntry.count != 0) {
2063 sensorPixelMode = sensorPixelModeEntry.data.u8[0];
2064 if (sensorPixelMode != ANDROID_SENSOR_PIXEL_MODE_DEFAULT &&
2065 sensorPixelMode != ANDROID_SENSOR_PIXEL_MODE_MAXIMUM_RESOLUTION) {
2066 ALOGE("%s: Request sensor pixel mode not is not one of the valid values %d",
2067 __FUNCTION__, sensorPixelMode);
2068 return false;
2069 }
2070 }
2071 // Check whether each stream has max resolution allowed.
2072 bool consistent = true;
2073 for (auto it : streamIdList) {
2074 auto const streamInfoIt = mStreamInfoMap.find(it);
2075 if (streamInfoIt == mStreamInfoMap.end()) {
2076 ALOGE("%s: stream id %d not created, skipping", __FUNCTION__, it);
2077 return false;
2078 }
2079 consistent =
2080 streamInfoIt->second.sensorPixelModesUsed.find(sensorPixelMode) !=
2081 streamInfoIt->second.sensorPixelModesUsed.end();
2082 if (!consistent) {
2083 ALOGE("sensorPixelMode used %i not consistent with configured modes", sensorPixelMode);
2084 for (auto m : streamInfoIt->second.sensorPixelModesUsed) {
2085 ALOGE("sensor pixel mode used list: %i", m);
2086 }
2087 break;
2088 }
2089 }
2090
2091 return consistent;
2092 }
2093
2094 } // namespace android
2095