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 "Camera3-Device"
18 #define ATRACE_TAG ATRACE_TAG_CAMERA
19 //#define LOG_NDEBUG 0
20 //#define LOG_NNDEBUG 0 // Per-frame verbose logging
21
22 #ifdef LOG_NNDEBUG
23 #define ALOGVV(...) ALOGV(__VA_ARGS__)
24 #else
25 #define ALOGVV(...) ((void)0)
26 #endif
27
28 // Convenience macro for transient errors
29 #define CLOGE(fmt, ...) ALOGE("Camera %s: %s: " fmt, mId.string(), __FUNCTION__, \
30 ##__VA_ARGS__)
31
32 #define CLOGW(fmt, ...) ALOGW("Camera %s: %s: " fmt, mId.string(), __FUNCTION__, \
33 ##__VA_ARGS__)
34
35 // Convenience macros for transitioning to the error state
36 #define SET_ERR(fmt, ...) setErrorState( \
37 "%s: " fmt, __FUNCTION__, \
38 ##__VA_ARGS__)
39 #define SET_ERR_L(fmt, ...) setErrorStateLocked( \
40 "%s: " fmt, __FUNCTION__, \
41 ##__VA_ARGS__)
42
43 #include <inttypes.h>
44
45 #include <utility>
46
47 #include <utils/Log.h>
48 #include <utils/Trace.h>
49 #include <utils/Timers.h>
50 #include <cutils/properties.h>
51
52 #include <android/hardware/camera/device/3.7/ICameraInjectionSession.h>
53 #include <android/hardware/camera2/ICameraDeviceUser.h>
54
55 #include "utils/CameraTraces.h"
56 #include "mediautils/SchedulingPolicyService.h"
57 #include "device3/Camera3Device.h"
58 #include "device3/Camera3OutputStream.h"
59 #include "device3/Camera3InputStream.h"
60 #include "device3/Camera3FakeStream.h"
61 #include "device3/Camera3SharedOutputStream.h"
62 #include "CameraService.h"
63 #include "utils/CameraThreadState.h"
64 #include "utils/SessionConfigurationUtils.h"
65 #include "utils/TraceHFR.h"
66 #include "utils/CameraServiceProxyWrapper.h"
67
68 #include <algorithm>
69 #include <tuple>
70
71 using namespace android::camera3;
72 using namespace android::hardware::camera;
73 using namespace android::hardware::camera::device::V3_2;
74 using android::hardware::camera::metadata::V3_6::CameraMetadataEnumAndroidSensorPixelMode;
75
76 namespace android {
77
Camera3Device(const String8 & id,bool overrideForPerfClass)78 Camera3Device::Camera3Device(const String8 &id, bool overrideForPerfClass):
79 mId(id),
80 mOperatingMode(NO_MODE),
81 mIsConstrainedHighSpeedConfiguration(false),
82 mStatus(STATUS_UNINITIALIZED),
83 mStatusWaiters(0),
84 mUsePartialResult(false),
85 mNumPartialResults(1),
86 mTimestampOffset(0),
87 mNextResultFrameNumber(0),
88 mNextReprocessResultFrameNumber(0),
89 mNextZslStillResultFrameNumber(0),
90 mNextShutterFrameNumber(0),
91 mNextReprocessShutterFrameNumber(0),
92 mNextZslStillShutterFrameNumber(0),
93 mListener(NULL),
94 mVendorTagId(CAMERA_METADATA_INVALID_VENDOR_ID),
95 mLastTemplateId(-1),
96 mNeedFixupMonochromeTags(false),
97 mOverrideForPerfClass(overrideForPerfClass)
98 {
99 ATRACE_CALL();
100 ALOGV("%s: Created device for camera %s", __FUNCTION__, mId.string());
101 }
102
~Camera3Device()103 Camera3Device::~Camera3Device()
104 {
105 ATRACE_CALL();
106 ALOGV("%s: Tearing down for camera id %s", __FUNCTION__, mId.string());
107 disconnectImpl();
108 }
109
getId() const110 const String8& Camera3Device::getId() const {
111 return mId;
112 }
113
initialize(sp<CameraProviderManager> manager,const String8 & monitorTags)114 status_t Camera3Device::initialize(sp<CameraProviderManager> manager, const String8& monitorTags) {
115 ATRACE_CALL();
116 Mutex::Autolock il(mInterfaceLock);
117 Mutex::Autolock l(mLock);
118
119 ALOGV("%s: Initializing HIDL device for camera %s", __FUNCTION__, mId.string());
120 if (mStatus != STATUS_UNINITIALIZED) {
121 CLOGE("Already initialized!");
122 return INVALID_OPERATION;
123 }
124 if (manager == nullptr) return INVALID_OPERATION;
125
126 sp<ICameraDeviceSession> session;
127 ATRACE_BEGIN("CameraHal::openSession");
128 status_t res = manager->openSession(mId.string(), this,
129 /*out*/ &session);
130 ATRACE_END();
131 if (res != OK) {
132 SET_ERR_L("Could not open camera session: %s (%d)", strerror(-res), res);
133 return res;
134 }
135
136 res = manager->getCameraCharacteristics(mId.string(), mOverrideForPerfClass, &mDeviceInfo);
137 if (res != OK) {
138 SET_ERR_L("Could not retrieve camera characteristics: %s (%d)", strerror(-res), res);
139 session->close();
140 return res;
141 }
142 mSupportNativeZoomRatio = manager->supportNativeZoomRatio(mId.string());
143
144 std::vector<std::string> physicalCameraIds;
145 bool isLogical = manager->isLogicalCamera(mId.string(), &physicalCameraIds);
146 if (isLogical) {
147 for (auto& physicalId : physicalCameraIds) {
148 // Do not override characteristics for physical cameras
149 res = manager->getCameraCharacteristics(
150 physicalId, /*overrideForPerfClass*/false, &mPhysicalDeviceInfoMap[physicalId]);
151 if (res != OK) {
152 SET_ERR_L("Could not retrieve camera %s characteristics: %s (%d)",
153 physicalId.c_str(), strerror(-res), res);
154 session->close();
155 return res;
156 }
157
158 bool usePrecorrectArray =
159 DistortionMapper::isDistortionSupported(mPhysicalDeviceInfoMap[physicalId]);
160 if (usePrecorrectArray) {
161 res = mDistortionMappers[physicalId].setupStaticInfo(
162 mPhysicalDeviceInfoMap[physicalId]);
163 if (res != OK) {
164 SET_ERR_L("Unable to read camera %s's calibration fields for distortion "
165 "correction", physicalId.c_str());
166 session->close();
167 return res;
168 }
169 }
170
171 mZoomRatioMappers[physicalId] = ZoomRatioMapper(
172 &mPhysicalDeviceInfoMap[physicalId],
173 mSupportNativeZoomRatio, usePrecorrectArray);
174
175 if (SessionConfigurationUtils::isUltraHighResolutionSensor(
176 mPhysicalDeviceInfoMap[physicalId])) {
177 mUHRCropAndMeteringRegionMappers[physicalId] =
178 UHRCropAndMeteringRegionMapper(mPhysicalDeviceInfoMap[physicalId],
179 usePrecorrectArray);
180 }
181 }
182 }
183
184 std::shared_ptr<RequestMetadataQueue> queue;
185 auto requestQueueRet = session->getCaptureRequestMetadataQueue(
186 [&queue](const auto& descriptor) {
187 queue = std::make_shared<RequestMetadataQueue>(descriptor);
188 if (!queue->isValid() || queue->availableToWrite() <= 0) {
189 ALOGE("HAL returns empty request metadata fmq, not use it");
190 queue = nullptr;
191 // don't use the queue onwards.
192 }
193 });
194 if (!requestQueueRet.isOk()) {
195 ALOGE("Transaction error when getting request metadata fmq: %s, not use it",
196 requestQueueRet.description().c_str());
197 return DEAD_OBJECT;
198 }
199
200 std::unique_ptr<ResultMetadataQueue>& resQueue = mResultMetadataQueue;
201 auto resultQueueRet = session->getCaptureResultMetadataQueue(
202 [&resQueue](const auto& descriptor) {
203 resQueue = std::make_unique<ResultMetadataQueue>(descriptor);
204 if (!resQueue->isValid() || resQueue->availableToWrite() <= 0) {
205 ALOGE("HAL returns empty result metadata fmq, not use it");
206 resQueue = nullptr;
207 // Don't use the resQueue onwards.
208 }
209 });
210 if (!resultQueueRet.isOk()) {
211 ALOGE("Transaction error when getting result metadata queue from camera session: %s",
212 resultQueueRet.description().c_str());
213 return DEAD_OBJECT;
214 }
215 IF_ALOGV() {
216 session->interfaceChain([](
217 ::android::hardware::hidl_vec<::android::hardware::hidl_string> interfaceChain) {
218 ALOGV("Session interface chain:");
219 for (const auto& iface : interfaceChain) {
220 ALOGV(" %s", iface.c_str());
221 }
222 });
223 }
224
225 camera_metadata_entry bufMgrMode =
226 mDeviceInfo.find(ANDROID_INFO_SUPPORTED_BUFFER_MANAGEMENT_VERSION);
227 if (bufMgrMode.count > 0) {
228 mUseHalBufManager = (bufMgrMode.data.u8[0] ==
229 ANDROID_INFO_SUPPORTED_BUFFER_MANAGEMENT_VERSION_HIDL_DEVICE_3_5);
230 }
231
232 camera_metadata_entry_t capabilities = mDeviceInfo.find(ANDROID_REQUEST_AVAILABLE_CAPABILITIES);
233 for (size_t i = 0; i < capabilities.count; i++) {
234 uint8_t capability = capabilities.data.u8[i];
235 if (capability == ANDROID_REQUEST_AVAILABLE_CAPABILITIES_OFFLINE_PROCESSING) {
236 mSupportOfflineProcessing = true;
237 }
238 }
239
240 mInterface = new HalInterface(session, queue, mUseHalBufManager, mSupportOfflineProcessing);
241 std::string providerType;
242 mVendorTagId = manager->getProviderTagIdLocked(mId.string());
243 mTagMonitor.initialize(mVendorTagId);
244 if (!monitorTags.isEmpty()) {
245 mTagMonitor.parseTagsToMonitor(String8(monitorTags));
246 }
247
248 // Metadata tags needs fixup for monochrome camera device version less
249 // than 3.5.
250 hardware::hidl_version maxVersion{0,0};
251 res = manager->getHighestSupportedVersion(mId.string(), &maxVersion);
252 if (res != OK) {
253 ALOGE("%s: Error in getting camera device version id: %s (%d)",
254 __FUNCTION__, strerror(-res), res);
255 return res;
256 }
257 int deviceVersion = HARDWARE_DEVICE_API_VERSION(
258 maxVersion.get_major(), maxVersion.get_minor());
259
260 bool isMonochrome = false;
261 for (size_t i = 0; i < capabilities.count; i++) {
262 uint8_t capability = capabilities.data.u8[i];
263 if (capability == ANDROID_REQUEST_AVAILABLE_CAPABILITIES_MONOCHROME) {
264 isMonochrome = true;
265 }
266 }
267 mNeedFixupMonochromeTags = (isMonochrome && deviceVersion < CAMERA_DEVICE_API_VERSION_3_5);
268
269 return initializeCommonLocked();
270 }
271
initializeCommonLocked()272 status_t Camera3Device::initializeCommonLocked() {
273
274 /** Start up status tracker thread */
275 mStatusTracker = new StatusTracker(this);
276 status_t res = mStatusTracker->run(String8::format("C3Dev-%s-Status", mId.string()).string());
277 if (res != OK) {
278 SET_ERR_L("Unable to start status tracking thread: %s (%d)",
279 strerror(-res), res);
280 mInterface->close();
281 mStatusTracker.clear();
282 return res;
283 }
284
285 /** Register in-flight map to the status tracker */
286 mInFlightStatusId = mStatusTracker->addComponent("InflightRequests");
287
288 if (mUseHalBufManager) {
289 res = mRequestBufferSM.initialize(mStatusTracker);
290 if (res != OK) {
291 SET_ERR_L("Unable to start request buffer state machine: %s (%d)",
292 strerror(-res), res);
293 mInterface->close();
294 mStatusTracker.clear();
295 return res;
296 }
297 }
298
299 /** Create buffer manager */
300 mBufferManager = new Camera3BufferManager();
301
302 Vector<int32_t> sessionParamKeys;
303 camera_metadata_entry_t sessionKeysEntry = mDeviceInfo.find(
304 ANDROID_REQUEST_AVAILABLE_SESSION_KEYS);
305 if (sessionKeysEntry.count > 0) {
306 sessionParamKeys.insertArrayAt(sessionKeysEntry.data.i32, 0, sessionKeysEntry.count);
307 }
308
309 camera_metadata_entry_t availableTestPatternModes = mDeviceInfo.find(
310 ANDROID_SENSOR_AVAILABLE_TEST_PATTERN_MODES);
311 for (size_t i = 0; i < availableTestPatternModes.count; i++) {
312 if (availableTestPatternModes.data.i32[i] ==
313 ANDROID_SENSOR_TEST_PATTERN_MODE_SOLID_COLOR) {
314 mSupportCameraMute = true;
315 mSupportTestPatternSolidColor = true;
316 break;
317 } else if (availableTestPatternModes.data.i32[i] ==
318 ANDROID_SENSOR_TEST_PATTERN_MODE_BLACK) {
319 mSupportCameraMute = true;
320 mSupportTestPatternSolidColor = false;
321 }
322 }
323
324 /** Start up request queue thread */
325 mRequestThread = new RequestThread(
326 this, mStatusTracker, mInterface, sessionParamKeys,
327 mUseHalBufManager, mSupportCameraMute);
328 res = mRequestThread->run(String8::format("C3Dev-%s-ReqQueue", mId.string()).string());
329 if (res != OK) {
330 SET_ERR_L("Unable to start request queue thread: %s (%d)",
331 strerror(-res), res);
332 mInterface->close();
333 mRequestThread.clear();
334 return res;
335 }
336
337 mPreparerThread = new PreparerThread();
338
339 internalUpdateStatusLocked(STATUS_UNCONFIGURED);
340 mNextStreamId = 0;
341 mFakeStreamId = NO_STREAM;
342 mNeedConfig = true;
343 mPauseStateNotify = false;
344 mIsInputStreamMultiResolution = false;
345
346 // Measure the clock domain offset between camera and video/hw_composer
347 camera_metadata_entry timestampSource =
348 mDeviceInfo.find(ANDROID_SENSOR_INFO_TIMESTAMP_SOURCE);
349 if (timestampSource.count > 0 && timestampSource.data.u8[0] ==
350 ANDROID_SENSOR_INFO_TIMESTAMP_SOURCE_REALTIME) {
351 mTimestampOffset = getMonoToBoottimeOffset();
352 }
353
354 // Will the HAL be sending in early partial result metadata?
355 camera_metadata_entry partialResultsCount =
356 mDeviceInfo.find(ANDROID_REQUEST_PARTIAL_RESULT_COUNT);
357 if (partialResultsCount.count > 0) {
358 mNumPartialResults = partialResultsCount.data.i32[0];
359 mUsePartialResult = (mNumPartialResults > 1);
360 }
361
362 bool usePrecorrectArray = DistortionMapper::isDistortionSupported(mDeviceInfo);
363 if (usePrecorrectArray) {
364 res = mDistortionMappers[mId.c_str()].setupStaticInfo(mDeviceInfo);
365 if (res != OK) {
366 SET_ERR_L("Unable to read necessary calibration fields for distortion correction");
367 return res;
368 }
369 }
370
371 mZoomRatioMappers[mId.c_str()] = ZoomRatioMapper(&mDeviceInfo,
372 mSupportNativeZoomRatio, usePrecorrectArray);
373
374 if (SessionConfigurationUtils::isUltraHighResolutionSensor(mDeviceInfo)) {
375 mUHRCropAndMeteringRegionMappers[mId.c_str()] =
376 UHRCropAndMeteringRegionMapper(mDeviceInfo, usePrecorrectArray);
377 }
378
379 if (RotateAndCropMapper::isNeeded(&mDeviceInfo)) {
380 mRotateAndCropMappers.emplace(mId.c_str(), &mDeviceInfo);
381 }
382
383 mInjectionMethods = new Camera3DeviceInjectionMethods(this);
384
385 return OK;
386 }
387
disconnect()388 status_t Camera3Device::disconnect() {
389 return disconnectImpl();
390 }
391
disconnectImpl()392 status_t Camera3Device::disconnectImpl() {
393 ATRACE_CALL();
394 ALOGI("%s: E", __FUNCTION__);
395
396 status_t res = OK;
397 std::vector<wp<Camera3StreamInterface>> streams;
398 {
399 Mutex::Autolock il(mInterfaceLock);
400 nsecs_t maxExpectedDuration = getExpectedInFlightDuration();
401 {
402 Mutex::Autolock l(mLock);
403 if (mStatus == STATUS_UNINITIALIZED) return res;
404
405 if (mStatus == STATUS_ACTIVE ||
406 (mStatus == STATUS_ERROR && mRequestThread != NULL)) {
407 res = mRequestThread->clearRepeatingRequests();
408 if (res != OK) {
409 SET_ERR_L("Can't stop streaming");
410 // Continue to close device even in case of error
411 } else {
412 res = waitUntilStateThenRelock(/*active*/ false, maxExpectedDuration);
413 if (res != OK) {
414 SET_ERR_L("Timeout waiting for HAL to drain (% " PRIi64 " ns)",
415 maxExpectedDuration);
416 // Continue to close device even in case of error
417 }
418 }
419 }
420
421 if (mStatus == STATUS_ERROR) {
422 CLOGE("Shutting down in an error state");
423 }
424
425 if (mStatusTracker != NULL) {
426 mStatusTracker->requestExit();
427 }
428
429 if (mRequestThread != NULL) {
430 mRequestThread->requestExit();
431 }
432
433 streams.reserve(mOutputStreams.size() + (mInputStream != nullptr ? 1 : 0));
434 for (size_t i = 0; i < mOutputStreams.size(); i++) {
435 streams.push_back(mOutputStreams[i]);
436 }
437 if (mInputStream != nullptr) {
438 streams.push_back(mInputStream);
439 }
440 }
441 }
442 // Joining done without holding mLock and mInterfaceLock, otherwise deadlocks may ensue
443 // as the threads try to access parent state (b/143513518)
444 if (mRequestThread != NULL && mStatus != STATUS_ERROR) {
445 // HAL may be in a bad state, so waiting for request thread
446 // (which may be stuck in the HAL processCaptureRequest call)
447 // could be dangerous.
448 // give up mInterfaceLock here and then lock it again. Could this lead
449 // to other deadlocks
450 mRequestThread->join();
451 }
452 {
453 Mutex::Autolock il(mInterfaceLock);
454 if (mStatusTracker != NULL) {
455 mStatusTracker->join();
456 }
457
458 if (mInjectionMethods->isInjecting()) {
459 mInjectionMethods->stopInjection();
460 }
461
462 HalInterface* interface;
463 {
464 Mutex::Autolock l(mLock);
465 mRequestThread.clear();
466 Mutex::Autolock stLock(mTrackerLock);
467 mStatusTracker.clear();
468 interface = mInterface.get();
469 }
470
471 // Call close without internal mutex held, as the HAL close may need to
472 // wait on assorted callbacks,etc, to complete before it can return.
473 interface->close();
474
475 flushInflightRequests();
476
477 {
478 Mutex::Autolock l(mLock);
479 mInterface->clear();
480 mOutputStreams.clear();
481 mInputStream.clear();
482 mDeletedStreams.clear();
483 mBufferManager.clear();
484 internalUpdateStatusLocked(STATUS_UNINITIALIZED);
485 }
486
487 for (auto& weakStream : streams) {
488 sp<Camera3StreamInterface> stream = weakStream.promote();
489 if (stream != nullptr) {
490 ALOGE("%s: Stream %d leaked! strong reference (%d)!",
491 __FUNCTION__, stream->getId(), stream->getStrongCount() - 1);
492 }
493 }
494 }
495 ALOGI("%s: X", __FUNCTION__);
496 return res;
497 }
498
499 // For dumping/debugging only -
500 // try to acquire a lock a few times, eventually give up to proceed with
501 // debug/dump operations
tryLockSpinRightRound(Mutex & lock)502 bool Camera3Device::tryLockSpinRightRound(Mutex& lock) {
503 bool gotLock = false;
504 for (size_t i = 0; i < kDumpLockAttempts; ++i) {
505 if (lock.tryLock() == NO_ERROR) {
506 gotLock = true;
507 break;
508 } else {
509 usleep(kDumpSleepDuration);
510 }
511 }
512 return gotLock;
513 }
514
getMonoToBoottimeOffset()515 nsecs_t Camera3Device::getMonoToBoottimeOffset() {
516 // try three times to get the clock offset, choose the one
517 // with the minimum gap in measurements.
518 const int tries = 3;
519 nsecs_t bestGap, measured;
520 for (int i = 0; i < tries; ++i) {
521 const nsecs_t tmono = systemTime(SYSTEM_TIME_MONOTONIC);
522 const nsecs_t tbase = systemTime(SYSTEM_TIME_BOOTTIME);
523 const nsecs_t tmono2 = systemTime(SYSTEM_TIME_MONOTONIC);
524 const nsecs_t gap = tmono2 - tmono;
525 if (i == 0 || gap < bestGap) {
526 bestGap = gap;
527 measured = tbase - ((tmono + tmono2) >> 1);
528 }
529 }
530 return measured;
531 }
532
mapToPixelFormat(int frameworkFormat)533 hardware::graphics::common::V1_0::PixelFormat Camera3Device::mapToPixelFormat(
534 int frameworkFormat) {
535 return (hardware::graphics::common::V1_0::PixelFormat) frameworkFormat;
536 }
537
mapToHidlDataspace(android_dataspace dataSpace)538 DataspaceFlags Camera3Device::mapToHidlDataspace(
539 android_dataspace dataSpace) {
540 return dataSpace;
541 }
542
mapToConsumerUsage(uint64_t usage)543 BufferUsageFlags Camera3Device::mapToConsumerUsage(
544 uint64_t usage) {
545 return usage;
546 }
547
mapToStreamRotation(camera_stream_rotation_t rotation)548 StreamRotation Camera3Device::mapToStreamRotation(camera_stream_rotation_t rotation) {
549 switch (rotation) {
550 case CAMERA_STREAM_ROTATION_0:
551 return StreamRotation::ROTATION_0;
552 case CAMERA_STREAM_ROTATION_90:
553 return StreamRotation::ROTATION_90;
554 case CAMERA_STREAM_ROTATION_180:
555 return StreamRotation::ROTATION_180;
556 case CAMERA_STREAM_ROTATION_270:
557 return StreamRotation::ROTATION_270;
558 }
559 ALOGE("%s: Unknown stream rotation %d", __FUNCTION__, rotation);
560 return StreamRotation::ROTATION_0;
561 }
562
mapToStreamConfigurationMode(camera_stream_configuration_mode_t operationMode,StreamConfigurationMode * mode)563 status_t Camera3Device::mapToStreamConfigurationMode(
564 camera_stream_configuration_mode_t operationMode, StreamConfigurationMode *mode) {
565 if (mode == nullptr) return BAD_VALUE;
566 if (operationMode < CAMERA_VENDOR_STREAM_CONFIGURATION_MODE_START) {
567 switch(operationMode) {
568 case CAMERA_STREAM_CONFIGURATION_NORMAL_MODE:
569 *mode = StreamConfigurationMode::NORMAL_MODE;
570 break;
571 case CAMERA_STREAM_CONFIGURATION_CONSTRAINED_HIGH_SPEED_MODE:
572 *mode = StreamConfigurationMode::CONSTRAINED_HIGH_SPEED_MODE;
573 break;
574 default:
575 ALOGE("%s: Unknown stream configuration mode %d", __FUNCTION__, operationMode);
576 return BAD_VALUE;
577 }
578 } else {
579 *mode = static_cast<StreamConfigurationMode>(operationMode);
580 }
581 return OK;
582 }
583
mapToFrameworkFormat(hardware::graphics::common::V1_0::PixelFormat pixelFormat)584 int Camera3Device::mapToFrameworkFormat(
585 hardware::graphics::common::V1_0::PixelFormat pixelFormat) {
586 return static_cast<uint32_t>(pixelFormat);
587 }
588
mapToFrameworkDataspace(DataspaceFlags dataSpace)589 android_dataspace Camera3Device::mapToFrameworkDataspace(
590 DataspaceFlags dataSpace) {
591 return static_cast<android_dataspace>(dataSpace);
592 }
593
mapConsumerToFrameworkUsage(BufferUsageFlags usage)594 uint64_t Camera3Device::mapConsumerToFrameworkUsage(
595 BufferUsageFlags usage) {
596 return usage;
597 }
598
mapProducerToFrameworkUsage(BufferUsageFlags usage)599 uint64_t Camera3Device::mapProducerToFrameworkUsage(
600 BufferUsageFlags usage) {
601 return usage;
602 }
603
getJpegBufferSize(uint32_t width,uint32_t height) const604 ssize_t Camera3Device::getJpegBufferSize(uint32_t width, uint32_t height) const {
605 // Get max jpeg size (area-wise) for default sensor pixel mode
606 camera3::Size maxDefaultJpegResolution =
607 SessionConfigurationUtils::getMaxJpegResolution(mDeviceInfo,
608 /*isUltraHighResolutionSensor*/false);
609 // Get max jpeg size (area-wise) for max resolution sensor pixel mode / 0 if
610 // not ultra high res sensor
611 camera3::Size uhrMaxJpegResolution =
612 SessionConfigurationUtils::getMaxJpegResolution(mDeviceInfo,
613 /*isUltraHighResolution*/true);
614 if (maxDefaultJpegResolution.width == 0) {
615 ALOGE("%s: Camera %s: Can't find valid available jpeg sizes in static metadata!",
616 __FUNCTION__, mId.string());
617 return BAD_VALUE;
618 }
619 bool useMaxSensorPixelModeThreshold = false;
620 if (uhrMaxJpegResolution.width != 0 &&
621 width * height > maxDefaultJpegResolution.width * maxDefaultJpegResolution.height) {
622 // Use the ultra high res max jpeg size and max jpeg buffer size
623 useMaxSensorPixelModeThreshold = true;
624 }
625
626 // Get max jpeg buffer size
627 ssize_t maxJpegBufferSize = 0;
628 camera_metadata_ro_entry jpegBufMaxSize = mDeviceInfo.find(ANDROID_JPEG_MAX_SIZE);
629 if (jpegBufMaxSize.count == 0) {
630 ALOGE("%s: Camera %s: Can't find maximum JPEG size in static metadata!", __FUNCTION__,
631 mId.string());
632 return BAD_VALUE;
633 }
634 maxJpegBufferSize = jpegBufMaxSize.data.i32[0];
635
636 camera3::Size chosenMaxJpegResolution = maxDefaultJpegResolution;
637 if (useMaxSensorPixelModeThreshold) {
638 maxJpegBufferSize =
639 SessionConfigurationUtils::getUHRMaxJpegBufferSize(uhrMaxJpegResolution,
640 maxDefaultJpegResolution, maxJpegBufferSize);
641 chosenMaxJpegResolution = uhrMaxJpegResolution;
642 }
643 assert(kMinJpegBufferSize < maxJpegBufferSize);
644
645 // Calculate final jpeg buffer size for the given resolution.
646 float scaleFactor = ((float) (width * height)) /
647 (chosenMaxJpegResolution.width * chosenMaxJpegResolution.height);
648 ssize_t jpegBufferSize = scaleFactor * (maxJpegBufferSize - kMinJpegBufferSize) +
649 kMinJpegBufferSize;
650 if (jpegBufferSize > maxJpegBufferSize) {
651 ALOGI("%s: jpeg buffer size calculated is > maxJpeg bufferSize(%zd), clamping",
652 __FUNCTION__, maxJpegBufferSize);
653 jpegBufferSize = maxJpegBufferSize;
654 }
655 return jpegBufferSize;
656 }
657
getPointCloudBufferSize() const658 ssize_t Camera3Device::getPointCloudBufferSize() const {
659 const int FLOATS_PER_POINT=4;
660 camera_metadata_ro_entry maxPointCount = mDeviceInfo.find(ANDROID_DEPTH_MAX_DEPTH_SAMPLES);
661 if (maxPointCount.count == 0) {
662 ALOGE("%s: Camera %s: Can't find maximum depth point cloud size in static metadata!",
663 __FUNCTION__, mId.string());
664 return BAD_VALUE;
665 }
666 ssize_t maxBytesForPointCloud = sizeof(android_depth_points) +
667 maxPointCount.data.i32[0] * sizeof(float) * FLOATS_PER_POINT;
668 return maxBytesForPointCloud;
669 }
670
getRawOpaqueBufferSize(int32_t width,int32_t height,bool maxResolution) const671 ssize_t Camera3Device::getRawOpaqueBufferSize(int32_t width, int32_t height,
672 bool maxResolution) const {
673 const int PER_CONFIGURATION_SIZE = 3;
674 const int WIDTH_OFFSET = 0;
675 const int HEIGHT_OFFSET = 1;
676 const int SIZE_OFFSET = 2;
677 camera_metadata_ro_entry rawOpaqueSizes =
678 mDeviceInfo.find(
679 camera3::SessionConfigurationUtils::getAppropriateModeTag(
680 ANDROID_SENSOR_OPAQUE_RAW_SIZE,
681 maxResolution));
682 size_t count = rawOpaqueSizes.count;
683 if (count == 0 || (count % PER_CONFIGURATION_SIZE)) {
684 ALOGE("%s: Camera %s: bad opaque RAW size static metadata length(%zu)!",
685 __FUNCTION__, mId.string(), count);
686 return BAD_VALUE;
687 }
688
689 for (size_t i = 0; i < count; i += PER_CONFIGURATION_SIZE) {
690 if (width == rawOpaqueSizes.data.i32[i + WIDTH_OFFSET] &&
691 height == rawOpaqueSizes.data.i32[i + HEIGHT_OFFSET]) {
692 return rawOpaqueSizes.data.i32[i + SIZE_OFFSET];
693 }
694 }
695
696 ALOGE("%s: Camera %s: cannot find size for %dx%d opaque RAW image!",
697 __FUNCTION__, mId.string(), width, height);
698 return BAD_VALUE;
699 }
700
dump(int fd,const Vector<String16> & args)701 status_t Camera3Device::dump(int fd, const Vector<String16> &args) {
702 ATRACE_CALL();
703 (void)args;
704
705 // Try to lock, but continue in case of failure (to avoid blocking in
706 // deadlocks)
707 bool gotInterfaceLock = tryLockSpinRightRound(mInterfaceLock);
708 bool gotLock = tryLockSpinRightRound(mLock);
709
710 ALOGW_IF(!gotInterfaceLock,
711 "Camera %s: %s: Unable to lock interface lock, proceeding anyway",
712 mId.string(), __FUNCTION__);
713 ALOGW_IF(!gotLock,
714 "Camera %s: %s: Unable to lock main lock, proceeding anyway",
715 mId.string(), __FUNCTION__);
716
717 bool dumpTemplates = false;
718
719 String16 templatesOption("-t");
720 int n = args.size();
721 for (int i = 0; i < n; i++) {
722 if (args[i] == templatesOption) {
723 dumpTemplates = true;
724 }
725 if (args[i] == TagMonitor::kMonitorOption) {
726 if (i + 1 < n) {
727 String8 monitorTags = String8(args[i + 1]);
728 if (monitorTags == "off") {
729 mTagMonitor.disableMonitoring();
730 } else {
731 mTagMonitor.parseTagsToMonitor(monitorTags);
732 }
733 } else {
734 mTagMonitor.disableMonitoring();
735 }
736 }
737 }
738
739 String8 lines;
740
741 const char *status =
742 mStatus == STATUS_ERROR ? "ERROR" :
743 mStatus == STATUS_UNINITIALIZED ? "UNINITIALIZED" :
744 mStatus == STATUS_UNCONFIGURED ? "UNCONFIGURED" :
745 mStatus == STATUS_CONFIGURED ? "CONFIGURED" :
746 mStatus == STATUS_ACTIVE ? "ACTIVE" :
747 "Unknown";
748
749 lines.appendFormat(" Device status: %s\n", status);
750 if (mStatus == STATUS_ERROR) {
751 lines.appendFormat(" Error cause: %s\n", mErrorCause.string());
752 }
753 lines.appendFormat(" Stream configuration:\n");
754 const char *mode =
755 mOperatingMode == static_cast<int>(StreamConfigurationMode::NORMAL_MODE) ? "NORMAL" :
756 mOperatingMode == static_cast<int>(
757 StreamConfigurationMode::CONSTRAINED_HIGH_SPEED_MODE) ? "CONSTRAINED_HIGH_SPEED" :
758 "CUSTOM";
759 lines.appendFormat(" Operation mode: %s (%d) \n", mode, mOperatingMode);
760
761 if (mInputStream != NULL) {
762 write(fd, lines.string(), lines.size());
763 mInputStream->dump(fd, args);
764 } else {
765 lines.appendFormat(" No input stream.\n");
766 write(fd, lines.string(), lines.size());
767 }
768 for (size_t i = 0; i < mOutputStreams.size(); i++) {
769 mOutputStreams[i]->dump(fd,args);
770 }
771
772 if (mBufferManager != NULL) {
773 lines = String8(" Camera3 Buffer Manager:\n");
774 write(fd, lines.string(), lines.size());
775 mBufferManager->dump(fd, args);
776 }
777
778 lines = String8(" In-flight requests:\n");
779 if (mInFlightLock.try_lock()) {
780 if (mInFlightMap.size() == 0) {
781 lines.append(" None\n");
782 } else {
783 for (size_t i = 0; i < mInFlightMap.size(); i++) {
784 InFlightRequest r = mInFlightMap.valueAt(i);
785 lines.appendFormat(" Frame %d | Timestamp: %" PRId64 ", metadata"
786 " arrived: %s, buffers left: %d\n", mInFlightMap.keyAt(i),
787 r.shutterTimestamp, r.haveResultMetadata ? "true" : "false",
788 r.numBuffersLeft);
789 }
790 }
791 mInFlightLock.unlock();
792 } else {
793 lines.append(" Failed to acquire In-flight lock!\n");
794 }
795 write(fd, lines.string(), lines.size());
796
797 if (mRequestThread != NULL) {
798 mRequestThread->dumpCaptureRequestLatency(fd,
799 " ProcessCaptureRequest latency histogram:");
800 }
801
802 {
803 lines = String8(" Last request sent:\n");
804 write(fd, lines.string(), lines.size());
805
806 CameraMetadata lastRequest = getLatestRequestLocked();
807 lastRequest.dump(fd, /*verbosity*/2, /*indentation*/6);
808 }
809
810 if (dumpTemplates) {
811 const char *templateNames[CAMERA_TEMPLATE_COUNT] = {
812 "TEMPLATE_PREVIEW",
813 "TEMPLATE_STILL_CAPTURE",
814 "TEMPLATE_VIDEO_RECORD",
815 "TEMPLATE_VIDEO_SNAPSHOT",
816 "TEMPLATE_ZERO_SHUTTER_LAG",
817 "TEMPLATE_MANUAL",
818 };
819
820 for (int i = 1; i < CAMERA_TEMPLATE_COUNT; i++) {
821 camera_metadata_t *templateRequest = nullptr;
822 mInterface->constructDefaultRequestSettings(
823 (camera_request_template_t) i, &templateRequest);
824 lines = String8::format(" HAL Request %s:\n", templateNames[i-1]);
825 if (templateRequest == nullptr) {
826 lines.append(" Not supported\n");
827 write(fd, lines.string(), lines.size());
828 } else {
829 write(fd, lines.string(), lines.size());
830 dump_indented_camera_metadata(templateRequest,
831 fd, /*verbosity*/2, /*indentation*/8);
832 }
833 free_camera_metadata(templateRequest);
834 }
835 }
836
837 mTagMonitor.dumpMonitoredMetadata(fd);
838
839 if (mInterface->valid()) {
840 lines = String8(" HAL device dump:\n");
841 write(fd, lines.string(), lines.size());
842 mInterface->dump(fd);
843 }
844
845 if (gotLock) mLock.unlock();
846 if (gotInterfaceLock) mInterfaceLock.unlock();
847
848 return OK;
849 }
850
infoPhysical(const String8 & physicalId) const851 const CameraMetadata& Camera3Device::infoPhysical(const String8& physicalId) const {
852 ALOGVV("%s: E", __FUNCTION__);
853 if (CC_UNLIKELY(mStatus == STATUS_UNINITIALIZED ||
854 mStatus == STATUS_ERROR)) {
855 ALOGW("%s: Access to static info %s!", __FUNCTION__,
856 mStatus == STATUS_ERROR ?
857 "when in error state" : "before init");
858 }
859 if (physicalId.isEmpty()) {
860 return mDeviceInfo;
861 } else {
862 std::string id(physicalId.c_str());
863 if (mPhysicalDeviceInfoMap.find(id) != mPhysicalDeviceInfoMap.end()) {
864 return mPhysicalDeviceInfoMap.at(id);
865 } else {
866 ALOGE("%s: Invalid physical camera id %s", __FUNCTION__, physicalId.c_str());
867 return mDeviceInfo;
868 }
869 }
870 }
871
info() const872 const CameraMetadata& Camera3Device::info() const {
873 String8 emptyId;
874 return infoPhysical(emptyId);
875 }
876
checkStatusOkToCaptureLocked()877 status_t Camera3Device::checkStatusOkToCaptureLocked() {
878 switch (mStatus) {
879 case STATUS_ERROR:
880 CLOGE("Device has encountered a serious error");
881 return INVALID_OPERATION;
882 case STATUS_UNINITIALIZED:
883 CLOGE("Device not initialized");
884 return INVALID_OPERATION;
885 case STATUS_UNCONFIGURED:
886 case STATUS_CONFIGURED:
887 case STATUS_ACTIVE:
888 // OK
889 break;
890 default:
891 SET_ERR_L("Unexpected status: %d", mStatus);
892 return INVALID_OPERATION;
893 }
894 return OK;
895 }
896
convertMetadataListToRequestListLocked(const List<const PhysicalCameraSettingsList> & metadataList,const std::list<const SurfaceMap> & surfaceMaps,bool repeating,nsecs_t requestTimeNs,RequestList * requestList)897 status_t Camera3Device::convertMetadataListToRequestListLocked(
898 const List<const PhysicalCameraSettingsList> &metadataList,
899 const std::list<const SurfaceMap> &surfaceMaps,
900 bool repeating, nsecs_t requestTimeNs,
901 RequestList *requestList) {
902 if (requestList == NULL) {
903 CLOGE("requestList cannot be NULL.");
904 return BAD_VALUE;
905 }
906
907 int32_t burstId = 0;
908 List<const PhysicalCameraSettingsList>::const_iterator metadataIt = metadataList.begin();
909 std::list<const SurfaceMap>::const_iterator surfaceMapIt = surfaceMaps.begin();
910 for (; metadataIt != metadataList.end() && surfaceMapIt != surfaceMaps.end();
911 ++metadataIt, ++surfaceMapIt) {
912 sp<CaptureRequest> newRequest = setUpRequestLocked(*metadataIt, *surfaceMapIt);
913 if (newRequest == 0) {
914 CLOGE("Can't create capture request");
915 return BAD_VALUE;
916 }
917
918 newRequest->mRepeating = repeating;
919 newRequest->mRequestTimeNs = requestTimeNs;
920
921 // Setup burst Id and request Id
922 newRequest->mResultExtras.burstId = burstId++;
923 auto requestIdEntry = metadataIt->begin()->metadata.find(ANDROID_REQUEST_ID);
924 if (requestIdEntry.count == 0) {
925 CLOGE("RequestID does not exist in metadata");
926 return BAD_VALUE;
927 }
928 newRequest->mResultExtras.requestId = requestIdEntry.data.i32[0];
929
930 requestList->push_back(newRequest);
931
932 ALOGV("%s: requestId = %" PRId32, __FUNCTION__, newRequest->mResultExtras.requestId);
933 }
934 if (metadataIt != metadataList.end() || surfaceMapIt != surfaceMaps.end()) {
935 ALOGE("%s: metadataList and surfaceMaps are not the same size!", __FUNCTION__);
936 return BAD_VALUE;
937 }
938
939 // Setup batch size if this is a high speed video recording request.
940 if (mIsConstrainedHighSpeedConfiguration && requestList->size() > 0) {
941 auto firstRequest = requestList->begin();
942 for (auto& outputStream : (*firstRequest)->mOutputStreams) {
943 if (outputStream->isVideoStream()) {
944 (*firstRequest)->mBatchSize = requestList->size();
945 outputStream->setBatchSize(requestList->size());
946 break;
947 }
948 }
949 }
950
951 return OK;
952 }
953
capture(CameraMetadata & request,int64_t * lastFrameNumber)954 status_t Camera3Device::capture(CameraMetadata &request, int64_t* lastFrameNumber) {
955 ATRACE_CALL();
956
957 List<const PhysicalCameraSettingsList> requestsList;
958 std::list<const SurfaceMap> surfaceMaps;
959 convertToRequestList(requestsList, surfaceMaps, request);
960
961 return captureList(requestsList, surfaceMaps, lastFrameNumber);
962 }
963
convertToRequestList(List<const PhysicalCameraSettingsList> & requestsList,std::list<const SurfaceMap> & surfaceMaps,const CameraMetadata & request)964 void Camera3Device::convertToRequestList(List<const PhysicalCameraSettingsList>& requestsList,
965 std::list<const SurfaceMap>& surfaceMaps,
966 const CameraMetadata& request) {
967 PhysicalCameraSettingsList requestList;
968 requestList.push_back({std::string(getId().string()), request});
969 requestsList.push_back(requestList);
970
971 SurfaceMap surfaceMap;
972 camera_metadata_ro_entry streams = request.find(ANDROID_REQUEST_OUTPUT_STREAMS);
973 // With no surface list passed in, stream and surface will have 1-to-1
974 // mapping. So the surface index is 0 for each stream in the surfaceMap.
975 for (size_t i = 0; i < streams.count; i++) {
976 surfaceMap[streams.data.i32[i]].push_back(0);
977 }
978 surfaceMaps.push_back(surfaceMap);
979 }
980
submitRequestsHelper(const List<const PhysicalCameraSettingsList> & requests,const std::list<const SurfaceMap> & surfaceMaps,bool repeating,int64_t * lastFrameNumber)981 status_t Camera3Device::submitRequestsHelper(
982 const List<const PhysicalCameraSettingsList> &requests,
983 const std::list<const SurfaceMap> &surfaceMaps,
984 bool repeating,
985 /*out*/
986 int64_t *lastFrameNumber) {
987 ATRACE_CALL();
988 nsecs_t requestTimeNs = systemTime();
989
990 Mutex::Autolock il(mInterfaceLock);
991 Mutex::Autolock l(mLock);
992
993 status_t res = checkStatusOkToCaptureLocked();
994 if (res != OK) {
995 // error logged by previous call
996 return res;
997 }
998
999 RequestList requestList;
1000
1001 res = convertMetadataListToRequestListLocked(requests, surfaceMaps,
1002 repeating, requestTimeNs, /*out*/&requestList);
1003 if (res != OK) {
1004 // error logged by previous call
1005 return res;
1006 }
1007
1008 if (repeating) {
1009 res = mRequestThread->setRepeatingRequests(requestList, lastFrameNumber);
1010 } else {
1011 res = mRequestThread->queueRequestList(requestList, lastFrameNumber);
1012 }
1013
1014 if (res == OK) {
1015 waitUntilStateThenRelock(/*active*/true, kActiveTimeout);
1016 if (res != OK) {
1017 SET_ERR_L("Can't transition to active in %f seconds!",
1018 kActiveTimeout/1e9);
1019 }
1020 ALOGV("Camera %s: Capture request %" PRId32 " enqueued", mId.string(),
1021 (*(requestList.begin()))->mResultExtras.requestId);
1022 } else {
1023 CLOGE("Cannot queue request. Impossible.");
1024 return BAD_VALUE;
1025 }
1026
1027 return res;
1028 }
1029
requestStreamBuffers(const hardware::hidl_vec<hardware::camera::device::V3_5::BufferRequest> & bufReqs,requestStreamBuffers_cb _hidl_cb)1030 hardware::Return<void> Camera3Device::requestStreamBuffers(
1031 const hardware::hidl_vec<hardware::camera::device::V3_5::BufferRequest>& bufReqs,
1032 requestStreamBuffers_cb _hidl_cb) {
1033 RequestBufferStates states {
1034 mId, mRequestBufferInterfaceLock, mUseHalBufManager, mOutputStreams, mSessionStatsBuilder,
1035 *this, *mInterface, *this};
1036 camera3::requestStreamBuffers(states, bufReqs, _hidl_cb);
1037 return hardware::Void();
1038 }
1039
returnStreamBuffers(const hardware::hidl_vec<hardware::camera::device::V3_2::StreamBuffer> & buffers)1040 hardware::Return<void> Camera3Device::returnStreamBuffers(
1041 const hardware::hidl_vec<hardware::camera::device::V3_2::StreamBuffer>& buffers) {
1042 ReturnBufferStates states {
1043 mId, mUseHalBufManager, mOutputStreams, mSessionStatsBuilder, *mInterface};
1044 camera3::returnStreamBuffers(states, buffers);
1045 return hardware::Void();
1046 }
1047
processCaptureResult_3_4(const hardware::hidl_vec<hardware::camera::device::V3_4::CaptureResult> & results)1048 hardware::Return<void> Camera3Device::processCaptureResult_3_4(
1049 const hardware::hidl_vec<
1050 hardware::camera::device::V3_4::CaptureResult>& results) {
1051 // Ideally we should grab mLock, but that can lead to deadlock, and
1052 // it's not super important to get up to date value of mStatus for this
1053 // warning print, hence skipping the lock here
1054 if (mStatus == STATUS_ERROR) {
1055 // Per API contract, HAL should act as closed after device error
1056 // But mStatus can be set to error by framework as well, so just log
1057 // a warning here.
1058 ALOGW("%s: received capture result in error state.", __FUNCTION__);
1059 }
1060
1061 sp<NotificationListener> listener;
1062 {
1063 std::lock_guard<std::mutex> l(mOutputLock);
1064 listener = mListener.promote();
1065 }
1066
1067 if (mProcessCaptureResultLock.tryLock() != OK) {
1068 // This should never happen; it indicates a wrong client implementation
1069 // that doesn't follow the contract. But, we can be tolerant here.
1070 ALOGE("%s: callback overlapped! waiting 1s...",
1071 __FUNCTION__);
1072 if (mProcessCaptureResultLock.timedLock(1000000000 /* 1s */) != OK) {
1073 ALOGE("%s: cannot acquire lock in 1s, dropping results",
1074 __FUNCTION__);
1075 // really don't know what to do, so bail out.
1076 return hardware::Void();
1077 }
1078 }
1079 CaptureOutputStates states {
1080 mId,
1081 mInFlightLock, mLastCompletedRegularFrameNumber,
1082 mLastCompletedReprocessFrameNumber, mLastCompletedZslFrameNumber,
1083 mInFlightMap, mOutputLock, mResultQueue, mResultSignal,
1084 mNextShutterFrameNumber,
1085 mNextReprocessShutterFrameNumber, mNextZslStillShutterFrameNumber,
1086 mNextResultFrameNumber,
1087 mNextReprocessResultFrameNumber, mNextZslStillResultFrameNumber,
1088 mUseHalBufManager, mUsePartialResult, mNeedFixupMonochromeTags,
1089 mNumPartialResults, mVendorTagId, mDeviceInfo, mPhysicalDeviceInfoMap,
1090 mResultMetadataQueue, mDistortionMappers, mZoomRatioMappers, mRotateAndCropMappers,
1091 mTagMonitor, mInputStream, mOutputStreams, mSessionStatsBuilder, listener, *this, *this,
1092 *mInterface
1093 };
1094
1095 for (const auto& result : results) {
1096 processOneCaptureResultLocked(states, result.v3_2, result.physicalCameraMetadata);
1097 }
1098 mProcessCaptureResultLock.unlock();
1099 return hardware::Void();
1100 }
1101
1102 // Only one processCaptureResult should be called at a time, so
1103 // the locks won't block. The locks are present here simply to enforce this.
processCaptureResult(const hardware::hidl_vec<hardware::camera::device::V3_2::CaptureResult> & results)1104 hardware::Return<void> Camera3Device::processCaptureResult(
1105 const hardware::hidl_vec<
1106 hardware::camera::device::V3_2::CaptureResult>& results) {
1107 hardware::hidl_vec<hardware::camera::device::V3_4::PhysicalCameraMetadata> noPhysMetadata;
1108
1109 // Ideally we should grab mLock, but that can lead to deadlock, and
1110 // it's not super important to get up to date value of mStatus for this
1111 // warning print, hence skipping the lock here
1112 if (mStatus == STATUS_ERROR) {
1113 // Per API contract, HAL should act as closed after device error
1114 // But mStatus can be set to error by framework as well, so just log
1115 // a warning here.
1116 ALOGW("%s: received capture result in error state.", __FUNCTION__);
1117 }
1118
1119 sp<NotificationListener> listener;
1120 {
1121 std::lock_guard<std::mutex> l(mOutputLock);
1122 listener = mListener.promote();
1123 }
1124
1125 if (mProcessCaptureResultLock.tryLock() != OK) {
1126 // This should never happen; it indicates a wrong client implementation
1127 // that doesn't follow the contract. But, we can be tolerant here.
1128 ALOGE("%s: callback overlapped! waiting 1s...",
1129 __FUNCTION__);
1130 if (mProcessCaptureResultLock.timedLock(1000000000 /* 1s */) != OK) {
1131 ALOGE("%s: cannot acquire lock in 1s, dropping results",
1132 __FUNCTION__);
1133 // really don't know what to do, so bail out.
1134 return hardware::Void();
1135 }
1136 }
1137
1138 CaptureOutputStates states {
1139 mId,
1140 mInFlightLock, mLastCompletedRegularFrameNumber,
1141 mLastCompletedReprocessFrameNumber, mLastCompletedZslFrameNumber,
1142 mInFlightMap, mOutputLock, mResultQueue, mResultSignal,
1143 mNextShutterFrameNumber,
1144 mNextReprocessShutterFrameNumber, mNextZslStillShutterFrameNumber,
1145 mNextResultFrameNumber,
1146 mNextReprocessResultFrameNumber, mNextZslStillResultFrameNumber,
1147 mUseHalBufManager, mUsePartialResult, mNeedFixupMonochromeTags,
1148 mNumPartialResults, mVendorTagId, mDeviceInfo, mPhysicalDeviceInfoMap,
1149 mResultMetadataQueue, mDistortionMappers, mZoomRatioMappers, mRotateAndCropMappers,
1150 mTagMonitor, mInputStream, mOutputStreams, mSessionStatsBuilder, listener, *this, *this,
1151 *mInterface
1152 };
1153
1154 for (const auto& result : results) {
1155 processOneCaptureResultLocked(states, result, noPhysMetadata);
1156 }
1157 mProcessCaptureResultLock.unlock();
1158 return hardware::Void();
1159 }
1160
notify(const hardware::hidl_vec<hardware::camera::device::V3_2::NotifyMsg> & msgs)1161 hardware::Return<void> Camera3Device::notify(
1162 const hardware::hidl_vec<hardware::camera::device::V3_2::NotifyMsg>& msgs) {
1163 // Ideally we should grab mLock, but that can lead to deadlock, and
1164 // it's not super important to get up to date value of mStatus for this
1165 // warning print, hence skipping the lock here
1166 if (mStatus == STATUS_ERROR) {
1167 // Per API contract, HAL should act as closed after device error
1168 // But mStatus can be set to error by framework as well, so just log
1169 // a warning here.
1170 ALOGW("%s: received notify message in error state.", __FUNCTION__);
1171 }
1172
1173 sp<NotificationListener> listener;
1174 {
1175 std::lock_guard<std::mutex> l(mOutputLock);
1176 listener = mListener.promote();
1177 }
1178
1179 CaptureOutputStates states {
1180 mId,
1181 mInFlightLock, mLastCompletedRegularFrameNumber,
1182 mLastCompletedReprocessFrameNumber, mLastCompletedZslFrameNumber,
1183 mInFlightMap, mOutputLock, mResultQueue, mResultSignal,
1184 mNextShutterFrameNumber,
1185 mNextReprocessShutterFrameNumber, mNextZslStillShutterFrameNumber,
1186 mNextResultFrameNumber,
1187 mNextReprocessResultFrameNumber, mNextZslStillResultFrameNumber,
1188 mUseHalBufManager, mUsePartialResult, mNeedFixupMonochromeTags,
1189 mNumPartialResults, mVendorTagId, mDeviceInfo, mPhysicalDeviceInfoMap,
1190 mResultMetadataQueue, mDistortionMappers, mZoomRatioMappers, mRotateAndCropMappers,
1191 mTagMonitor, mInputStream, mOutputStreams, mSessionStatsBuilder, listener, *this, *this,
1192 *mInterface
1193 };
1194 for (const auto& msg : msgs) {
1195 camera3::notify(states, msg);
1196 }
1197 return hardware::Void();
1198 }
1199
captureList(const List<const PhysicalCameraSettingsList> & requestsList,const std::list<const SurfaceMap> & surfaceMaps,int64_t * lastFrameNumber)1200 status_t Camera3Device::captureList(const List<const PhysicalCameraSettingsList> &requestsList,
1201 const std::list<const SurfaceMap> &surfaceMaps,
1202 int64_t *lastFrameNumber) {
1203 ATRACE_CALL();
1204
1205 return submitRequestsHelper(requestsList, surfaceMaps, /*repeating*/false, lastFrameNumber);
1206 }
1207
setStreamingRequest(const CameraMetadata & request,int64_t *)1208 status_t Camera3Device::setStreamingRequest(const CameraMetadata &request,
1209 int64_t* /*lastFrameNumber*/) {
1210 ATRACE_CALL();
1211
1212 List<const PhysicalCameraSettingsList> requestsList;
1213 std::list<const SurfaceMap> surfaceMaps;
1214 convertToRequestList(requestsList, surfaceMaps, request);
1215
1216 return setStreamingRequestList(requestsList, /*surfaceMap*/surfaceMaps,
1217 /*lastFrameNumber*/NULL);
1218 }
1219
setStreamingRequestList(const List<const PhysicalCameraSettingsList> & requestsList,const std::list<const SurfaceMap> & surfaceMaps,int64_t * lastFrameNumber)1220 status_t Camera3Device::setStreamingRequestList(
1221 const List<const PhysicalCameraSettingsList> &requestsList,
1222 const std::list<const SurfaceMap> &surfaceMaps, int64_t *lastFrameNumber) {
1223 ATRACE_CALL();
1224
1225 return submitRequestsHelper(requestsList, surfaceMaps, /*repeating*/true, lastFrameNumber);
1226 }
1227
setUpRequestLocked(const PhysicalCameraSettingsList & request,const SurfaceMap & surfaceMap)1228 sp<Camera3Device::CaptureRequest> Camera3Device::setUpRequestLocked(
1229 const PhysicalCameraSettingsList &request, const SurfaceMap &surfaceMap) {
1230 status_t res;
1231
1232 if (mStatus == STATUS_UNCONFIGURED || mNeedConfig) {
1233 // This point should only be reached via API1 (API2 must explicitly call configureStreams)
1234 // so unilaterally select normal operating mode.
1235 res = filterParamsAndConfigureLocked(request.begin()->metadata,
1236 CAMERA_STREAM_CONFIGURATION_NORMAL_MODE);
1237 // Stream configuration failed. Client might try other configuraitons.
1238 if (res != OK) {
1239 CLOGE("Can't set up streams: %s (%d)", strerror(-res), res);
1240 return NULL;
1241 } else if (mStatus == STATUS_UNCONFIGURED) {
1242 // Stream configuration successfully configure to empty stream configuration.
1243 CLOGE("No streams configured");
1244 return NULL;
1245 }
1246 }
1247
1248 sp<CaptureRequest> newRequest = createCaptureRequest(request, surfaceMap);
1249 return newRequest;
1250 }
1251
clearStreamingRequest(int64_t * lastFrameNumber)1252 status_t Camera3Device::clearStreamingRequest(int64_t *lastFrameNumber) {
1253 ATRACE_CALL();
1254 Mutex::Autolock il(mInterfaceLock);
1255 Mutex::Autolock l(mLock);
1256
1257 switch (mStatus) {
1258 case STATUS_ERROR:
1259 CLOGE("Device has encountered a serious error");
1260 return INVALID_OPERATION;
1261 case STATUS_UNINITIALIZED:
1262 CLOGE("Device not initialized");
1263 return INVALID_OPERATION;
1264 case STATUS_UNCONFIGURED:
1265 case STATUS_CONFIGURED:
1266 case STATUS_ACTIVE:
1267 // OK
1268 break;
1269 default:
1270 SET_ERR_L("Unexpected status: %d", mStatus);
1271 return INVALID_OPERATION;
1272 }
1273 ALOGV("Camera %s: Clearing repeating request", mId.string());
1274
1275 return mRequestThread->clearRepeatingRequests(lastFrameNumber);
1276 }
1277
waitUntilRequestReceived(int32_t requestId,nsecs_t timeout)1278 status_t Camera3Device::waitUntilRequestReceived(int32_t requestId, nsecs_t timeout) {
1279 ATRACE_CALL();
1280 Mutex::Autolock il(mInterfaceLock);
1281
1282 return mRequestThread->waitUntilRequestProcessed(requestId, timeout);
1283 }
1284
createInputStream(uint32_t width,uint32_t height,int format,bool isMultiResolution,int * id)1285 status_t Camera3Device::createInputStream(
1286 uint32_t width, uint32_t height, int format, bool isMultiResolution, int *id) {
1287 ATRACE_CALL();
1288 Mutex::Autolock il(mInterfaceLock);
1289 nsecs_t maxExpectedDuration = getExpectedInFlightDuration();
1290 Mutex::Autolock l(mLock);
1291 ALOGV("Camera %s: Creating new input stream %d: %d x %d, format %d",
1292 mId.string(), mNextStreamId, width, height, format);
1293
1294 status_t res;
1295 bool wasActive = false;
1296
1297 switch (mStatus) {
1298 case STATUS_ERROR:
1299 ALOGE("%s: Device has encountered a serious error", __FUNCTION__);
1300 return INVALID_OPERATION;
1301 case STATUS_UNINITIALIZED:
1302 ALOGE("%s: Device not initialized", __FUNCTION__);
1303 return INVALID_OPERATION;
1304 case STATUS_UNCONFIGURED:
1305 case STATUS_CONFIGURED:
1306 // OK
1307 break;
1308 case STATUS_ACTIVE:
1309 ALOGV("%s: Stopping activity to reconfigure streams", __FUNCTION__);
1310 res = internalPauseAndWaitLocked(maxExpectedDuration);
1311 if (res != OK) {
1312 SET_ERR_L("Can't pause captures to reconfigure streams!");
1313 return res;
1314 }
1315 wasActive = true;
1316 break;
1317 default:
1318 SET_ERR_L("%s: Unexpected status: %d", mStatus);
1319 return INVALID_OPERATION;
1320 }
1321 assert(mStatus != STATUS_ACTIVE);
1322
1323 if (mInputStream != 0) {
1324 ALOGE("%s: Cannot create more than 1 input stream", __FUNCTION__);
1325 return INVALID_OPERATION;
1326 }
1327
1328 sp<Camera3InputStream> newStream = new Camera3InputStream(mNextStreamId,
1329 width, height, format);
1330 newStream->setStatusTracker(mStatusTracker);
1331
1332 mInputStream = newStream;
1333 mIsInputStreamMultiResolution = isMultiResolution;
1334
1335 *id = mNextStreamId++;
1336
1337 // Continue captures if active at start
1338 if (wasActive) {
1339 ALOGV("%s: Restarting activity to reconfigure streams", __FUNCTION__);
1340 // Reuse current operating mode and session parameters for new stream config
1341 res = configureStreamsLocked(mOperatingMode, mSessionParams);
1342 if (res != OK) {
1343 ALOGE("%s: Can't reconfigure device for new stream %d: %s (%d)",
1344 __FUNCTION__, mNextStreamId, strerror(-res), res);
1345 return res;
1346 }
1347 internalResumeLocked();
1348 }
1349
1350 ALOGV("Camera %s: Created input stream", mId.string());
1351 return OK;
1352 }
1353
createStream(sp<Surface> consumer,uint32_t width,uint32_t height,int format,android_dataspace dataSpace,camera_stream_rotation_t rotation,int * id,const String8 & physicalCameraId,const std::unordered_set<int32_t> & sensorPixelModesUsed,std::vector<int> * surfaceIds,int streamSetId,bool isShared,bool isMultiResolution,uint64_t consumerUsage)1354 status_t Camera3Device::createStream(sp<Surface> consumer,
1355 uint32_t width, uint32_t height, int format,
1356 android_dataspace dataSpace, camera_stream_rotation_t rotation, int *id,
1357 const String8& physicalCameraId,
1358 const std::unordered_set<int32_t> &sensorPixelModesUsed,
1359 std::vector<int> *surfaceIds, int streamSetId, bool isShared, bool isMultiResolution,
1360 uint64_t consumerUsage) {
1361 ATRACE_CALL();
1362
1363 if (consumer == nullptr) {
1364 ALOGE("%s: consumer must not be null", __FUNCTION__);
1365 return BAD_VALUE;
1366 }
1367
1368 std::vector<sp<Surface>> consumers;
1369 consumers.push_back(consumer);
1370
1371 return createStream(consumers, /*hasDeferredConsumer*/ false, width, height,
1372 format, dataSpace, rotation, id, physicalCameraId, sensorPixelModesUsed, surfaceIds,
1373 streamSetId, isShared, isMultiResolution, consumerUsage);
1374 }
1375
isRawFormat(int format)1376 static bool isRawFormat(int format) {
1377 switch (format) {
1378 case HAL_PIXEL_FORMAT_RAW16:
1379 case HAL_PIXEL_FORMAT_RAW12:
1380 case HAL_PIXEL_FORMAT_RAW10:
1381 case HAL_PIXEL_FORMAT_RAW_OPAQUE:
1382 return true;
1383 default:
1384 return false;
1385 }
1386 }
1387
createStream(const std::vector<sp<Surface>> & consumers,bool hasDeferredConsumer,uint32_t width,uint32_t height,int format,android_dataspace dataSpace,camera_stream_rotation_t rotation,int * id,const String8 & physicalCameraId,const std::unordered_set<int32_t> & sensorPixelModesUsed,std::vector<int> * surfaceIds,int streamSetId,bool isShared,bool isMultiResolution,uint64_t consumerUsage)1388 status_t Camera3Device::createStream(const std::vector<sp<Surface>>& consumers,
1389 bool hasDeferredConsumer, uint32_t width, uint32_t height, int format,
1390 android_dataspace dataSpace, camera_stream_rotation_t rotation, int *id,
1391 const String8& physicalCameraId, const std::unordered_set<int32_t> &sensorPixelModesUsed,
1392 std::vector<int> *surfaceIds, int streamSetId, bool isShared, bool isMultiResolution,
1393 uint64_t consumerUsage) {
1394 ATRACE_CALL();
1395
1396 Mutex::Autolock il(mInterfaceLock);
1397 nsecs_t maxExpectedDuration = getExpectedInFlightDuration();
1398 Mutex::Autolock l(mLock);
1399 ALOGV("Camera %s: Creating new stream %d: %d x %d, format %d, dataspace %d rotation %d"
1400 " consumer usage %" PRIu64 ", isShared %d, physicalCameraId %s, isMultiResolution %d",
1401 mId.string(), mNextStreamId, width, height, format, dataSpace, rotation,
1402 consumerUsage, isShared, physicalCameraId.string(), isMultiResolution);
1403
1404 status_t res;
1405 bool wasActive = false;
1406
1407 switch (mStatus) {
1408 case STATUS_ERROR:
1409 CLOGE("Device has encountered a serious error");
1410 return INVALID_OPERATION;
1411 case STATUS_UNINITIALIZED:
1412 CLOGE("Device not initialized");
1413 return INVALID_OPERATION;
1414 case STATUS_UNCONFIGURED:
1415 case STATUS_CONFIGURED:
1416 // OK
1417 break;
1418 case STATUS_ACTIVE:
1419 ALOGV("%s: Stopping activity to reconfigure streams", __FUNCTION__);
1420 res = internalPauseAndWaitLocked(maxExpectedDuration);
1421 if (res != OK) {
1422 SET_ERR_L("Can't pause captures to reconfigure streams!");
1423 return res;
1424 }
1425 wasActive = true;
1426 break;
1427 default:
1428 SET_ERR_L("Unexpected status: %d", mStatus);
1429 return INVALID_OPERATION;
1430 }
1431 assert(mStatus != STATUS_ACTIVE);
1432
1433 sp<Camera3OutputStream> newStream;
1434
1435 if (consumers.size() == 0 && !hasDeferredConsumer) {
1436 ALOGE("%s: Number of consumers cannot be smaller than 1", __FUNCTION__);
1437 return BAD_VALUE;
1438 }
1439
1440 if (hasDeferredConsumer && format != HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED) {
1441 ALOGE("Deferred consumer stream creation only support IMPLEMENTATION_DEFINED format");
1442 return BAD_VALUE;
1443 }
1444
1445 if (isRawFormat(format) && sensorPixelModesUsed.size() > 1) {
1446 // We can't use one stream with a raw format in both sensor pixel modes since its going to
1447 // be found in only one sensor pixel mode.
1448 ALOGE("%s: RAW opaque stream cannot be used with > 1 sensor pixel modes", __FUNCTION__);
1449 return BAD_VALUE;
1450 }
1451 if (format == HAL_PIXEL_FORMAT_BLOB) {
1452 ssize_t blobBufferSize;
1453 if (dataSpace == HAL_DATASPACE_DEPTH) {
1454 blobBufferSize = getPointCloudBufferSize();
1455 if (blobBufferSize <= 0) {
1456 SET_ERR_L("Invalid point cloud buffer size %zd", blobBufferSize);
1457 return BAD_VALUE;
1458 }
1459 } else if (dataSpace == static_cast<android_dataspace>(HAL_DATASPACE_JPEG_APP_SEGMENTS)) {
1460 blobBufferSize = width * height;
1461 } else {
1462 blobBufferSize = getJpegBufferSize(width, height);
1463 if (blobBufferSize <= 0) {
1464 SET_ERR_L("Invalid jpeg buffer size %zd", blobBufferSize);
1465 return BAD_VALUE;
1466 }
1467 }
1468 newStream = new Camera3OutputStream(mNextStreamId, consumers[0],
1469 width, height, blobBufferSize, format, dataSpace, rotation,
1470 mTimestampOffset, physicalCameraId, sensorPixelModesUsed, streamSetId,
1471 isMultiResolution);
1472 } else if (format == HAL_PIXEL_FORMAT_RAW_OPAQUE) {
1473 bool maxResolution =
1474 sensorPixelModesUsed.find(ANDROID_SENSOR_PIXEL_MODE_MAXIMUM_RESOLUTION) !=
1475 sensorPixelModesUsed.end();
1476 ssize_t rawOpaqueBufferSize = getRawOpaqueBufferSize(width, height, maxResolution);
1477 if (rawOpaqueBufferSize <= 0) {
1478 SET_ERR_L("Invalid RAW opaque buffer size %zd", rawOpaqueBufferSize);
1479 return BAD_VALUE;
1480 }
1481 newStream = new Camera3OutputStream(mNextStreamId, consumers[0],
1482 width, height, rawOpaqueBufferSize, format, dataSpace, rotation,
1483 mTimestampOffset, physicalCameraId, sensorPixelModesUsed, streamSetId,
1484 isMultiResolution);
1485 } else if (isShared) {
1486 newStream = new Camera3SharedOutputStream(mNextStreamId, consumers,
1487 width, height, format, consumerUsage, dataSpace, rotation,
1488 mTimestampOffset, physicalCameraId, sensorPixelModesUsed, streamSetId,
1489 mUseHalBufManager);
1490 } else if (consumers.size() == 0 && hasDeferredConsumer) {
1491 newStream = new Camera3OutputStream(mNextStreamId,
1492 width, height, format, consumerUsage, dataSpace, rotation,
1493 mTimestampOffset, physicalCameraId, sensorPixelModesUsed, streamSetId,
1494 isMultiResolution);
1495 } else {
1496 newStream = new Camera3OutputStream(mNextStreamId, consumers[0],
1497 width, height, format, dataSpace, rotation,
1498 mTimestampOffset, physicalCameraId, sensorPixelModesUsed, streamSetId,
1499 isMultiResolution);
1500 }
1501
1502 size_t consumerCount = consumers.size();
1503 for (size_t i = 0; i < consumerCount; i++) {
1504 int id = newStream->getSurfaceId(consumers[i]);
1505 if (id < 0) {
1506 SET_ERR_L("Invalid surface id");
1507 return BAD_VALUE;
1508 }
1509 if (surfaceIds != nullptr) {
1510 surfaceIds->push_back(id);
1511 }
1512 }
1513
1514 newStream->setStatusTracker(mStatusTracker);
1515
1516 newStream->setBufferManager(mBufferManager);
1517
1518 newStream->setImageDumpMask(mImageDumpMask);
1519
1520 res = mOutputStreams.add(mNextStreamId, newStream);
1521 if (res < 0) {
1522 SET_ERR_L("Can't add new stream to set: %s (%d)", strerror(-res), res);
1523 return res;
1524 }
1525
1526 mSessionStatsBuilder.addStream(mNextStreamId);
1527
1528 *id = mNextStreamId++;
1529 mNeedConfig = true;
1530
1531 // Continue captures if active at start
1532 if (wasActive) {
1533 ALOGV("%s: Restarting activity to reconfigure streams", __FUNCTION__);
1534 // Reuse current operating mode and session parameters for new stream config
1535 res = configureStreamsLocked(mOperatingMode, mSessionParams);
1536 if (res != OK) {
1537 CLOGE("Can't reconfigure device for new stream %d: %s (%d)",
1538 mNextStreamId, strerror(-res), res);
1539 return res;
1540 }
1541 internalResumeLocked();
1542 }
1543 ALOGV("Camera %s: Created new stream", mId.string());
1544 return OK;
1545 }
1546
getStreamInfo(int id,StreamInfo * streamInfo)1547 status_t Camera3Device::getStreamInfo(int id, StreamInfo *streamInfo) {
1548 ATRACE_CALL();
1549 if (nullptr == streamInfo) {
1550 return BAD_VALUE;
1551 }
1552 Mutex::Autolock il(mInterfaceLock);
1553 Mutex::Autolock l(mLock);
1554
1555 switch (mStatus) {
1556 case STATUS_ERROR:
1557 CLOGE("Device has encountered a serious error");
1558 return INVALID_OPERATION;
1559 case STATUS_UNINITIALIZED:
1560 CLOGE("Device not initialized!");
1561 return INVALID_OPERATION;
1562 case STATUS_UNCONFIGURED:
1563 case STATUS_CONFIGURED:
1564 case STATUS_ACTIVE:
1565 // OK
1566 break;
1567 default:
1568 SET_ERR_L("Unexpected status: %d", mStatus);
1569 return INVALID_OPERATION;
1570 }
1571
1572 sp<Camera3StreamInterface> stream = mOutputStreams.get(id);
1573 if (stream == nullptr) {
1574 CLOGE("Stream %d is unknown", id);
1575 return BAD_VALUE;
1576 }
1577
1578 streamInfo->width = stream->getWidth();
1579 streamInfo->height = stream->getHeight();
1580 streamInfo->format = stream->getFormat();
1581 streamInfo->dataSpace = stream->getDataSpace();
1582 streamInfo->formatOverridden = stream->isFormatOverridden();
1583 streamInfo->originalFormat = stream->getOriginalFormat();
1584 streamInfo->dataSpaceOverridden = stream->isDataSpaceOverridden();
1585 streamInfo->originalDataSpace = stream->getOriginalDataSpace();
1586 return OK;
1587 }
1588
setStreamTransform(int id,int transform)1589 status_t Camera3Device::setStreamTransform(int id,
1590 int transform) {
1591 ATRACE_CALL();
1592 Mutex::Autolock il(mInterfaceLock);
1593 Mutex::Autolock l(mLock);
1594
1595 switch (mStatus) {
1596 case STATUS_ERROR:
1597 CLOGE("Device has encountered a serious error");
1598 return INVALID_OPERATION;
1599 case STATUS_UNINITIALIZED:
1600 CLOGE("Device not initialized");
1601 return INVALID_OPERATION;
1602 case STATUS_UNCONFIGURED:
1603 case STATUS_CONFIGURED:
1604 case STATUS_ACTIVE:
1605 // OK
1606 break;
1607 default:
1608 SET_ERR_L("Unexpected status: %d", mStatus);
1609 return INVALID_OPERATION;
1610 }
1611
1612 sp<Camera3OutputStreamInterface> stream = mOutputStreams.get(id);
1613 if (stream == nullptr) {
1614 CLOGE("Stream %d does not exist", id);
1615 return BAD_VALUE;
1616 }
1617 return stream->setTransform(transform);
1618 }
1619
deleteStream(int id)1620 status_t Camera3Device::deleteStream(int id) {
1621 ATRACE_CALL();
1622 Mutex::Autolock il(mInterfaceLock);
1623 Mutex::Autolock l(mLock);
1624 status_t res;
1625
1626 ALOGV("%s: Camera %s: Deleting stream %d", __FUNCTION__, mId.string(), id);
1627
1628 // CameraDevice semantics require device to already be idle before
1629 // deleteStream is called, unlike for createStream.
1630 if (mStatus == STATUS_ACTIVE) {
1631 ALOGW("%s: Camera %s: Device not idle", __FUNCTION__, mId.string());
1632 return -EBUSY;
1633 }
1634
1635 if (mStatus == STATUS_ERROR) {
1636 ALOGW("%s: Camera %s: deleteStream not allowed in ERROR state",
1637 __FUNCTION__, mId.string());
1638 return -EBUSY;
1639 }
1640
1641 sp<Camera3StreamInterface> deletedStream;
1642 sp<Camera3StreamInterface> stream = mOutputStreams.get(id);
1643 if (mInputStream != NULL && id == mInputStream->getId()) {
1644 deletedStream = mInputStream;
1645 mInputStream.clear();
1646 } else {
1647 if (stream == nullptr) {
1648 CLOGE("Stream %d does not exist", id);
1649 return BAD_VALUE;
1650 }
1651 mSessionStatsBuilder.removeStream(id);
1652 }
1653
1654 // Delete output stream or the output part of a bi-directional stream.
1655 if (stream != nullptr) {
1656 deletedStream = stream;
1657 mOutputStreams.remove(id);
1658 }
1659
1660 // Free up the stream endpoint so that it can be used by some other stream
1661 res = deletedStream->disconnect();
1662 if (res != OK) {
1663 SET_ERR_L("Can't disconnect deleted stream %d", id);
1664 // fall through since we want to still list the stream as deleted.
1665 }
1666 mDeletedStreams.add(deletedStream);
1667 mNeedConfig = true;
1668
1669 return res;
1670 }
1671
configureStreams(const CameraMetadata & sessionParams,int operatingMode)1672 status_t Camera3Device::configureStreams(const CameraMetadata& sessionParams, int operatingMode) {
1673 ATRACE_CALL();
1674 ALOGV("%s: E", __FUNCTION__);
1675
1676 Mutex::Autolock il(mInterfaceLock);
1677 Mutex::Autolock l(mLock);
1678
1679 // In case the client doesn't include any session parameter, try a
1680 // speculative configuration using the values from the last cached
1681 // default request.
1682 if (sessionParams.isEmpty() &&
1683 ((mLastTemplateId > 0) && (mLastTemplateId < CAMERA_TEMPLATE_COUNT)) &&
1684 (!mRequestTemplateCache[mLastTemplateId].isEmpty())) {
1685 ALOGV("%s: Speculative session param configuration with template id: %d", __func__,
1686 mLastTemplateId);
1687 return filterParamsAndConfigureLocked(mRequestTemplateCache[mLastTemplateId],
1688 operatingMode);
1689 }
1690
1691 return filterParamsAndConfigureLocked(sessionParams, operatingMode);
1692 }
1693
filterParamsAndConfigureLocked(const CameraMetadata & sessionParams,int operatingMode)1694 status_t Camera3Device::filterParamsAndConfigureLocked(const CameraMetadata& sessionParams,
1695 int operatingMode) {
1696 //Filter out any incoming session parameters
1697 const CameraMetadata params(sessionParams);
1698 camera_metadata_entry_t availableSessionKeys = mDeviceInfo.find(
1699 ANDROID_REQUEST_AVAILABLE_SESSION_KEYS);
1700 CameraMetadata filteredParams(availableSessionKeys.count);
1701 camera_metadata_t *meta = const_cast<camera_metadata_t *>(
1702 filteredParams.getAndLock());
1703 set_camera_metadata_vendor_id(meta, mVendorTagId);
1704 filteredParams.unlock(meta);
1705 if (availableSessionKeys.count > 0) {
1706 for (size_t i = 0; i < availableSessionKeys.count; i++) {
1707 camera_metadata_ro_entry entry = params.find(
1708 availableSessionKeys.data.i32[i]);
1709 if (entry.count > 0) {
1710 filteredParams.update(entry);
1711 }
1712 }
1713 }
1714
1715 return configureStreamsLocked(operatingMode, filteredParams);
1716 }
1717
getInputBufferProducer(sp<IGraphicBufferProducer> * producer)1718 status_t Camera3Device::getInputBufferProducer(
1719 sp<IGraphicBufferProducer> *producer) {
1720 ATRACE_CALL();
1721 Mutex::Autolock il(mInterfaceLock);
1722 Mutex::Autolock l(mLock);
1723
1724 if (producer == NULL) {
1725 return BAD_VALUE;
1726 } else if (mInputStream == NULL) {
1727 return INVALID_OPERATION;
1728 }
1729
1730 return mInputStream->getInputBufferProducer(producer);
1731 }
1732
createDefaultRequest(camera_request_template_t templateId,CameraMetadata * request)1733 status_t Camera3Device::createDefaultRequest(camera_request_template_t templateId,
1734 CameraMetadata *request) {
1735 ATRACE_CALL();
1736 ALOGV("%s: for template %d", __FUNCTION__, templateId);
1737
1738 if (templateId <= 0 || templateId >= CAMERA_TEMPLATE_COUNT) {
1739 android_errorWriteWithInfoLog(CameraService::SN_EVENT_LOG_ID, "26866110",
1740 CameraThreadState::getCallingUid(), nullptr, 0);
1741 return BAD_VALUE;
1742 }
1743
1744 Mutex::Autolock il(mInterfaceLock);
1745
1746 {
1747 Mutex::Autolock l(mLock);
1748 switch (mStatus) {
1749 case STATUS_ERROR:
1750 CLOGE("Device has encountered a serious error");
1751 return INVALID_OPERATION;
1752 case STATUS_UNINITIALIZED:
1753 CLOGE("Device is not initialized!");
1754 return INVALID_OPERATION;
1755 case STATUS_UNCONFIGURED:
1756 case STATUS_CONFIGURED:
1757 case STATUS_ACTIVE:
1758 // OK
1759 break;
1760 default:
1761 SET_ERR_L("Unexpected status: %d", mStatus);
1762 return INVALID_OPERATION;
1763 }
1764
1765 if (!mRequestTemplateCache[templateId].isEmpty()) {
1766 *request = mRequestTemplateCache[templateId];
1767 mLastTemplateId = templateId;
1768 return OK;
1769 }
1770 }
1771
1772 camera_metadata_t *rawRequest;
1773 status_t res = mInterface->constructDefaultRequestSettings(
1774 (camera_request_template_t) templateId, &rawRequest);
1775
1776 {
1777 Mutex::Autolock l(mLock);
1778 if (res == BAD_VALUE) {
1779 ALOGI("%s: template %d is not supported on this camera device",
1780 __FUNCTION__, templateId);
1781 return res;
1782 } else if (res != OK) {
1783 CLOGE("Unable to construct request template %d: %s (%d)",
1784 templateId, strerror(-res), res);
1785 return res;
1786 }
1787
1788 set_camera_metadata_vendor_id(rawRequest, mVendorTagId);
1789 mRequestTemplateCache[templateId].acquire(rawRequest);
1790
1791 // Override the template request with zoomRatioMapper
1792 res = mZoomRatioMappers[mId.c_str()].initZoomRatioInTemplate(
1793 &mRequestTemplateCache[templateId]);
1794 if (res != OK) {
1795 CLOGE("Failed to update zoom ratio for template %d: %s (%d)",
1796 templateId, strerror(-res), res);
1797 return res;
1798 }
1799
1800 // Fill in JPEG_QUALITY if not available
1801 if (!mRequestTemplateCache[templateId].exists(ANDROID_JPEG_QUALITY)) {
1802 static const uint8_t kDefaultJpegQuality = 95;
1803 mRequestTemplateCache[templateId].update(ANDROID_JPEG_QUALITY,
1804 &kDefaultJpegQuality, 1);
1805 }
1806
1807 *request = mRequestTemplateCache[templateId];
1808 mLastTemplateId = templateId;
1809 }
1810 return OK;
1811 }
1812
waitUntilDrained()1813 status_t Camera3Device::waitUntilDrained() {
1814 ATRACE_CALL();
1815 Mutex::Autolock il(mInterfaceLock);
1816 nsecs_t maxExpectedDuration = getExpectedInFlightDuration();
1817 Mutex::Autolock l(mLock);
1818
1819 return waitUntilDrainedLocked(maxExpectedDuration);
1820 }
1821
waitUntilDrainedLocked(nsecs_t maxExpectedDuration)1822 status_t Camera3Device::waitUntilDrainedLocked(nsecs_t maxExpectedDuration) {
1823 switch (mStatus) {
1824 case STATUS_UNINITIALIZED:
1825 case STATUS_UNCONFIGURED:
1826 ALOGV("%s: Already idle", __FUNCTION__);
1827 return OK;
1828 case STATUS_CONFIGURED:
1829 // To avoid race conditions, check with tracker to be sure
1830 case STATUS_ERROR:
1831 case STATUS_ACTIVE:
1832 // Need to verify shut down
1833 break;
1834 default:
1835 SET_ERR_L("Unexpected status: %d",mStatus);
1836 return INVALID_OPERATION;
1837 }
1838 ALOGV("%s: Camera %s: Waiting until idle (%" PRIi64 "ns)", __FUNCTION__, mId.string(),
1839 maxExpectedDuration);
1840 status_t res = waitUntilStateThenRelock(/*active*/ false, maxExpectedDuration);
1841 if (res != OK) {
1842 mStatusTracker->dumpActiveComponents();
1843 SET_ERR_L("Error waiting for HAL to drain: %s (%d)", strerror(-res),
1844 res);
1845 }
1846 return res;
1847 }
1848
internalUpdateStatusLocked(Status status)1849 void Camera3Device::internalUpdateStatusLocked(Status status) {
1850 mStatus = status;
1851 mRecentStatusUpdates.add(mStatus);
1852 mStatusChanged.broadcast();
1853 }
1854
1855 // Pause to reconfigure
internalPauseAndWaitLocked(nsecs_t maxExpectedDuration)1856 status_t Camera3Device::internalPauseAndWaitLocked(nsecs_t maxExpectedDuration) {
1857 if (mRequestThread.get() != nullptr) {
1858 mRequestThread->setPaused(true);
1859 } else {
1860 return NO_INIT;
1861 }
1862
1863 ALOGV("%s: Camera %s: Internal wait until idle (% " PRIi64 " ns)", __FUNCTION__, mId.string(),
1864 maxExpectedDuration);
1865 status_t res = waitUntilStateThenRelock(/*active*/ false, maxExpectedDuration);
1866 if (res != OK) {
1867 SET_ERR_L("Can't idle device in %f seconds!",
1868 maxExpectedDuration/1e9);
1869 }
1870
1871 return res;
1872 }
1873
1874 // Resume after internalPauseAndWaitLocked
internalResumeLocked()1875 status_t Camera3Device::internalResumeLocked() {
1876 status_t res;
1877
1878 mRequestThread->setPaused(false);
1879
1880 ALOGV("%s: Camera %s: Internal wait until active (% " PRIi64 " ns)", __FUNCTION__, mId.string(),
1881 kActiveTimeout);
1882 res = waitUntilStateThenRelock(/*active*/ true, kActiveTimeout);
1883 if (res != OK) {
1884 SET_ERR_L("Can't transition to active in %f seconds!",
1885 kActiveTimeout/1e9);
1886 }
1887 mPauseStateNotify = false;
1888 return OK;
1889 }
1890
waitUntilStateThenRelock(bool active,nsecs_t timeout)1891 status_t Camera3Device::waitUntilStateThenRelock(bool active, nsecs_t timeout) {
1892 status_t res = OK;
1893
1894 size_t startIndex = 0;
1895 if (mStatusWaiters == 0) {
1896 // Clear the list of recent statuses if there are no existing threads waiting on updates to
1897 // this status list
1898 mRecentStatusUpdates.clear();
1899 } else {
1900 // If other threads are waiting on updates to this status list, set the position of the
1901 // first element that this list will check rather than clearing the list.
1902 startIndex = mRecentStatusUpdates.size();
1903 }
1904
1905 mStatusWaiters++;
1906
1907 bool signalPipelineDrain = false;
1908 if (!active && mUseHalBufManager) {
1909 auto streamIds = mOutputStreams.getStreamIds();
1910 if (mStatus == STATUS_ACTIVE) {
1911 mRequestThread->signalPipelineDrain(streamIds);
1912 signalPipelineDrain = true;
1913 }
1914 mRequestBufferSM.onWaitUntilIdle();
1915 }
1916
1917 bool stateSeen = false;
1918 do {
1919 if (active == (mStatus == STATUS_ACTIVE)) {
1920 // Desired state is current
1921 break;
1922 }
1923
1924 res = mStatusChanged.waitRelative(mLock, timeout);
1925 if (res != OK) break;
1926
1927 // This is impossible, but if not, could result in subtle deadlocks and invalid state
1928 // transitions.
1929 LOG_ALWAYS_FATAL_IF(startIndex > mRecentStatusUpdates.size(),
1930 "%s: Skipping status updates in Camera3Device, may result in deadlock.",
1931 __FUNCTION__);
1932
1933 // Encountered desired state since we began waiting
1934 for (size_t i = startIndex; i < mRecentStatusUpdates.size(); i++) {
1935 if (active == (mRecentStatusUpdates[i] == STATUS_ACTIVE) ) {
1936 stateSeen = true;
1937 break;
1938 }
1939 }
1940 } while (!stateSeen);
1941
1942 if (signalPipelineDrain) {
1943 mRequestThread->resetPipelineDrain();
1944 }
1945
1946 mStatusWaiters--;
1947
1948 return res;
1949 }
1950
1951
setNotifyCallback(wp<NotificationListener> listener)1952 status_t Camera3Device::setNotifyCallback(wp<NotificationListener> listener) {
1953 ATRACE_CALL();
1954 std::lock_guard<std::mutex> l(mOutputLock);
1955
1956 if (listener != NULL && mListener != NULL) {
1957 ALOGW("%s: Replacing old callback listener", __FUNCTION__);
1958 }
1959 mListener = listener;
1960 mRequestThread->setNotificationListener(listener);
1961 mPreparerThread->setNotificationListener(listener);
1962
1963 return OK;
1964 }
1965
willNotify3A()1966 bool Camera3Device::willNotify3A() {
1967 return false;
1968 }
1969
waitForNextFrame(nsecs_t timeout)1970 status_t Camera3Device::waitForNextFrame(nsecs_t timeout) {
1971 ATRACE_CALL();
1972 std::unique_lock<std::mutex> l(mOutputLock);
1973
1974 while (mResultQueue.empty()) {
1975 auto st = mResultSignal.wait_for(l, std::chrono::nanoseconds(timeout));
1976 if (st == std::cv_status::timeout) {
1977 return TIMED_OUT;
1978 }
1979 }
1980 return OK;
1981 }
1982
getNextResult(CaptureResult * frame)1983 status_t Camera3Device::getNextResult(CaptureResult *frame) {
1984 ATRACE_CALL();
1985 std::lock_guard<std::mutex> l(mOutputLock);
1986
1987 if (mResultQueue.empty()) {
1988 return NOT_ENOUGH_DATA;
1989 }
1990
1991 if (frame == NULL) {
1992 ALOGE("%s: argument cannot be NULL", __FUNCTION__);
1993 return BAD_VALUE;
1994 }
1995
1996 CaptureResult &result = *(mResultQueue.begin());
1997 frame->mResultExtras = result.mResultExtras;
1998 frame->mMetadata.acquire(result.mMetadata);
1999 frame->mPhysicalMetadatas = std::move(result.mPhysicalMetadatas);
2000 mResultQueue.erase(mResultQueue.begin());
2001
2002 return OK;
2003 }
2004
triggerAutofocus(uint32_t id)2005 status_t Camera3Device::triggerAutofocus(uint32_t id) {
2006 ATRACE_CALL();
2007 Mutex::Autolock il(mInterfaceLock);
2008
2009 ALOGV("%s: Triggering autofocus, id %d", __FUNCTION__, id);
2010 // Mix-in this trigger into the next request and only the next request.
2011 RequestTrigger trigger[] = {
2012 {
2013 ANDROID_CONTROL_AF_TRIGGER,
2014 ANDROID_CONTROL_AF_TRIGGER_START
2015 },
2016 {
2017 ANDROID_CONTROL_AF_TRIGGER_ID,
2018 static_cast<int32_t>(id)
2019 }
2020 };
2021
2022 return mRequestThread->queueTrigger(trigger,
2023 sizeof(trigger)/sizeof(trigger[0]));
2024 }
2025
triggerCancelAutofocus(uint32_t id)2026 status_t Camera3Device::triggerCancelAutofocus(uint32_t id) {
2027 ATRACE_CALL();
2028 Mutex::Autolock il(mInterfaceLock);
2029
2030 ALOGV("%s: Triggering cancel autofocus, id %d", __FUNCTION__, id);
2031 // Mix-in this trigger into the next request and only the next request.
2032 RequestTrigger trigger[] = {
2033 {
2034 ANDROID_CONTROL_AF_TRIGGER,
2035 ANDROID_CONTROL_AF_TRIGGER_CANCEL
2036 },
2037 {
2038 ANDROID_CONTROL_AF_TRIGGER_ID,
2039 static_cast<int32_t>(id)
2040 }
2041 };
2042
2043 return mRequestThread->queueTrigger(trigger,
2044 sizeof(trigger)/sizeof(trigger[0]));
2045 }
2046
triggerPrecaptureMetering(uint32_t id)2047 status_t Camera3Device::triggerPrecaptureMetering(uint32_t id) {
2048 ATRACE_CALL();
2049 Mutex::Autolock il(mInterfaceLock);
2050
2051 ALOGV("%s: Triggering precapture metering, id %d", __FUNCTION__, id);
2052 // Mix-in this trigger into the next request and only the next request.
2053 RequestTrigger trigger[] = {
2054 {
2055 ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER,
2056 ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER_START
2057 },
2058 {
2059 ANDROID_CONTROL_AE_PRECAPTURE_ID,
2060 static_cast<int32_t>(id)
2061 }
2062 };
2063
2064 return mRequestThread->queueTrigger(trigger,
2065 sizeof(trigger)/sizeof(trigger[0]));
2066 }
2067
flush(int64_t * frameNumber)2068 status_t Camera3Device::flush(int64_t *frameNumber) {
2069 ATRACE_CALL();
2070 ALOGV("%s: Camera %s: Flushing all requests", __FUNCTION__, mId.string());
2071 Mutex::Autolock il(mInterfaceLock);
2072
2073 {
2074 Mutex::Autolock l(mLock);
2075
2076 // b/116514106 "disconnect()" can get called twice for the same device. The
2077 // camera device will not be initialized during the second run.
2078 if (mStatus == STATUS_UNINITIALIZED) {
2079 return OK;
2080 }
2081
2082 mRequestThread->clear(/*out*/frameNumber);
2083
2084 // Stop session and stream counter
2085 mSessionStatsBuilder.stopCounter();
2086 }
2087
2088 return mRequestThread->flush();
2089 }
2090
prepare(int streamId)2091 status_t Camera3Device::prepare(int streamId) {
2092 return prepare(camera3::Camera3StreamInterface::ALLOCATE_PIPELINE_MAX, streamId);
2093 }
2094
prepare(int maxCount,int streamId)2095 status_t Camera3Device::prepare(int maxCount, int streamId) {
2096 ATRACE_CALL();
2097 ALOGV("%s: Camera %s: Preparing stream %d", __FUNCTION__, mId.string(), streamId);
2098 Mutex::Autolock il(mInterfaceLock);
2099 Mutex::Autolock l(mLock);
2100
2101 sp<Camera3StreamInterface> stream = mOutputStreams.get(streamId);
2102 if (stream == nullptr) {
2103 CLOGE("Stream %d does not exist", streamId);
2104 return BAD_VALUE;
2105 }
2106
2107 if (stream->isUnpreparable() || stream->hasOutstandingBuffers() ) {
2108 CLOGE("Stream %d has already been a request target", streamId);
2109 return BAD_VALUE;
2110 }
2111
2112 if (mRequestThread->isStreamPending(stream)) {
2113 CLOGE("Stream %d is already a target in a pending request", streamId);
2114 return BAD_VALUE;
2115 }
2116
2117 return mPreparerThread->prepare(maxCount, stream);
2118 }
2119
tearDown(int streamId)2120 status_t Camera3Device::tearDown(int streamId) {
2121 ATRACE_CALL();
2122 ALOGV("%s: Camera %s: Tearing down stream %d", __FUNCTION__, mId.string(), streamId);
2123 Mutex::Autolock il(mInterfaceLock);
2124 Mutex::Autolock l(mLock);
2125
2126 sp<Camera3StreamInterface> stream = mOutputStreams.get(streamId);
2127 if (stream == nullptr) {
2128 CLOGE("Stream %d does not exist", streamId);
2129 return BAD_VALUE;
2130 }
2131
2132 if (stream->hasOutstandingBuffers() || mRequestThread->isStreamPending(stream)) {
2133 CLOGE("Stream %d is a target of a in-progress request", streamId);
2134 return BAD_VALUE;
2135 }
2136
2137 return stream->tearDown();
2138 }
2139
addBufferListenerForStream(int streamId,wp<Camera3StreamBufferListener> listener)2140 status_t Camera3Device::addBufferListenerForStream(int streamId,
2141 wp<Camera3StreamBufferListener> listener) {
2142 ATRACE_CALL();
2143 ALOGV("%s: Camera %s: Adding buffer listener for stream %d", __FUNCTION__, mId.string(), streamId);
2144 Mutex::Autolock il(mInterfaceLock);
2145 Mutex::Autolock l(mLock);
2146
2147 sp<Camera3StreamInterface> stream = mOutputStreams.get(streamId);
2148 if (stream == nullptr) {
2149 CLOGE("Stream %d does not exist", streamId);
2150 return BAD_VALUE;
2151 }
2152 stream->addBufferListener(listener);
2153
2154 return OK;
2155 }
2156
2157 /**
2158 * Methods called by subclasses
2159 */
2160
notifyStatus(bool idle)2161 void Camera3Device::notifyStatus(bool idle) {
2162 ATRACE_CALL();
2163 std::vector<int> streamIds;
2164 std::vector<hardware::CameraStreamStats> streamStats;
2165
2166 {
2167 // Need mLock to safely update state and synchronize to current
2168 // state of methods in flight.
2169 Mutex::Autolock l(mLock);
2170 // We can get various system-idle notices from the status tracker
2171 // while starting up. Only care about them if we've actually sent
2172 // in some requests recently.
2173 if (mStatus != STATUS_ACTIVE && mStatus != STATUS_CONFIGURED) {
2174 return;
2175 }
2176 ALOGV("%s: Camera %s: Now %s, pauseState: %s", __FUNCTION__, mId.string(),
2177 idle ? "idle" : "active", mPauseStateNotify ? "true" : "false");
2178 internalUpdateStatusLocked(idle ? STATUS_CONFIGURED : STATUS_ACTIVE);
2179
2180 // Skip notifying listener if we're doing some user-transparent
2181 // state changes
2182 if (mPauseStateNotify) return;
2183
2184 // Populate stream statistics in case of Idle
2185 if (idle) {
2186 for (size_t i = 0; i < mOutputStreams.size(); i++) {
2187 auto stream = mOutputStreams[i];
2188 if (stream.get() == nullptr) continue;
2189 streamIds.push_back(stream->getId());
2190 Camera3Stream* camera3Stream = Camera3Stream::cast(stream->asHalStream());
2191 int64_t usage = 0LL;
2192 if (camera3Stream != nullptr) {
2193 usage = camera3Stream->getUsage();
2194 }
2195 streamStats.emplace_back(stream->getWidth(), stream->getHeight(),
2196 stream->getFormat(), stream->getDataSpace(), usage,
2197 stream->getMaxHalBuffers(),
2198 stream->getMaxTotalBuffers() - stream->getMaxHalBuffers());
2199 }
2200 }
2201 }
2202
2203 sp<NotificationListener> listener;
2204 {
2205 std::lock_guard<std::mutex> l(mOutputLock);
2206 listener = mListener.promote();
2207 }
2208 status_t res = OK;
2209 if (listener != nullptr) {
2210 if (idle) {
2211 // Get session stats from the builder, and notify the listener.
2212 int64_t requestCount, resultErrorCount;
2213 bool deviceError;
2214 std::map<int, StreamStats> streamStatsMap;
2215 mSessionStatsBuilder.buildAndReset(&requestCount, &resultErrorCount,
2216 &deviceError, &streamStatsMap);
2217 for (size_t i = 0; i < streamIds.size(); i++) {
2218 int streamId = streamIds[i];
2219 auto stats = streamStatsMap.find(streamId);
2220 if (stats != streamStatsMap.end()) {
2221 streamStats[i].mRequestCount = stats->second.mRequestedFrameCount;
2222 streamStats[i].mErrorCount = stats->second.mDroppedFrameCount;
2223 streamStats[i].mStartLatencyMs = stats->second.mStartLatencyMs;
2224 streamStats[i].mHistogramType =
2225 hardware::CameraStreamStats::HISTOGRAM_TYPE_CAPTURE_LATENCY;
2226 streamStats[i].mHistogramBins.assign(
2227 stats->second.mCaptureLatencyBins.begin(),
2228 stats->second.mCaptureLatencyBins.end());
2229 streamStats[i].mHistogramCounts.assign(
2230 stats->second.mCaptureLatencyHistogram.begin(),
2231 stats->second.mCaptureLatencyHistogram.end());
2232 }
2233 }
2234 listener->notifyIdle(requestCount, resultErrorCount, deviceError, streamStats);
2235 } else {
2236 res = listener->notifyActive();
2237 }
2238 }
2239 if (res != OK) {
2240 SET_ERR("Camera access permission lost mid-operation: %s (%d)",
2241 strerror(-res), res);
2242 }
2243 }
2244
setConsumerSurfaces(int streamId,const std::vector<sp<Surface>> & consumers,std::vector<int> * surfaceIds)2245 status_t Camera3Device::setConsumerSurfaces(int streamId,
2246 const std::vector<sp<Surface>>& consumers, std::vector<int> *surfaceIds) {
2247 ATRACE_CALL();
2248 ALOGV("%s: Camera %s: set consumer surface for stream %d",
2249 __FUNCTION__, mId.string(), streamId);
2250
2251 if (surfaceIds == nullptr) {
2252 return BAD_VALUE;
2253 }
2254
2255 Mutex::Autolock il(mInterfaceLock);
2256 Mutex::Autolock l(mLock);
2257
2258 if (consumers.size() == 0) {
2259 CLOGE("No consumer is passed!");
2260 return BAD_VALUE;
2261 }
2262
2263 sp<Camera3OutputStreamInterface> stream = mOutputStreams.get(streamId);
2264 if (stream == nullptr) {
2265 CLOGE("Stream %d is unknown", streamId);
2266 return BAD_VALUE;
2267 }
2268
2269 // isConsumerConfigurationDeferred will be off after setConsumers
2270 bool isDeferred = stream->isConsumerConfigurationDeferred();
2271 status_t res = stream->setConsumers(consumers);
2272 if (res != OK) {
2273 CLOGE("Stream %d set consumer failed (error %d %s) ", streamId, res, strerror(-res));
2274 return res;
2275 }
2276
2277 for (auto &consumer : consumers) {
2278 int id = stream->getSurfaceId(consumer);
2279 if (id < 0) {
2280 CLOGE("Invalid surface id!");
2281 return BAD_VALUE;
2282 }
2283 surfaceIds->push_back(id);
2284 }
2285
2286 if (isDeferred) {
2287 if (!stream->isConfiguring()) {
2288 CLOGE("Stream %d was already fully configured.", streamId);
2289 return INVALID_OPERATION;
2290 }
2291
2292 res = stream->finishConfiguration();
2293 if (res != OK) {
2294 // If finishConfiguration fails due to abandoned surface, do not set
2295 // device to error state.
2296 bool isSurfaceAbandoned =
2297 (res == NO_INIT || res == DEAD_OBJECT) && stream->isAbandoned();
2298 if (!isSurfaceAbandoned) {
2299 SET_ERR_L("Can't finish configuring output stream %d: %s (%d)",
2300 stream->getId(), strerror(-res), res);
2301 }
2302 return res;
2303 }
2304 }
2305
2306 return OK;
2307 }
2308
updateStream(int streamId,const std::vector<sp<Surface>> & newSurfaces,const std::vector<OutputStreamInfo> & outputInfo,const std::vector<size_t> & removedSurfaceIds,KeyedVector<sp<Surface>,size_t> * outputMap)2309 status_t Camera3Device::updateStream(int streamId, const std::vector<sp<Surface>> &newSurfaces,
2310 const std::vector<OutputStreamInfo> &outputInfo,
2311 const std::vector<size_t> &removedSurfaceIds, KeyedVector<sp<Surface>, size_t> *outputMap) {
2312 Mutex::Autolock il(mInterfaceLock);
2313 Mutex::Autolock l(mLock);
2314
2315 sp<Camera3OutputStreamInterface> stream = mOutputStreams.get(streamId);
2316 if (stream == nullptr) {
2317 CLOGE("Stream %d is unknown", streamId);
2318 return BAD_VALUE;
2319 }
2320
2321 for (const auto &it : removedSurfaceIds) {
2322 if (mRequestThread->isOutputSurfacePending(streamId, it)) {
2323 CLOGE("Shared surface still part of a pending request!");
2324 return -EBUSY;
2325 }
2326 }
2327
2328 status_t res = stream->updateStream(newSurfaces, outputInfo, removedSurfaceIds, outputMap);
2329 if (res != OK) {
2330 CLOGE("Stream %d failed to update stream (error %d %s) ",
2331 streamId, res, strerror(-res));
2332 if (res == UNKNOWN_ERROR) {
2333 SET_ERR_L("%s: Stream update failed to revert to previous output configuration!",
2334 __FUNCTION__);
2335 }
2336 return res;
2337 }
2338
2339 return res;
2340 }
2341
dropStreamBuffers(bool dropping,int streamId)2342 status_t Camera3Device::dropStreamBuffers(bool dropping, int streamId) {
2343 Mutex::Autolock il(mInterfaceLock);
2344 Mutex::Autolock l(mLock);
2345
2346 sp<Camera3OutputStreamInterface> stream = mOutputStreams.get(streamId);
2347 if (stream == nullptr) {
2348 ALOGE("%s: Stream %d is not found.", __FUNCTION__, streamId);
2349 return BAD_VALUE;
2350 }
2351
2352 if (dropping) {
2353 mSessionStatsBuilder.stopCounter(streamId);
2354 } else {
2355 mSessionStatsBuilder.startCounter(streamId);
2356 }
2357 return stream->dropBuffers(dropping);
2358 }
2359
2360 /**
2361 * Camera3Device private methods
2362 */
2363
createCaptureRequest(const PhysicalCameraSettingsList & request,const SurfaceMap & surfaceMap)2364 sp<Camera3Device::CaptureRequest> Camera3Device::createCaptureRequest(
2365 const PhysicalCameraSettingsList &request, const SurfaceMap &surfaceMap) {
2366 ATRACE_CALL();
2367
2368 sp<CaptureRequest> newRequest = new CaptureRequest();
2369 newRequest->mSettingsList = request;
2370
2371 camera_metadata_entry_t inputStreams =
2372 newRequest->mSettingsList.begin()->metadata.find(ANDROID_REQUEST_INPUT_STREAMS);
2373 if (inputStreams.count > 0) {
2374 if (mInputStream == NULL ||
2375 mInputStream->getId() != inputStreams.data.i32[0]) {
2376 CLOGE("Request references unknown input stream %d",
2377 inputStreams.data.u8[0]);
2378 return NULL;
2379 }
2380
2381 if (mInputStream->isConfiguring()) {
2382 SET_ERR_L("%s: input stream %d is not configured!",
2383 __FUNCTION__, mInputStream->getId());
2384 return NULL;
2385 }
2386 // Check if stream prepare is blocking requests.
2387 if (mInputStream->isBlockedByPrepare()) {
2388 CLOGE("Request references an input stream that's being prepared!");
2389 return NULL;
2390 }
2391
2392 newRequest->mInputStream = mInputStream;
2393 newRequest->mSettingsList.begin()->metadata.erase(ANDROID_REQUEST_INPUT_STREAMS);
2394 }
2395
2396 camera_metadata_entry_t streams =
2397 newRequest->mSettingsList.begin()->metadata.find(ANDROID_REQUEST_OUTPUT_STREAMS);
2398 if (streams.count == 0) {
2399 CLOGE("Zero output streams specified!");
2400 return NULL;
2401 }
2402
2403 for (size_t i = 0; i < streams.count; i++) {
2404 sp<Camera3OutputStreamInterface> stream = mOutputStreams.get(streams.data.i32[i]);
2405 if (stream == nullptr) {
2406 CLOGE("Request references unknown stream %d",
2407 streams.data.i32[i]);
2408 return NULL;
2409 }
2410 // It is illegal to include a deferred consumer output stream into a request
2411 auto iter = surfaceMap.find(streams.data.i32[i]);
2412 if (iter != surfaceMap.end()) {
2413 const std::vector<size_t>& surfaces = iter->second;
2414 for (const auto& surface : surfaces) {
2415 if (stream->isConsumerConfigurationDeferred(surface)) {
2416 CLOGE("Stream %d surface %zu hasn't finished configuration yet "
2417 "due to deferred consumer", stream->getId(), surface);
2418 return NULL;
2419 }
2420 }
2421 newRequest->mOutputSurfaces[streams.data.i32[i]] = surfaces;
2422 }
2423
2424 if (stream->isConfiguring()) {
2425 SET_ERR_L("%s: stream %d is not configured!", __FUNCTION__, stream->getId());
2426 return NULL;
2427 }
2428 // Check if stream prepare is blocking requests.
2429 if (stream->isBlockedByPrepare()) {
2430 CLOGE("Request references an output stream that's being prepared!");
2431 return NULL;
2432 }
2433
2434 newRequest->mOutputStreams.push(stream);
2435 }
2436 newRequest->mSettingsList.begin()->metadata.erase(ANDROID_REQUEST_OUTPUT_STREAMS);
2437 newRequest->mBatchSize = 1;
2438
2439 auto rotateAndCropEntry =
2440 newRequest->mSettingsList.begin()->metadata.find(ANDROID_SCALER_ROTATE_AND_CROP);
2441 if (rotateAndCropEntry.count > 0 &&
2442 rotateAndCropEntry.data.u8[0] == ANDROID_SCALER_ROTATE_AND_CROP_AUTO) {
2443 newRequest->mRotateAndCropAuto = true;
2444 } else {
2445 newRequest->mRotateAndCropAuto = false;
2446 }
2447
2448 auto zoomRatioEntry =
2449 newRequest->mSettingsList.begin()->metadata.find(ANDROID_CONTROL_ZOOM_RATIO);
2450 if (zoomRatioEntry.count > 0 &&
2451 zoomRatioEntry.data.f[0] == 1.0f) {
2452 newRequest->mZoomRatioIs1x = true;
2453 } else {
2454 newRequest->mZoomRatioIs1x = false;
2455 }
2456
2457 if (mSupportCameraMute) {
2458 auto testPatternModeEntry =
2459 newRequest->mSettingsList.begin()->metadata.find(ANDROID_SENSOR_TEST_PATTERN_MODE);
2460 newRequest->mOriginalTestPatternMode = testPatternModeEntry.count > 0 ?
2461 testPatternModeEntry.data.i32[0] :
2462 ANDROID_SENSOR_TEST_PATTERN_MODE_OFF;
2463
2464 auto testPatternDataEntry =
2465 newRequest->mSettingsList.begin()->metadata.find(ANDROID_SENSOR_TEST_PATTERN_DATA);
2466 if (testPatternDataEntry.count >= 4) {
2467 memcpy(newRequest->mOriginalTestPatternData, testPatternDataEntry.data.i32,
2468 sizeof(CaptureRequest::mOriginalTestPatternData));
2469 } else {
2470 newRequest->mOriginalTestPatternData[0] = 0;
2471 newRequest->mOriginalTestPatternData[1] = 0;
2472 newRequest->mOriginalTestPatternData[2] = 0;
2473 newRequest->mOriginalTestPatternData[3] = 0;
2474 }
2475 }
2476
2477 return newRequest;
2478 }
2479
cancelStreamsConfigurationLocked()2480 void Camera3Device::cancelStreamsConfigurationLocked() {
2481 int res = OK;
2482 if (mInputStream != NULL && mInputStream->isConfiguring()) {
2483 res = mInputStream->cancelConfiguration();
2484 if (res != OK) {
2485 CLOGE("Can't cancel configuring input stream %d: %s (%d)",
2486 mInputStream->getId(), strerror(-res), res);
2487 }
2488 }
2489
2490 for (size_t i = 0; i < mOutputStreams.size(); i++) {
2491 sp<Camera3OutputStreamInterface> outputStream = mOutputStreams[i];
2492 if (outputStream->isConfiguring()) {
2493 res = outputStream->cancelConfiguration();
2494 if (res != OK) {
2495 CLOGE("Can't cancel configuring output stream %d: %s (%d)",
2496 outputStream->getId(), strerror(-res), res);
2497 }
2498 }
2499 }
2500
2501 // Return state to that at start of call, so that future configures
2502 // properly clean things up
2503 internalUpdateStatusLocked(STATUS_UNCONFIGURED);
2504 mNeedConfig = true;
2505
2506 res = mPreparerThread->resume();
2507 if (res != OK) {
2508 ALOGE("%s: Camera %s: Preparer thread failed to resume!", __FUNCTION__, mId.string());
2509 }
2510 }
2511
checkAbandonedStreamsLocked()2512 bool Camera3Device::checkAbandonedStreamsLocked() {
2513 if ((mInputStream.get() != nullptr) && (mInputStream->isAbandoned())) {
2514 return true;
2515 }
2516
2517 for (size_t i = 0; i < mOutputStreams.size(); i++) {
2518 auto stream = mOutputStreams[i];
2519 if ((stream.get() != nullptr) && (stream->isAbandoned())) {
2520 return true;
2521 }
2522 }
2523
2524 return false;
2525 }
2526
reconfigureCamera(const CameraMetadata & sessionParams,int clientStatusId)2527 bool Camera3Device::reconfigureCamera(const CameraMetadata& sessionParams, int clientStatusId) {
2528 ATRACE_CALL();
2529 bool ret = false;
2530
2531 nsecs_t startTime = systemTime();
2532
2533 Mutex::Autolock il(mInterfaceLock);
2534 nsecs_t maxExpectedDuration = getExpectedInFlightDuration();
2535
2536 Mutex::Autolock l(mLock);
2537 if (checkAbandonedStreamsLocked()) {
2538 ALOGW("%s: Abandoned stream detected, session parameters can't be applied correctly!",
2539 __FUNCTION__);
2540 return true;
2541 }
2542
2543 status_t rc = NO_ERROR;
2544 bool markClientActive = false;
2545 if (mStatus == STATUS_ACTIVE) {
2546 markClientActive = true;
2547 mPauseStateNotify = true;
2548 mStatusTracker->markComponentIdle(clientStatusId, Fence::NO_FENCE);
2549
2550 rc = internalPauseAndWaitLocked(maxExpectedDuration);
2551 }
2552
2553 if (rc == NO_ERROR) {
2554 mNeedConfig = true;
2555 rc = configureStreamsLocked(mOperatingMode, sessionParams, /*notifyRequestThread*/ false);
2556 if (rc == NO_ERROR) {
2557 ret = true;
2558 mPauseStateNotify = false;
2559 //Moving to active state while holding 'mLock' is important.
2560 //There could be pending calls to 'create-/deleteStream' which
2561 //will trigger another stream configuration while the already
2562 //present streams end up with outstanding buffers that will
2563 //not get drained.
2564 internalUpdateStatusLocked(STATUS_ACTIVE);
2565 } else if (rc == DEAD_OBJECT) {
2566 // DEAD_OBJECT can be returned if either the consumer surface is
2567 // abandoned, or the HAL has died.
2568 // - If the HAL has died, configureStreamsLocked call will set
2569 // device to error state,
2570 // - If surface is abandoned, we should not set device to error
2571 // state.
2572 ALOGE("Failed to re-configure camera due to abandoned surface");
2573 } else {
2574 SET_ERR_L("Failed to re-configure camera: %d", rc);
2575 }
2576 } else {
2577 ALOGE("%s: Failed to pause streaming: %d", __FUNCTION__, rc);
2578 }
2579
2580 CameraServiceProxyWrapper::logStreamConfigured(mId, mOperatingMode, true /*internalReconfig*/,
2581 ns2ms(systemTime() - startTime));
2582
2583 if (markClientActive) {
2584 mStatusTracker->markComponentActive(clientStatusId);
2585 }
2586
2587 return ret;
2588 }
2589
configureStreamsLocked(int operatingMode,const CameraMetadata & sessionParams,bool notifyRequestThread)2590 status_t Camera3Device::configureStreamsLocked(int operatingMode,
2591 const CameraMetadata& sessionParams, bool notifyRequestThread) {
2592 ATRACE_CALL();
2593 status_t res;
2594
2595 if (mStatus != STATUS_UNCONFIGURED && mStatus != STATUS_CONFIGURED) {
2596 CLOGE("Not idle");
2597 return INVALID_OPERATION;
2598 }
2599
2600 if (operatingMode < 0) {
2601 CLOGE("Invalid operating mode: %d", operatingMode);
2602 return BAD_VALUE;
2603 }
2604
2605 bool isConstrainedHighSpeed =
2606 static_cast<int>(StreamConfigurationMode::CONSTRAINED_HIGH_SPEED_MODE) ==
2607 operatingMode;
2608
2609 if (mOperatingMode != operatingMode) {
2610 mNeedConfig = true;
2611 mIsConstrainedHighSpeedConfiguration = isConstrainedHighSpeed;
2612 mOperatingMode = operatingMode;
2613 }
2614
2615 // In case called from configureStreams, abort queued input buffers not belonging to
2616 // any pending requests.
2617 if (mInputStream != NULL && notifyRequestThread) {
2618 while (true) {
2619 camera_stream_buffer_t inputBuffer;
2620 camera3::Size inputBufferSize;
2621 status_t res = mInputStream->getInputBuffer(&inputBuffer,
2622 &inputBufferSize, /*respectHalLimit*/ false);
2623 if (res != OK) {
2624 // Exhausted acquiring all input buffers.
2625 break;
2626 }
2627
2628 inputBuffer.status = CAMERA_BUFFER_STATUS_ERROR;
2629 res = mInputStream->returnInputBuffer(inputBuffer);
2630 if (res != OK) {
2631 ALOGE("%s: %d: couldn't return input buffer while clearing input queue: "
2632 "%s (%d)", __FUNCTION__, __LINE__, strerror(-res), res);
2633 }
2634 }
2635 }
2636
2637 if (!mNeedConfig) {
2638 ALOGV("%s: Skipping config, no stream changes", __FUNCTION__);
2639 return OK;
2640 }
2641
2642 // Workaround for device HALv3.2 or older spec bug - zero streams requires
2643 // adding a fake stream instead.
2644 // TODO: Bug: 17321404 for fixing the HAL spec and removing this workaround.
2645 if (mOutputStreams.size() == 0) {
2646 addFakeStreamLocked();
2647 } else {
2648 tryRemoveFakeStreamLocked();
2649 }
2650
2651 // Start configuring the streams
2652 ALOGV("%s: Camera %s: Starting stream configuration", __FUNCTION__, mId.string());
2653
2654 mPreparerThread->pause();
2655
2656 camera_stream_configuration config;
2657 config.operation_mode = mOperatingMode;
2658 config.num_streams = (mInputStream != NULL) + mOutputStreams.size();
2659 config.input_is_multi_resolution = false;
2660
2661 Vector<camera3::camera_stream_t*> streams;
2662 streams.setCapacity(config.num_streams);
2663 std::vector<uint32_t> bufferSizes(config.num_streams, 0);
2664
2665
2666 if (mInputStream != NULL) {
2667 camera3::camera_stream_t *inputStream;
2668 inputStream = mInputStream->startConfiguration();
2669 if (inputStream == NULL) {
2670 CLOGE("Can't start input stream configuration");
2671 cancelStreamsConfigurationLocked();
2672 return INVALID_OPERATION;
2673 }
2674 streams.add(inputStream);
2675
2676 config.input_is_multi_resolution = mIsInputStreamMultiResolution;
2677 }
2678
2679 mGroupIdPhysicalCameraMap.clear();
2680 for (size_t i = 0; i < mOutputStreams.size(); i++) {
2681
2682 // Don't configure bidi streams twice, nor add them twice to the list
2683 if (mOutputStreams[i].get() ==
2684 static_cast<Camera3StreamInterface*>(mInputStream.get())) {
2685
2686 config.num_streams--;
2687 continue;
2688 }
2689
2690 camera3::camera_stream_t *outputStream;
2691 outputStream = mOutputStreams[i]->startConfiguration();
2692 if (outputStream == NULL) {
2693 CLOGE("Can't start output stream configuration");
2694 cancelStreamsConfigurationLocked();
2695 return INVALID_OPERATION;
2696 }
2697 streams.add(outputStream);
2698
2699 if (outputStream->format == HAL_PIXEL_FORMAT_BLOB) {
2700 size_t k = i + ((mInputStream != nullptr) ? 1 : 0); // Input stream if present should
2701 // always occupy the initial entry.
2702 if (outputStream->data_space == HAL_DATASPACE_V0_JFIF) {
2703 bufferSizes[k] = static_cast<uint32_t>(
2704 getJpegBufferSize(outputStream->width, outputStream->height));
2705 } else if (outputStream->data_space ==
2706 static_cast<android_dataspace>(HAL_DATASPACE_JPEG_APP_SEGMENTS)) {
2707 bufferSizes[k] = outputStream->width * outputStream->height;
2708 } else {
2709 ALOGW("%s: Blob dataSpace %d not supported",
2710 __FUNCTION__, outputStream->data_space);
2711 }
2712 }
2713
2714 if (mOutputStreams[i]->isMultiResolution()) {
2715 int32_t streamGroupId = mOutputStreams[i]->getHalStreamGroupId();
2716 const String8& physicalCameraId = mOutputStreams[i]->getPhysicalCameraId();
2717 mGroupIdPhysicalCameraMap[streamGroupId].insert(physicalCameraId);
2718 }
2719 }
2720
2721 config.streams = streams.editArray();
2722
2723 // Do the HAL configuration; will potentially touch stream
2724 // max_buffers, usage, and priv fields, as well as data_space and format
2725 // fields for IMPLEMENTATION_DEFINED formats.
2726
2727 const camera_metadata_t *sessionBuffer = sessionParams.getAndLock();
2728 res = mInterface->configureStreams(sessionBuffer, &config, bufferSizes);
2729 sessionParams.unlock(sessionBuffer);
2730
2731 if (res == BAD_VALUE) {
2732 // HAL rejected this set of streams as unsupported, clean up config
2733 // attempt and return to unconfigured state
2734 CLOGE("Set of requested inputs/outputs not supported by HAL");
2735 cancelStreamsConfigurationLocked();
2736 return BAD_VALUE;
2737 } else if (res != OK) {
2738 // Some other kind of error from configure_streams - this is not
2739 // expected
2740 SET_ERR_L("Unable to configure streams with HAL: %s (%d)",
2741 strerror(-res), res);
2742 return res;
2743 }
2744
2745 // Finish all stream configuration immediately.
2746 // TODO: Try to relax this later back to lazy completion, which should be
2747 // faster
2748
2749 if (mInputStream != NULL && mInputStream->isConfiguring()) {
2750 bool streamReConfigured = false;
2751 res = mInputStream->finishConfiguration(&streamReConfigured);
2752 if (res != OK) {
2753 CLOGE("Can't finish configuring input stream %d: %s (%d)",
2754 mInputStream->getId(), strerror(-res), res);
2755 cancelStreamsConfigurationLocked();
2756 if ((res == NO_INIT || res == DEAD_OBJECT) && mInputStream->isAbandoned()) {
2757 return DEAD_OBJECT;
2758 }
2759 return BAD_VALUE;
2760 }
2761 if (streamReConfigured) {
2762 mInterface->onStreamReConfigured(mInputStream->getId());
2763 }
2764 }
2765
2766 for (size_t i = 0; i < mOutputStreams.size(); i++) {
2767 sp<Camera3OutputStreamInterface> outputStream = mOutputStreams[i];
2768 if (outputStream->isConfiguring() && !outputStream->isConsumerConfigurationDeferred()) {
2769 bool streamReConfigured = false;
2770 res = outputStream->finishConfiguration(&streamReConfigured);
2771 if (res != OK) {
2772 CLOGE("Can't finish configuring output stream %d: %s (%d)",
2773 outputStream->getId(), strerror(-res), res);
2774 cancelStreamsConfigurationLocked();
2775 if ((res == NO_INIT || res == DEAD_OBJECT) && outputStream->isAbandoned()) {
2776 return DEAD_OBJECT;
2777 }
2778 return BAD_VALUE;
2779 }
2780 if (streamReConfigured) {
2781 mInterface->onStreamReConfigured(outputStream->getId());
2782 }
2783 }
2784 }
2785
2786 // Request thread needs to know to avoid using repeat-last-settings protocol
2787 // across configure_streams() calls
2788 if (notifyRequestThread) {
2789 mRequestThread->configurationComplete(mIsConstrainedHighSpeedConfiguration,
2790 sessionParams, mGroupIdPhysicalCameraMap);
2791 }
2792
2793 char value[PROPERTY_VALUE_MAX];
2794 property_get("camera.fifo.disable", value, "0");
2795 int32_t disableFifo = atoi(value);
2796 if (disableFifo != 1) {
2797 // Boost priority of request thread to SCHED_FIFO.
2798 pid_t requestThreadTid = mRequestThread->getTid();
2799 res = requestPriority(getpid(), requestThreadTid,
2800 kRequestThreadPriority, /*isForApp*/ false, /*asynchronous*/ false);
2801 if (res != OK) {
2802 ALOGW("Can't set realtime priority for request processing thread: %s (%d)",
2803 strerror(-res), res);
2804 } else {
2805 ALOGD("Set real time priority for request queue thread (tid %d)", requestThreadTid);
2806 }
2807 }
2808
2809 // Update device state
2810 const camera_metadata_t *newSessionParams = sessionParams.getAndLock();
2811 const camera_metadata_t *currentSessionParams = mSessionParams.getAndLock();
2812 bool updateSessionParams = (newSessionParams != currentSessionParams) ? true : false;
2813 sessionParams.unlock(newSessionParams);
2814 mSessionParams.unlock(currentSessionParams);
2815 if (updateSessionParams) {
2816 mSessionParams = sessionParams;
2817 }
2818
2819 mNeedConfig = false;
2820
2821 internalUpdateStatusLocked((mFakeStreamId == NO_STREAM) ?
2822 STATUS_CONFIGURED : STATUS_UNCONFIGURED);
2823
2824 ALOGV("%s: Camera %s: Stream configuration complete", __FUNCTION__, mId.string());
2825
2826 // tear down the deleted streams after configure streams.
2827 mDeletedStreams.clear();
2828
2829 auto rc = mPreparerThread->resume();
2830 if (rc != OK) {
2831 SET_ERR_L("%s: Camera %s: Preparer thread failed to resume!", __FUNCTION__, mId.string());
2832 return rc;
2833 }
2834
2835 if (mFakeStreamId == NO_STREAM) {
2836 mRequestBufferSM.onStreamsConfigured();
2837 }
2838
2839 // Since the streams configuration of the injection camera is based on the internal camera, we
2840 // must wait until the internal camera configure streams before calling injectCamera() to
2841 // configure the injection streams.
2842 if (mInjectionMethods->isInjecting()) {
2843 ALOGV("%s: Injection camera %s: Start to configure streams.",
2844 __FUNCTION__, mInjectionMethods->getInjectedCamId().string());
2845 res = mInjectionMethods->injectCamera(config, bufferSizes);
2846 if (res != OK) {
2847 ALOGE("Can't finish inject camera process!");
2848 return res;
2849 }
2850 }
2851
2852 return OK;
2853 }
2854
addFakeStreamLocked()2855 status_t Camera3Device::addFakeStreamLocked() {
2856 ATRACE_CALL();
2857 status_t res;
2858
2859 if (mFakeStreamId != NO_STREAM) {
2860 // Should never be adding a second fake stream when one is already
2861 // active
2862 SET_ERR_L("%s: Camera %s: A fake stream already exists!",
2863 __FUNCTION__, mId.string());
2864 return INVALID_OPERATION;
2865 }
2866
2867 ALOGV("%s: Camera %s: Adding a fake stream", __FUNCTION__, mId.string());
2868
2869 sp<Camera3OutputStreamInterface> fakeStream =
2870 new Camera3FakeStream(mNextStreamId);
2871
2872 res = mOutputStreams.add(mNextStreamId, fakeStream);
2873 if (res < 0) {
2874 SET_ERR_L("Can't add fake stream to set: %s (%d)", strerror(-res), res);
2875 return res;
2876 }
2877
2878 mFakeStreamId = mNextStreamId;
2879 mNextStreamId++;
2880
2881 return OK;
2882 }
2883
tryRemoveFakeStreamLocked()2884 status_t Camera3Device::tryRemoveFakeStreamLocked() {
2885 ATRACE_CALL();
2886 status_t res;
2887
2888 if (mFakeStreamId == NO_STREAM) return OK;
2889 if (mOutputStreams.size() == 1) return OK;
2890
2891 ALOGV("%s: Camera %s: Removing the fake stream", __FUNCTION__, mId.string());
2892
2893 // Ok, have a fake stream and there's at least one other output stream,
2894 // so remove the fake
2895
2896 sp<Camera3StreamInterface> deletedStream = mOutputStreams.get(mFakeStreamId);
2897 if (deletedStream == nullptr) {
2898 SET_ERR_L("Fake stream %d does not appear to exist", mFakeStreamId);
2899 return INVALID_OPERATION;
2900 }
2901 mOutputStreams.remove(mFakeStreamId);
2902
2903 // Free up the stream endpoint so that it can be used by some other stream
2904 res = deletedStream->disconnect();
2905 if (res != OK) {
2906 SET_ERR_L("Can't disconnect deleted fake stream %d", mFakeStreamId);
2907 // fall through since we want to still list the stream as deleted.
2908 }
2909 mDeletedStreams.add(deletedStream);
2910 mFakeStreamId = NO_STREAM;
2911
2912 return res;
2913 }
2914
setErrorState(const char * fmt,...)2915 void Camera3Device::setErrorState(const char *fmt, ...) {
2916 ATRACE_CALL();
2917 Mutex::Autolock l(mLock);
2918 va_list args;
2919 va_start(args, fmt);
2920
2921 setErrorStateLockedV(fmt, args);
2922
2923 va_end(args);
2924 }
2925
setErrorStateV(const char * fmt,va_list args)2926 void Camera3Device::setErrorStateV(const char *fmt, va_list args) {
2927 ATRACE_CALL();
2928 Mutex::Autolock l(mLock);
2929 setErrorStateLockedV(fmt, args);
2930 }
2931
setErrorStateLocked(const char * fmt,...)2932 void Camera3Device::setErrorStateLocked(const char *fmt, ...) {
2933 va_list args;
2934 va_start(args, fmt);
2935
2936 setErrorStateLockedV(fmt, args);
2937
2938 va_end(args);
2939 }
2940
setErrorStateLockedV(const char * fmt,va_list args)2941 void Camera3Device::setErrorStateLockedV(const char *fmt, va_list args) {
2942 // Print out all error messages to log
2943 String8 errorCause = String8::formatV(fmt, args);
2944 ALOGE("Camera %s: %s", mId.string(), errorCause.string());
2945
2946 // But only do error state transition steps for the first error
2947 if (mStatus == STATUS_ERROR || mStatus == STATUS_UNINITIALIZED) return;
2948
2949 mErrorCause = errorCause;
2950
2951 if (mRequestThread != nullptr) {
2952 mRequestThread->setPaused(true);
2953 }
2954 internalUpdateStatusLocked(STATUS_ERROR);
2955
2956 // Notify upstream about a device error
2957 sp<NotificationListener> listener = mListener.promote();
2958 if (listener != NULL) {
2959 listener->notifyError(hardware::camera2::ICameraDeviceCallbacks::ERROR_CAMERA_DEVICE,
2960 CaptureResultExtras());
2961 mSessionStatsBuilder.onDeviceError();
2962 }
2963
2964 // Save stack trace. View by dumping it later.
2965 CameraTraces::saveTrace();
2966 // TODO: consider adding errorCause and client pid/procname
2967 }
2968
2969 /**
2970 * In-flight request management
2971 */
2972
registerInFlight(uint32_t frameNumber,int32_t numBuffers,CaptureResultExtras resultExtras,bool hasInput,bool hasAppCallback,nsecs_t maxExpectedDuration,const std::set<std::set<String8>> & physicalCameraIds,bool isStillCapture,bool isZslCapture,bool rotateAndCropAuto,const std::set<std::string> & cameraIdsWithZoom,const SurfaceMap & outputSurfaces,nsecs_t requestTimeNs)2973 status_t Camera3Device::registerInFlight(uint32_t frameNumber,
2974 int32_t numBuffers, CaptureResultExtras resultExtras, bool hasInput,
2975 bool hasAppCallback, nsecs_t maxExpectedDuration,
2976 const std::set<std::set<String8>>& physicalCameraIds,
2977 bool isStillCapture, bool isZslCapture, bool rotateAndCropAuto,
2978 const std::set<std::string>& cameraIdsWithZoom,
2979 const SurfaceMap& outputSurfaces, nsecs_t requestTimeNs) {
2980 ATRACE_CALL();
2981 std::lock_guard<std::mutex> l(mInFlightLock);
2982
2983 ssize_t res;
2984 res = mInFlightMap.add(frameNumber, InFlightRequest(numBuffers, resultExtras, hasInput,
2985 hasAppCallback, maxExpectedDuration, physicalCameraIds, isStillCapture, isZslCapture,
2986 rotateAndCropAuto, cameraIdsWithZoom, requestTimeNs, outputSurfaces));
2987 if (res < 0) return res;
2988
2989 if (mInFlightMap.size() == 1) {
2990 // Hold a separate dedicated tracker lock to prevent race with disconnect and also
2991 // avoid a deadlock during reprocess requests.
2992 Mutex::Autolock l(mTrackerLock);
2993 if (mStatusTracker != nullptr) {
2994 mStatusTracker->markComponentActive(mInFlightStatusId);
2995 }
2996 }
2997
2998 mExpectedInflightDuration += maxExpectedDuration;
2999 return OK;
3000 }
3001
onInflightEntryRemovedLocked(nsecs_t duration)3002 void Camera3Device::onInflightEntryRemovedLocked(nsecs_t duration) {
3003 // Indicate idle inFlightMap to the status tracker
3004 if (mInFlightMap.size() == 0) {
3005 mRequestBufferSM.onInflightMapEmpty();
3006 // Hold a separate dedicated tracker lock to prevent race with disconnect and also
3007 // avoid a deadlock during reprocess requests.
3008 Mutex::Autolock l(mTrackerLock);
3009 if (mStatusTracker != nullptr) {
3010 mStatusTracker->markComponentIdle(mInFlightStatusId, Fence::NO_FENCE);
3011 }
3012 }
3013 mExpectedInflightDuration -= duration;
3014 }
3015
checkInflightMapLengthLocked()3016 void Camera3Device::checkInflightMapLengthLocked() {
3017 // Validation check - if we have too many in-flight frames with long total inflight duration,
3018 // something has likely gone wrong. This might still be legit only if application send in
3019 // a long burst of long exposure requests.
3020 if (mExpectedInflightDuration > kMinWarnInflightDuration) {
3021 if (!mIsConstrainedHighSpeedConfiguration && mInFlightMap.size() > kInFlightWarnLimit) {
3022 CLOGW("In-flight list too large: %zu, total inflight duration %" PRIu64,
3023 mInFlightMap.size(), mExpectedInflightDuration);
3024 } else if (mIsConstrainedHighSpeedConfiguration && mInFlightMap.size() >
3025 kInFlightWarnLimitHighSpeed) {
3026 CLOGW("In-flight list too large for high speed configuration: %zu,"
3027 "total inflight duration %" PRIu64,
3028 mInFlightMap.size(), mExpectedInflightDuration);
3029 }
3030 }
3031 }
3032
onInflightMapFlushedLocked()3033 void Camera3Device::onInflightMapFlushedLocked() {
3034 mExpectedInflightDuration = 0;
3035 }
3036
removeInFlightMapEntryLocked(int idx)3037 void Camera3Device::removeInFlightMapEntryLocked(int idx) {
3038 ATRACE_HFR_CALL();
3039 nsecs_t duration = mInFlightMap.valueAt(idx).maxExpectedDuration;
3040 mInFlightMap.removeItemsAt(idx, 1);
3041
3042 onInflightEntryRemovedLocked(duration);
3043 }
3044
3045
flushInflightRequests()3046 void Camera3Device::flushInflightRequests() {
3047 ATRACE_CALL();
3048 sp<NotificationListener> listener;
3049 {
3050 std::lock_guard<std::mutex> l(mOutputLock);
3051 listener = mListener.promote();
3052 }
3053
3054 FlushInflightReqStates states {
3055 mId, mInFlightLock, mInFlightMap, mUseHalBufManager,
3056 listener, *this, *mInterface, *this, mSessionStatsBuilder};
3057
3058 camera3::flushInflightRequests(states);
3059 }
3060
getLatestRequestLocked()3061 CameraMetadata Camera3Device::getLatestRequestLocked() {
3062 ALOGV("%s", __FUNCTION__);
3063
3064 CameraMetadata retVal;
3065
3066 if (mRequestThread != NULL) {
3067 retVal = mRequestThread->getLatestRequest();
3068 }
3069
3070 return retVal;
3071 }
3072
monitorMetadata(TagMonitor::eventSource source,int64_t frameNumber,nsecs_t timestamp,const CameraMetadata & metadata,const std::unordered_map<std::string,CameraMetadata> & physicalMetadata)3073 void Camera3Device::monitorMetadata(TagMonitor::eventSource source,
3074 int64_t frameNumber, nsecs_t timestamp, const CameraMetadata& metadata,
3075 const std::unordered_map<std::string, CameraMetadata>& physicalMetadata) {
3076
3077 mTagMonitor.monitorMetadata(source, frameNumber, timestamp, metadata,
3078 physicalMetadata);
3079 }
3080
3081 /**
3082 * HalInterface inner class methods
3083 */
3084
HalInterface(sp<ICameraDeviceSession> & session,std::shared_ptr<RequestMetadataQueue> queue,bool useHalBufManager,bool supportOfflineProcessing)3085 Camera3Device::HalInterface::HalInterface(
3086 sp<ICameraDeviceSession> &session,
3087 std::shared_ptr<RequestMetadataQueue> queue,
3088 bool useHalBufManager, bool supportOfflineProcessing) :
3089 mHidlSession(session),
3090 mRequestMetadataQueue(queue),
3091 mUseHalBufManager(useHalBufManager),
3092 mIsReconfigurationQuerySupported(true),
3093 mSupportOfflineProcessing(supportOfflineProcessing) {
3094 // Check with hardware service manager if we can downcast these interfaces
3095 // Somewhat expensive, so cache the results at startup
3096 auto castResult_3_7 = device::V3_7::ICameraDeviceSession::castFrom(mHidlSession);
3097 if (castResult_3_7.isOk()) {
3098 mHidlSession_3_7 = castResult_3_7;
3099 }
3100 auto castResult_3_6 = device::V3_6::ICameraDeviceSession::castFrom(mHidlSession);
3101 if (castResult_3_6.isOk()) {
3102 mHidlSession_3_6 = castResult_3_6;
3103 }
3104 auto castResult_3_5 = device::V3_5::ICameraDeviceSession::castFrom(mHidlSession);
3105 if (castResult_3_5.isOk()) {
3106 mHidlSession_3_5 = castResult_3_5;
3107 }
3108 auto castResult_3_4 = device::V3_4::ICameraDeviceSession::castFrom(mHidlSession);
3109 if (castResult_3_4.isOk()) {
3110 mHidlSession_3_4 = castResult_3_4;
3111 }
3112 auto castResult_3_3 = device::V3_3::ICameraDeviceSession::castFrom(mHidlSession);
3113 if (castResult_3_3.isOk()) {
3114 mHidlSession_3_3 = castResult_3_3;
3115 }
3116 }
3117
HalInterface()3118 Camera3Device::HalInterface::HalInterface() :
3119 mUseHalBufManager(false),
3120 mSupportOfflineProcessing(false) {}
3121
HalInterface(const HalInterface & other)3122 Camera3Device::HalInterface::HalInterface(const HalInterface& other) :
3123 mHidlSession(other.mHidlSession),
3124 mRequestMetadataQueue(other.mRequestMetadataQueue),
3125 mUseHalBufManager(other.mUseHalBufManager),
3126 mSupportOfflineProcessing(other.mSupportOfflineProcessing) {}
3127
valid()3128 bool Camera3Device::HalInterface::valid() {
3129 return (mHidlSession != nullptr);
3130 }
3131
clear()3132 void Camera3Device::HalInterface::clear() {
3133 mHidlSession_3_7.clear();
3134 mHidlSession_3_6.clear();
3135 mHidlSession_3_5.clear();
3136 mHidlSession_3_4.clear();
3137 mHidlSession_3_3.clear();
3138 mHidlSession.clear();
3139 }
3140
constructDefaultRequestSettings(camera_request_template_t templateId,camera_metadata_t ** requestTemplate)3141 status_t Camera3Device::HalInterface::constructDefaultRequestSettings(
3142 camera_request_template_t templateId,
3143 /*out*/ camera_metadata_t **requestTemplate) {
3144 ATRACE_NAME("CameraHal::constructDefaultRequestSettings");
3145 if (!valid()) return INVALID_OPERATION;
3146 status_t res = OK;
3147
3148 common::V1_0::Status status;
3149
3150 auto requestCallback = [&status, &requestTemplate]
3151 (common::V1_0::Status s, const device::V3_2::CameraMetadata& request) {
3152 status = s;
3153 if (status == common::V1_0::Status::OK) {
3154 const camera_metadata *r =
3155 reinterpret_cast<const camera_metadata_t*>(request.data());
3156 size_t expectedSize = request.size();
3157 int ret = validate_camera_metadata_structure(r, &expectedSize);
3158 if (ret == OK || ret == CAMERA_METADATA_VALIDATION_SHIFTED) {
3159 *requestTemplate = clone_camera_metadata(r);
3160 if (*requestTemplate == nullptr) {
3161 ALOGE("%s: Unable to clone camera metadata received from HAL",
3162 __FUNCTION__);
3163 status = common::V1_0::Status::INTERNAL_ERROR;
3164 }
3165 } else {
3166 ALOGE("%s: Malformed camera metadata received from HAL", __FUNCTION__);
3167 status = common::V1_0::Status::INTERNAL_ERROR;
3168 }
3169 }
3170 };
3171 hardware::Return<void> err;
3172 RequestTemplate id;
3173 switch (templateId) {
3174 case CAMERA_TEMPLATE_PREVIEW:
3175 id = RequestTemplate::PREVIEW;
3176 break;
3177 case CAMERA_TEMPLATE_STILL_CAPTURE:
3178 id = RequestTemplate::STILL_CAPTURE;
3179 break;
3180 case CAMERA_TEMPLATE_VIDEO_RECORD:
3181 id = RequestTemplate::VIDEO_RECORD;
3182 break;
3183 case CAMERA_TEMPLATE_VIDEO_SNAPSHOT:
3184 id = RequestTemplate::VIDEO_SNAPSHOT;
3185 break;
3186 case CAMERA_TEMPLATE_ZERO_SHUTTER_LAG:
3187 id = RequestTemplate::ZERO_SHUTTER_LAG;
3188 break;
3189 case CAMERA_TEMPLATE_MANUAL:
3190 id = RequestTemplate::MANUAL;
3191 break;
3192 default:
3193 // Unknown template ID, or this HAL is too old to support it
3194 return BAD_VALUE;
3195 }
3196 err = mHidlSession->constructDefaultRequestSettings(id, requestCallback);
3197
3198 if (!err.isOk()) {
3199 ALOGE("%s: Transaction error: %s", __FUNCTION__, err.description().c_str());
3200 res = DEAD_OBJECT;
3201 } else {
3202 res = CameraProviderManager::mapToStatusT(status);
3203 }
3204
3205 return res;
3206 }
3207
isReconfigurationRequired(CameraMetadata & oldSessionParams,CameraMetadata & newSessionParams)3208 bool Camera3Device::HalInterface::isReconfigurationRequired(CameraMetadata& oldSessionParams,
3209 CameraMetadata& newSessionParams) {
3210 // We do reconfiguration by default;
3211 bool ret = true;
3212 if ((mHidlSession_3_5 != nullptr) && mIsReconfigurationQuerySupported) {
3213 android::hardware::hidl_vec<uint8_t> oldParams, newParams;
3214 camera_metadata_t* oldSessioMeta = const_cast<camera_metadata_t*>(
3215 oldSessionParams.getAndLock());
3216 camera_metadata_t* newSessioMeta = const_cast<camera_metadata_t*>(
3217 newSessionParams.getAndLock());
3218 oldParams.setToExternal(reinterpret_cast<uint8_t*>(oldSessioMeta),
3219 get_camera_metadata_size(oldSessioMeta));
3220 newParams.setToExternal(reinterpret_cast<uint8_t*>(newSessioMeta),
3221 get_camera_metadata_size(newSessioMeta));
3222 hardware::camera::common::V1_0::Status callStatus;
3223 bool required;
3224 auto hidlCb = [&callStatus, &required] (hardware::camera::common::V1_0::Status s,
3225 bool requiredFlag) {
3226 callStatus = s;
3227 required = requiredFlag;
3228 };
3229 auto err = mHidlSession_3_5->isReconfigurationRequired(oldParams, newParams, hidlCb);
3230 oldSessionParams.unlock(oldSessioMeta);
3231 newSessionParams.unlock(newSessioMeta);
3232 if (err.isOk()) {
3233 switch (callStatus) {
3234 case hardware::camera::common::V1_0::Status::OK:
3235 ret = required;
3236 break;
3237 case hardware::camera::common::V1_0::Status::METHOD_NOT_SUPPORTED:
3238 mIsReconfigurationQuerySupported = false;
3239 ret = true;
3240 break;
3241 default:
3242 ALOGV("%s: Reconfiguration query failed: %d", __FUNCTION__, callStatus);
3243 ret = true;
3244 }
3245 } else {
3246 ALOGE("%s: Unexpected binder error: %s", __FUNCTION__, err.description().c_str());
3247 ret = true;
3248 }
3249 }
3250
3251 return ret;
3252 }
3253
configureStreams(const camera_metadata_t * sessionParams,camera_stream_configuration * config,const std::vector<uint32_t> & bufferSizes)3254 status_t Camera3Device::HalInterface::configureStreams(const camera_metadata_t *sessionParams,
3255 camera_stream_configuration *config, const std::vector<uint32_t>& bufferSizes) {
3256 ATRACE_NAME("CameraHal::configureStreams");
3257 if (!valid()) return INVALID_OPERATION;
3258 status_t res = OK;
3259
3260 if (config->input_is_multi_resolution && mHidlSession_3_7 == nullptr) {
3261 ALOGE("%s: Camera device doesn't support multi-resolution input stream", __FUNCTION__);
3262 return BAD_VALUE;
3263 }
3264
3265 // Convert stream config to HIDL
3266 std::set<int> activeStreams;
3267 device::V3_2::StreamConfiguration requestedConfiguration3_2;
3268 device::V3_4::StreamConfiguration requestedConfiguration3_4;
3269 device::V3_7::StreamConfiguration requestedConfiguration3_7;
3270 requestedConfiguration3_2.streams.resize(config->num_streams);
3271 requestedConfiguration3_4.streams.resize(config->num_streams);
3272 requestedConfiguration3_7.streams.resize(config->num_streams);
3273 for (size_t i = 0; i < config->num_streams; i++) {
3274 device::V3_2::Stream &dst3_2 = requestedConfiguration3_2.streams[i];
3275 device::V3_4::Stream &dst3_4 = requestedConfiguration3_4.streams[i];
3276 device::V3_7::Stream &dst3_7 = requestedConfiguration3_7.streams[i];
3277 camera3::camera_stream_t *src = config->streams[i];
3278
3279 Camera3Stream* cam3stream = Camera3Stream::cast(src);
3280 cam3stream->setBufferFreedListener(this);
3281 int streamId = cam3stream->getId();
3282 StreamType streamType;
3283 switch (src->stream_type) {
3284 case CAMERA_STREAM_OUTPUT:
3285 streamType = StreamType::OUTPUT;
3286 break;
3287 case CAMERA_STREAM_INPUT:
3288 streamType = StreamType::INPUT;
3289 break;
3290 default:
3291 ALOGE("%s: Stream %d: Unsupported stream type %d",
3292 __FUNCTION__, streamId, config->streams[i]->stream_type);
3293 return BAD_VALUE;
3294 }
3295 dst3_2.id = streamId;
3296 dst3_2.streamType = streamType;
3297 dst3_2.width = src->width;
3298 dst3_2.height = src->height;
3299 dst3_2.usage = mapToConsumerUsage(cam3stream->getUsage());
3300 dst3_2.rotation = mapToStreamRotation((camera_stream_rotation_t) src->rotation);
3301 // For HidlSession version 3.5 or newer, the format and dataSpace sent
3302 // to HAL are original, not the overridden ones.
3303 if (mHidlSession_3_5 != nullptr) {
3304 dst3_2.format = mapToPixelFormat(cam3stream->isFormatOverridden() ?
3305 cam3stream->getOriginalFormat() : src->format);
3306 dst3_2.dataSpace = mapToHidlDataspace(cam3stream->isDataSpaceOverridden() ?
3307 cam3stream->getOriginalDataSpace() : src->data_space);
3308 } else {
3309 dst3_2.format = mapToPixelFormat(src->format);
3310 dst3_2.dataSpace = mapToHidlDataspace(src->data_space);
3311 }
3312 dst3_4.v3_2 = dst3_2;
3313 dst3_4.bufferSize = bufferSizes[i];
3314 if (src->physical_camera_id != nullptr) {
3315 dst3_4.physicalCameraId = src->physical_camera_id;
3316 }
3317 dst3_7.v3_4 = dst3_4;
3318 dst3_7.groupId = cam3stream->getHalStreamGroupId();
3319 dst3_7.sensorPixelModesUsed.resize(src->sensor_pixel_modes_used.size());
3320 size_t j = 0;
3321 for (int mode : src->sensor_pixel_modes_used) {
3322 dst3_7.sensorPixelModesUsed[j++] =
3323 static_cast<CameraMetadataEnumAndroidSensorPixelMode>(mode);
3324 }
3325 activeStreams.insert(streamId);
3326 // Create Buffer ID map if necessary
3327 mBufferRecords.tryCreateBufferCache(streamId);
3328 }
3329 // remove BufferIdMap for deleted streams
3330 mBufferRecords.removeInactiveBufferCaches(activeStreams);
3331
3332 StreamConfigurationMode operationMode;
3333 res = mapToStreamConfigurationMode(
3334 (camera_stream_configuration_mode_t) config->operation_mode,
3335 /*out*/ &operationMode);
3336 if (res != OK) {
3337 return res;
3338 }
3339 requestedConfiguration3_2.operationMode = operationMode;
3340 requestedConfiguration3_4.operationMode = operationMode;
3341 requestedConfiguration3_7.operationMode = operationMode;
3342 size_t sessionParamSize = get_camera_metadata_size(sessionParams);
3343 requestedConfiguration3_4.sessionParams.setToExternal(
3344 reinterpret_cast<uint8_t*>(const_cast<camera_metadata_t*>(sessionParams)),
3345 sessionParamSize);
3346 requestedConfiguration3_7.operationMode = operationMode;
3347 requestedConfiguration3_7.sessionParams.setToExternal(
3348 reinterpret_cast<uint8_t*>(const_cast<camera_metadata_t*>(sessionParams)),
3349 sessionParamSize);
3350
3351 // Invoke configureStreams
3352 device::V3_3::HalStreamConfiguration finalConfiguration;
3353 device::V3_4::HalStreamConfiguration finalConfiguration3_4;
3354 device::V3_6::HalStreamConfiguration finalConfiguration3_6;
3355 common::V1_0::Status status;
3356
3357 auto configStream34Cb = [&status, &finalConfiguration3_4]
3358 (common::V1_0::Status s, const device::V3_4::HalStreamConfiguration& halConfiguration) {
3359 finalConfiguration3_4 = halConfiguration;
3360 status = s;
3361 };
3362
3363 auto configStream36Cb = [&status, &finalConfiguration3_6]
3364 (common::V1_0::Status s, const device::V3_6::HalStreamConfiguration& halConfiguration) {
3365 finalConfiguration3_6 = halConfiguration;
3366 status = s;
3367 };
3368
3369 auto postprocConfigStream34 = [&finalConfiguration, &finalConfiguration3_4]
3370 (hardware::Return<void>& err) -> status_t {
3371 if (!err.isOk()) {
3372 ALOGE("%s: Transaction error: %s", __FUNCTION__, err.description().c_str());
3373 return DEAD_OBJECT;
3374 }
3375 finalConfiguration.streams.resize(finalConfiguration3_4.streams.size());
3376 for (size_t i = 0; i < finalConfiguration3_4.streams.size(); i++) {
3377 finalConfiguration.streams[i] = finalConfiguration3_4.streams[i].v3_3;
3378 }
3379 return OK;
3380 };
3381
3382 auto postprocConfigStream36 = [&finalConfiguration, &finalConfiguration3_6]
3383 (hardware::Return<void>& err) -> status_t {
3384 if (!err.isOk()) {
3385 ALOGE("%s: Transaction error: %s", __FUNCTION__, err.description().c_str());
3386 return DEAD_OBJECT;
3387 }
3388 finalConfiguration.streams.resize(finalConfiguration3_6.streams.size());
3389 for (size_t i = 0; i < finalConfiguration3_6.streams.size(); i++) {
3390 finalConfiguration.streams[i] = finalConfiguration3_6.streams[i].v3_4.v3_3;
3391 }
3392 return OK;
3393 };
3394
3395 // See which version of HAL we have
3396 if (mHidlSession_3_7 != nullptr) {
3397 ALOGV("%s: v3.7 device found", __FUNCTION__);
3398 requestedConfiguration3_7.streamConfigCounter = mNextStreamConfigCounter++;
3399 requestedConfiguration3_7.multiResolutionInputImage = config->input_is_multi_resolution;
3400 auto err = mHidlSession_3_7->configureStreams_3_7(
3401 requestedConfiguration3_7, configStream36Cb);
3402 res = postprocConfigStream36(err);
3403 if (res != OK) {
3404 return res;
3405 }
3406 } else if (mHidlSession_3_6 != nullptr) {
3407 ALOGV("%s: v3.6 device found", __FUNCTION__);
3408 device::V3_5::StreamConfiguration requestedConfiguration3_5;
3409 requestedConfiguration3_5.v3_4 = requestedConfiguration3_4;
3410 requestedConfiguration3_5.streamConfigCounter = mNextStreamConfigCounter++;
3411 auto err = mHidlSession_3_6->configureStreams_3_6(
3412 requestedConfiguration3_5, configStream36Cb);
3413 res = postprocConfigStream36(err);
3414 if (res != OK) {
3415 return res;
3416 }
3417 } else if (mHidlSession_3_5 != nullptr) {
3418 ALOGV("%s: v3.5 device found", __FUNCTION__);
3419 device::V3_5::StreamConfiguration requestedConfiguration3_5;
3420 requestedConfiguration3_5.v3_4 = requestedConfiguration3_4;
3421 requestedConfiguration3_5.streamConfigCounter = mNextStreamConfigCounter++;
3422 auto err = mHidlSession_3_5->configureStreams_3_5(
3423 requestedConfiguration3_5, configStream34Cb);
3424 res = postprocConfigStream34(err);
3425 if (res != OK) {
3426 return res;
3427 }
3428 } else if (mHidlSession_3_4 != nullptr) {
3429 // We do; use v3.4 for the call
3430 ALOGV("%s: v3.4 device found", __FUNCTION__);
3431 auto err = mHidlSession_3_4->configureStreams_3_4(
3432 requestedConfiguration3_4, configStream34Cb);
3433 res = postprocConfigStream34(err);
3434 if (res != OK) {
3435 return res;
3436 }
3437 } else if (mHidlSession_3_3 != nullptr) {
3438 // We do; use v3.3 for the call
3439 ALOGV("%s: v3.3 device found", __FUNCTION__);
3440 auto err = mHidlSession_3_3->configureStreams_3_3(requestedConfiguration3_2,
3441 [&status, &finalConfiguration]
3442 (common::V1_0::Status s, const device::V3_3::HalStreamConfiguration& halConfiguration) {
3443 finalConfiguration = halConfiguration;
3444 status = s;
3445 });
3446 if (!err.isOk()) {
3447 ALOGE("%s: Transaction error: %s", __FUNCTION__, err.description().c_str());
3448 return DEAD_OBJECT;
3449 }
3450 } else {
3451 // We don't; use v3.2 call and construct a v3.3 HalStreamConfiguration
3452 ALOGV("%s: v3.2 device found", __FUNCTION__);
3453 HalStreamConfiguration finalConfiguration_3_2;
3454 auto err = mHidlSession->configureStreams(requestedConfiguration3_2,
3455 [&status, &finalConfiguration_3_2]
3456 (common::V1_0::Status s, const HalStreamConfiguration& halConfiguration) {
3457 finalConfiguration_3_2 = halConfiguration;
3458 status = s;
3459 });
3460 if (!err.isOk()) {
3461 ALOGE("%s: Transaction error: %s", __FUNCTION__, err.description().c_str());
3462 return DEAD_OBJECT;
3463 }
3464 finalConfiguration.streams.resize(finalConfiguration_3_2.streams.size());
3465 for (size_t i = 0; i < finalConfiguration_3_2.streams.size(); i++) {
3466 finalConfiguration.streams[i].v3_2 = finalConfiguration_3_2.streams[i];
3467 finalConfiguration.streams[i].overrideDataSpace =
3468 requestedConfiguration3_2.streams[i].dataSpace;
3469 }
3470 }
3471
3472 if (status != common::V1_0::Status::OK ) {
3473 return CameraProviderManager::mapToStatusT(status);
3474 }
3475
3476 // And convert output stream configuration from HIDL
3477
3478 for (size_t i = 0; i < config->num_streams; i++) {
3479 camera3::camera_stream_t *dst = config->streams[i];
3480 int streamId = Camera3Stream::cast(dst)->getId();
3481
3482 // Start scan at i, with the assumption that the stream order matches
3483 size_t realIdx = i;
3484 bool found = false;
3485 size_t halStreamCount = finalConfiguration.streams.size();
3486 for (size_t idx = 0; idx < halStreamCount; idx++) {
3487 if (finalConfiguration.streams[realIdx].v3_2.id == streamId) {
3488 found = true;
3489 break;
3490 }
3491 realIdx = (realIdx >= halStreamCount - 1) ? 0 : realIdx + 1;
3492 }
3493 if (!found) {
3494 ALOGE("%s: Stream %d not found in stream configuration response from HAL",
3495 __FUNCTION__, streamId);
3496 return INVALID_OPERATION;
3497 }
3498 device::V3_3::HalStream &src = finalConfiguration.streams[realIdx];
3499 device::V3_6::HalStream &src_36 = finalConfiguration3_6.streams[realIdx];
3500
3501 Camera3Stream* dstStream = Camera3Stream::cast(dst);
3502 int overrideFormat = mapToFrameworkFormat(src.v3_2.overrideFormat);
3503 android_dataspace overrideDataSpace = mapToFrameworkDataspace(src.overrideDataSpace);
3504
3505 if (mHidlSession_3_6 != nullptr) {
3506 dstStream->setOfflineProcessingSupport(src_36.supportOffline);
3507 }
3508
3509 if (dstStream->getOriginalFormat() != HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED) {
3510 dstStream->setFormatOverride(false);
3511 dstStream->setDataSpaceOverride(false);
3512 if (dst->format != overrideFormat) {
3513 ALOGE("%s: Stream %d: Format override not allowed for format 0x%x", __FUNCTION__,
3514 streamId, dst->format);
3515 }
3516 if (dst->data_space != overrideDataSpace) {
3517 ALOGE("%s: Stream %d: DataSpace override not allowed for format 0x%x", __FUNCTION__,
3518 streamId, dst->format);
3519 }
3520 } else {
3521 bool needFormatOverride =
3522 requestedConfiguration3_2.streams[i].format != src.v3_2.overrideFormat;
3523 bool needDataspaceOverride =
3524 requestedConfiguration3_2.streams[i].dataSpace != src.overrideDataSpace;
3525 // Override allowed with IMPLEMENTATION_DEFINED
3526 dstStream->setFormatOverride(needFormatOverride);
3527 dstStream->setDataSpaceOverride(needDataspaceOverride);
3528 dst->format = overrideFormat;
3529 dst->data_space = overrideDataSpace;
3530 }
3531
3532 if (dst->stream_type == CAMERA_STREAM_INPUT) {
3533 if (src.v3_2.producerUsage != 0) {
3534 ALOGE("%s: Stream %d: INPUT streams must have 0 for producer usage",
3535 __FUNCTION__, streamId);
3536 return INVALID_OPERATION;
3537 }
3538 dstStream->setUsage(
3539 mapConsumerToFrameworkUsage(src.v3_2.consumerUsage));
3540 } else {
3541 // OUTPUT
3542 if (src.v3_2.consumerUsage != 0) {
3543 ALOGE("%s: Stream %d: OUTPUT streams must have 0 for consumer usage",
3544 __FUNCTION__, streamId);
3545 return INVALID_OPERATION;
3546 }
3547 dstStream->setUsage(
3548 mapProducerToFrameworkUsage(src.v3_2.producerUsage));
3549 }
3550 dst->max_buffers = src.v3_2.maxBuffers;
3551 }
3552
3553 return res;
3554 }
3555
configureInjectedStreams(const camera_metadata_t * sessionParams,camera_stream_configuration * config,const std::vector<uint32_t> & bufferSizes,const CameraMetadata & cameraCharacteristics)3556 status_t Camera3Device::HalInterface::configureInjectedStreams(
3557 const camera_metadata_t* sessionParams, camera_stream_configuration* config,
3558 const std::vector<uint32_t>& bufferSizes,
3559 const CameraMetadata& cameraCharacteristics) {
3560 ATRACE_NAME("InjectionCameraHal::configureStreams");
3561 if (!valid()) return INVALID_OPERATION;
3562 status_t res = OK;
3563
3564 if (config->input_is_multi_resolution) {
3565 ALOGE("%s: Injection camera device doesn't support multi-resolution input "
3566 "stream", __FUNCTION__);
3567 return BAD_VALUE;
3568 }
3569
3570 // Convert stream config to HIDL
3571 std::set<int> activeStreams;
3572 device::V3_2::StreamConfiguration requestedConfiguration3_2;
3573 device::V3_4::StreamConfiguration requestedConfiguration3_4;
3574 device::V3_7::StreamConfiguration requestedConfiguration3_7;
3575 requestedConfiguration3_2.streams.resize(config->num_streams);
3576 requestedConfiguration3_4.streams.resize(config->num_streams);
3577 requestedConfiguration3_7.streams.resize(config->num_streams);
3578 for (size_t i = 0; i < config->num_streams; i++) {
3579 device::V3_2::Stream& dst3_2 = requestedConfiguration3_2.streams[i];
3580 device::V3_4::Stream& dst3_4 = requestedConfiguration3_4.streams[i];
3581 device::V3_7::Stream& dst3_7 = requestedConfiguration3_7.streams[i];
3582 camera3::camera_stream_t* src = config->streams[i];
3583
3584 Camera3Stream* cam3stream = Camera3Stream::cast(src);
3585 cam3stream->setBufferFreedListener(this);
3586 int streamId = cam3stream->getId();
3587 StreamType streamType;
3588 switch (src->stream_type) {
3589 case CAMERA_STREAM_OUTPUT:
3590 streamType = StreamType::OUTPUT;
3591 break;
3592 case CAMERA_STREAM_INPUT:
3593 streamType = StreamType::INPUT;
3594 break;
3595 default:
3596 ALOGE("%s: Stream %d: Unsupported stream type %d", __FUNCTION__,
3597 streamId, config->streams[i]->stream_type);
3598 return BAD_VALUE;
3599 }
3600 dst3_2.id = streamId;
3601 dst3_2.streamType = streamType;
3602 dst3_2.width = src->width;
3603 dst3_2.height = src->height;
3604 dst3_2.usage = mapToConsumerUsage(cam3stream->getUsage());
3605 dst3_2.rotation =
3606 mapToStreamRotation((camera_stream_rotation_t)src->rotation);
3607 // For HidlSession version 3.5 or newer, the format and dataSpace sent
3608 // to HAL are original, not the overridden ones.
3609 if (mHidlSession_3_5 != nullptr) {
3610 dst3_2.format = mapToPixelFormat(cam3stream->isFormatOverridden()
3611 ? cam3stream->getOriginalFormat()
3612 : src->format);
3613 dst3_2.dataSpace =
3614 mapToHidlDataspace(cam3stream->isDataSpaceOverridden()
3615 ? cam3stream->getOriginalDataSpace()
3616 : src->data_space);
3617 } else {
3618 dst3_2.format = mapToPixelFormat(src->format);
3619 dst3_2.dataSpace = mapToHidlDataspace(src->data_space);
3620 }
3621 dst3_4.v3_2 = dst3_2;
3622 dst3_4.bufferSize = bufferSizes[i];
3623 if (src->physical_camera_id != nullptr) {
3624 dst3_4.physicalCameraId = src->physical_camera_id;
3625 }
3626 dst3_7.v3_4 = dst3_4;
3627 dst3_7.groupId = cam3stream->getHalStreamGroupId();
3628 dst3_7.sensorPixelModesUsed.resize(src->sensor_pixel_modes_used.size());
3629 size_t j = 0;
3630 for (int mode : src->sensor_pixel_modes_used) {
3631 dst3_7.sensorPixelModesUsed[j++] =
3632 static_cast<CameraMetadataEnumAndroidSensorPixelMode>(mode);
3633 }
3634 activeStreams.insert(streamId);
3635 // Create Buffer ID map if necessary
3636 mBufferRecords.tryCreateBufferCache(streamId);
3637 }
3638 // remove BufferIdMap for deleted streams
3639 mBufferRecords.removeInactiveBufferCaches(activeStreams);
3640
3641 StreamConfigurationMode operationMode;
3642 res = mapToStreamConfigurationMode(
3643 (camera_stream_configuration_mode_t)config->operation_mode,
3644 /*out*/ &operationMode);
3645 if (res != OK) {
3646 return res;
3647 }
3648 requestedConfiguration3_7.operationMode = operationMode;
3649 size_t sessionParamSize = get_camera_metadata_size(sessionParams);
3650 requestedConfiguration3_7.operationMode = operationMode;
3651 requestedConfiguration3_7.sessionParams.setToExternal(
3652 reinterpret_cast<uint8_t*>(const_cast<camera_metadata_t*>(sessionParams)),
3653 sessionParamSize);
3654
3655 // See which version of HAL we have
3656 if (mHidlSession_3_7 != nullptr) {
3657 requestedConfiguration3_7.streamConfigCounter = mNextStreamConfigCounter++;
3658 requestedConfiguration3_7.multiResolutionInputImage =
3659 config->input_is_multi_resolution;
3660
3661 const camera_metadata_t* rawMetadata = cameraCharacteristics.getAndLock();
3662 ::android::hardware::camera::device::V3_2::CameraMetadata hidlChars = {};
3663 hidlChars.setToExternal(
3664 reinterpret_cast<uint8_t*>(const_cast<camera_metadata_t*>(rawMetadata)),
3665 get_camera_metadata_size(rawMetadata));
3666 cameraCharacteristics.unlock(rawMetadata);
3667
3668 sp<hardware::camera::device::V3_7::ICameraInjectionSession>
3669 hidlInjectionSession_3_7;
3670 auto castInjectionResult_3_7 =
3671 device::V3_7::ICameraInjectionSession::castFrom(mHidlSession_3_7);
3672 if (castInjectionResult_3_7.isOk()) {
3673 hidlInjectionSession_3_7 = castInjectionResult_3_7;
3674 } else {
3675 ALOGE("%s: Transaction error: %s", __FUNCTION__,
3676 castInjectionResult_3_7.description().c_str());
3677 return DEAD_OBJECT;
3678 }
3679
3680 auto err = hidlInjectionSession_3_7->configureInjectionStreams(
3681 requestedConfiguration3_7, hidlChars);
3682 if (!err.isOk()) {
3683 ALOGE("%s: Transaction error: %s", __FUNCTION__,
3684 err.description().c_str());
3685 return DEAD_OBJECT;
3686 }
3687 } else {
3688 ALOGE("%s: mHidlSession_3_7 does not exist, the lowest version of injection "
3689 "session is 3.7", __FUNCTION__);
3690 return DEAD_OBJECT;
3691 }
3692
3693 return res;
3694 }
3695
wrapAsHidlRequest(camera_capture_request_t * request,device::V3_2::CaptureRequest * captureRequest,std::vector<native_handle_t * > * handlesCreated,std::vector<std::pair<int32_t,int32_t>> * inflightBuffers)3696 status_t Camera3Device::HalInterface::wrapAsHidlRequest(camera_capture_request_t* request,
3697 /*out*/device::V3_2::CaptureRequest* captureRequest,
3698 /*out*/std::vector<native_handle_t*>* handlesCreated,
3699 /*out*/std::vector<std::pair<int32_t, int32_t>>* inflightBuffers) {
3700 ATRACE_CALL();
3701 if (captureRequest == nullptr || handlesCreated == nullptr || inflightBuffers == nullptr) {
3702 ALOGE("%s: captureRequest (%p), handlesCreated (%p), and inflightBuffers(%p) "
3703 "must not be null", __FUNCTION__, captureRequest, handlesCreated, inflightBuffers);
3704 return BAD_VALUE;
3705 }
3706
3707 captureRequest->frameNumber = request->frame_number;
3708
3709 captureRequest->fmqSettingsSize = 0;
3710
3711 {
3712 if (request->input_buffer != nullptr) {
3713 int32_t streamId = Camera3Stream::cast(request->input_buffer->stream)->getId();
3714 buffer_handle_t buf = *(request->input_buffer->buffer);
3715 auto pair = getBufferId(buf, streamId);
3716 bool isNewBuffer = pair.first;
3717 uint64_t bufferId = pair.second;
3718 captureRequest->inputBuffer.streamId = streamId;
3719 captureRequest->inputBuffer.bufferId = bufferId;
3720 captureRequest->inputBuffer.buffer = (isNewBuffer) ? buf : nullptr;
3721 captureRequest->inputBuffer.status = BufferStatus::OK;
3722 native_handle_t *acquireFence = nullptr;
3723 if (request->input_buffer->acquire_fence != -1) {
3724 acquireFence = native_handle_create(1,0);
3725 acquireFence->data[0] = request->input_buffer->acquire_fence;
3726 handlesCreated->push_back(acquireFence);
3727 }
3728 captureRequest->inputBuffer.acquireFence = acquireFence;
3729 captureRequest->inputBuffer.releaseFence = nullptr;
3730
3731 mBufferRecords.pushInflightBuffer(captureRequest->frameNumber, streamId,
3732 request->input_buffer->buffer);
3733 inflightBuffers->push_back(std::make_pair(captureRequest->frameNumber, streamId));
3734 } else {
3735 captureRequest->inputBuffer.streamId = -1;
3736 captureRequest->inputBuffer.bufferId = BUFFER_ID_NO_BUFFER;
3737 }
3738
3739 captureRequest->outputBuffers.resize(request->num_output_buffers);
3740 for (size_t i = 0; i < request->num_output_buffers; i++) {
3741 const camera_stream_buffer_t *src = request->output_buffers + i;
3742 StreamBuffer &dst = captureRequest->outputBuffers[i];
3743 int32_t streamId = Camera3Stream::cast(src->stream)->getId();
3744 if (src->buffer != nullptr) {
3745 buffer_handle_t buf = *(src->buffer);
3746 auto pair = getBufferId(buf, streamId);
3747 bool isNewBuffer = pair.first;
3748 dst.bufferId = pair.second;
3749 dst.buffer = isNewBuffer ? buf : nullptr;
3750 native_handle_t *acquireFence = nullptr;
3751 if (src->acquire_fence != -1) {
3752 acquireFence = native_handle_create(1,0);
3753 acquireFence->data[0] = src->acquire_fence;
3754 handlesCreated->push_back(acquireFence);
3755 }
3756 dst.acquireFence = acquireFence;
3757 } else if (mUseHalBufManager) {
3758 // HAL buffer management path
3759 dst.bufferId = BUFFER_ID_NO_BUFFER;
3760 dst.buffer = nullptr;
3761 dst.acquireFence = nullptr;
3762 } else {
3763 ALOGE("%s: cannot send a null buffer in capture request!", __FUNCTION__);
3764 return BAD_VALUE;
3765 }
3766 dst.streamId = streamId;
3767 dst.status = BufferStatus::OK;
3768 dst.releaseFence = nullptr;
3769
3770 // Output buffers are empty when using HAL buffer manager
3771 if (!mUseHalBufManager) {
3772 mBufferRecords.pushInflightBuffer(
3773 captureRequest->frameNumber, streamId, src->buffer);
3774 inflightBuffers->push_back(std::make_pair(captureRequest->frameNumber, streamId));
3775 }
3776 }
3777 }
3778 return OK;
3779 }
3780
cleanupNativeHandles(std::vector<native_handle_t * > * handles,bool closeFd)3781 void Camera3Device::HalInterface::cleanupNativeHandles(
3782 std::vector<native_handle_t*> *handles, bool closeFd) {
3783 if (handles == nullptr) {
3784 return;
3785 }
3786 if (closeFd) {
3787 for (auto& handle : *handles) {
3788 native_handle_close(handle);
3789 }
3790 }
3791 for (auto& handle : *handles) {
3792 native_handle_delete(handle);
3793 }
3794 handles->clear();
3795 return;
3796 }
3797
processBatchCaptureRequests(std::vector<camera_capture_request_t * > & requests,uint32_t * numRequestProcessed)3798 status_t Camera3Device::HalInterface::processBatchCaptureRequests(
3799 std::vector<camera_capture_request_t*>& requests,/*out*/uint32_t* numRequestProcessed) {
3800 ATRACE_NAME("CameraHal::processBatchCaptureRequests");
3801 if (!valid()) return INVALID_OPERATION;
3802
3803 sp<device::V3_4::ICameraDeviceSession> hidlSession_3_4;
3804 sp<device::V3_7::ICameraDeviceSession> hidlSession_3_7;
3805 auto castResult_3_7 = device::V3_7::ICameraDeviceSession::castFrom(mHidlSession);
3806 if (castResult_3_7.isOk()) {
3807 hidlSession_3_7 = castResult_3_7;
3808 }
3809 auto castResult_3_4 = device::V3_4::ICameraDeviceSession::castFrom(mHidlSession);
3810 if (castResult_3_4.isOk()) {
3811 hidlSession_3_4 = castResult_3_4;
3812 }
3813
3814 hardware::hidl_vec<device::V3_2::CaptureRequest> captureRequests;
3815 hardware::hidl_vec<device::V3_4::CaptureRequest> captureRequests_3_4;
3816 hardware::hidl_vec<device::V3_7::CaptureRequest> captureRequests_3_7;
3817 size_t batchSize = requests.size();
3818 if (hidlSession_3_7 != nullptr) {
3819 captureRequests_3_7.resize(batchSize);
3820 } else if (hidlSession_3_4 != nullptr) {
3821 captureRequests_3_4.resize(batchSize);
3822 } else {
3823 captureRequests.resize(batchSize);
3824 }
3825 std::vector<native_handle_t*> handlesCreated;
3826 std::vector<std::pair<int32_t, int32_t>> inflightBuffers;
3827
3828 status_t res = OK;
3829 for (size_t i = 0; i < batchSize; i++) {
3830 if (hidlSession_3_7 != nullptr) {
3831 res = wrapAsHidlRequest(requests[i], /*out*/&captureRequests_3_7[i].v3_4.v3_2,
3832 /*out*/&handlesCreated, /*out*/&inflightBuffers);
3833 } else if (hidlSession_3_4 != nullptr) {
3834 res = wrapAsHidlRequest(requests[i], /*out*/&captureRequests_3_4[i].v3_2,
3835 /*out*/&handlesCreated, /*out*/&inflightBuffers);
3836 } else {
3837 res = wrapAsHidlRequest(requests[i], /*out*/&captureRequests[i],
3838 /*out*/&handlesCreated, /*out*/&inflightBuffers);
3839 }
3840 if (res != OK) {
3841 mBufferRecords.popInflightBuffers(inflightBuffers);
3842 cleanupNativeHandles(&handlesCreated);
3843 return res;
3844 }
3845 }
3846
3847 std::vector<device::V3_2::BufferCache> cachesToRemove;
3848 {
3849 std::lock_guard<std::mutex> lock(mFreedBuffersLock);
3850 for (auto& pair : mFreedBuffers) {
3851 // The stream might have been removed since onBufferFreed
3852 if (mBufferRecords.isStreamCached(pair.first)) {
3853 cachesToRemove.push_back({pair.first, pair.second});
3854 }
3855 }
3856 mFreedBuffers.clear();
3857 }
3858
3859 common::V1_0::Status status = common::V1_0::Status::INTERNAL_ERROR;
3860 *numRequestProcessed = 0;
3861
3862 // Write metadata to FMQ.
3863 for (size_t i = 0; i < batchSize; i++) {
3864 camera_capture_request_t* request = requests[i];
3865 device::V3_2::CaptureRequest* captureRequest;
3866 if (hidlSession_3_7 != nullptr) {
3867 captureRequest = &captureRequests_3_7[i].v3_4.v3_2;
3868 } else if (hidlSession_3_4 != nullptr) {
3869 captureRequest = &captureRequests_3_4[i].v3_2;
3870 } else {
3871 captureRequest = &captureRequests[i];
3872 }
3873
3874 if (request->settings != nullptr) {
3875 size_t settingsSize = get_camera_metadata_size(request->settings);
3876 if (mRequestMetadataQueue != nullptr && mRequestMetadataQueue->write(
3877 reinterpret_cast<const uint8_t*>(request->settings), settingsSize)) {
3878 captureRequest->settings.resize(0);
3879 captureRequest->fmqSettingsSize = settingsSize;
3880 } else {
3881 if (mRequestMetadataQueue != nullptr) {
3882 ALOGW("%s: couldn't utilize fmq, fallback to hwbinder", __FUNCTION__);
3883 }
3884 captureRequest->settings.setToExternal(
3885 reinterpret_cast<uint8_t*>(const_cast<camera_metadata_t*>(request->settings)),
3886 get_camera_metadata_size(request->settings));
3887 captureRequest->fmqSettingsSize = 0u;
3888 }
3889 } else {
3890 // A null request settings maps to a size-0 CameraMetadata
3891 captureRequest->settings.resize(0);
3892 captureRequest->fmqSettingsSize = 0u;
3893 }
3894
3895 // hidl session 3.7 specific handling.
3896 if (hidlSession_3_7 != nullptr) {
3897 captureRequests_3_7[i].inputWidth = request->input_width;
3898 captureRequests_3_7[i].inputHeight = request->input_height;
3899 }
3900
3901 // hidl session 3.7 and 3.4 specific handling.
3902 if (hidlSession_3_7 != nullptr || hidlSession_3_4 != nullptr) {
3903 hardware::hidl_vec<device::V3_4::PhysicalCameraSetting>& physicalCameraSettings =
3904 (hidlSession_3_7 != nullptr) ?
3905 captureRequests_3_7[i].v3_4.physicalCameraSettings :
3906 captureRequests_3_4[i].physicalCameraSettings;
3907 physicalCameraSettings.resize(request->num_physcam_settings);
3908 for (size_t j = 0; j < request->num_physcam_settings; j++) {
3909 if (request->physcam_settings != nullptr) {
3910 size_t settingsSize = get_camera_metadata_size(request->physcam_settings[j]);
3911 if (mRequestMetadataQueue != nullptr && mRequestMetadataQueue->write(
3912 reinterpret_cast<const uint8_t*>(request->physcam_settings[j]),
3913 settingsSize)) {
3914 physicalCameraSettings[j].settings.resize(0);
3915 physicalCameraSettings[j].fmqSettingsSize = settingsSize;
3916 } else {
3917 if (mRequestMetadataQueue != nullptr) {
3918 ALOGW("%s: couldn't utilize fmq, fallback to hwbinder", __FUNCTION__);
3919 }
3920 physicalCameraSettings[j].settings.setToExternal(
3921 reinterpret_cast<uint8_t*>(const_cast<camera_metadata_t*>(
3922 request->physcam_settings[j])),
3923 get_camera_metadata_size(request->physcam_settings[j]));
3924 physicalCameraSettings[j].fmqSettingsSize = 0u;
3925 }
3926 } else {
3927 physicalCameraSettings[j].fmqSettingsSize = 0u;
3928 physicalCameraSettings[j].settings.resize(0);
3929 }
3930 physicalCameraSettings[j].physicalCameraId = request->physcam_id[j];
3931 }
3932 }
3933 }
3934
3935 hardware::details::return_status err;
3936 auto resultCallback =
3937 [&status, &numRequestProcessed] (auto s, uint32_t n) {
3938 status = s;
3939 *numRequestProcessed = n;
3940 };
3941 if (hidlSession_3_7 != nullptr) {
3942 err = hidlSession_3_7->processCaptureRequest_3_7(captureRequests_3_7, cachesToRemove,
3943 resultCallback);
3944 } else if (hidlSession_3_4 != nullptr) {
3945 err = hidlSession_3_4->processCaptureRequest_3_4(captureRequests_3_4, cachesToRemove,
3946 resultCallback);
3947 } else {
3948 err = mHidlSession->processCaptureRequest(captureRequests, cachesToRemove,
3949 resultCallback);
3950 }
3951 if (!err.isOk()) {
3952 ALOGE("%s: Transaction error: %s", __FUNCTION__, err.description().c_str());
3953 status = common::V1_0::Status::CAMERA_DISCONNECTED;
3954 }
3955
3956 if (status == common::V1_0::Status::OK && *numRequestProcessed != batchSize) {
3957 ALOGE("%s: processCaptureRequest returns OK but processed %d/%zu requests",
3958 __FUNCTION__, *numRequestProcessed, batchSize);
3959 status = common::V1_0::Status::INTERNAL_ERROR;
3960 }
3961
3962 res = CameraProviderManager::mapToStatusT(status);
3963 if (res == OK) {
3964 if (mHidlSession->isRemote()) {
3965 // Only close acquire fence FDs when the HIDL transaction succeeds (so the FDs have been
3966 // sent to camera HAL processes)
3967 cleanupNativeHandles(&handlesCreated, /*closeFd*/true);
3968 } else {
3969 // In passthrough mode the FDs are now owned by HAL
3970 cleanupNativeHandles(&handlesCreated);
3971 }
3972 } else {
3973 mBufferRecords.popInflightBuffers(inflightBuffers);
3974 cleanupNativeHandles(&handlesCreated);
3975 }
3976 return res;
3977 }
3978
flush()3979 status_t Camera3Device::HalInterface::flush() {
3980 ATRACE_NAME("CameraHal::flush");
3981 if (!valid()) return INVALID_OPERATION;
3982 status_t res = OK;
3983
3984 auto err = mHidlSession->flush();
3985 if (!err.isOk()) {
3986 ALOGE("%s: Transaction error: %s", __FUNCTION__, err.description().c_str());
3987 res = DEAD_OBJECT;
3988 } else {
3989 res = CameraProviderManager::mapToStatusT(err);
3990 }
3991
3992 return res;
3993 }
3994
dump(int)3995 status_t Camera3Device::HalInterface::dump(int /*fd*/) {
3996 ATRACE_NAME("CameraHal::dump");
3997 if (!valid()) return INVALID_OPERATION;
3998
3999 // Handled by CameraProviderManager::dump
4000
4001 return OK;
4002 }
4003
close()4004 status_t Camera3Device::HalInterface::close() {
4005 ATRACE_NAME("CameraHal::close()");
4006 if (!valid()) return INVALID_OPERATION;
4007 status_t res = OK;
4008
4009 auto err = mHidlSession->close();
4010 // Interface will be dead shortly anyway, so don't log errors
4011 if (!err.isOk()) {
4012 res = DEAD_OBJECT;
4013 }
4014
4015 return res;
4016 }
4017
signalPipelineDrain(const std::vector<int> & streamIds)4018 void Camera3Device::HalInterface::signalPipelineDrain(const std::vector<int>& streamIds) {
4019 ATRACE_NAME("CameraHal::signalPipelineDrain");
4020 if (!valid() || mHidlSession_3_5 == nullptr) {
4021 ALOGE("%s called on invalid camera!", __FUNCTION__);
4022 return;
4023 }
4024
4025 auto err = mHidlSession_3_5->signalStreamFlush(streamIds, mNextStreamConfigCounter - 1);
4026 if (!err.isOk()) {
4027 ALOGE("%s: Transaction error: %s", __FUNCTION__, err.description().c_str());
4028 return;
4029 }
4030 }
4031
switchToOffline(const std::vector<int32_t> & streamsToKeep,hardware::camera::device::V3_6::CameraOfflineSessionInfo * offlineSessionInfo,sp<hardware::camera::device::V3_6::ICameraOfflineSession> * offlineSession,camera3::BufferRecords * bufferRecords)4032 status_t Camera3Device::HalInterface::switchToOffline(
4033 const std::vector<int32_t>& streamsToKeep,
4034 /*out*/hardware::camera::device::V3_6::CameraOfflineSessionInfo* offlineSessionInfo,
4035 /*out*/sp<hardware::camera::device::V3_6::ICameraOfflineSession>* offlineSession,
4036 /*out*/camera3::BufferRecords* bufferRecords) {
4037 ATRACE_NAME("CameraHal::switchToOffline");
4038 if (!valid() || mHidlSession_3_6 == nullptr) {
4039 ALOGE("%s called on invalid camera!", __FUNCTION__);
4040 return INVALID_OPERATION;
4041 }
4042
4043 if (offlineSessionInfo == nullptr || offlineSession == nullptr || bufferRecords == nullptr) {
4044 ALOGE("%s: output arguments must not be null!", __FUNCTION__);
4045 return INVALID_OPERATION;
4046 }
4047
4048 common::V1_0::Status status = common::V1_0::Status::INTERNAL_ERROR;
4049 auto resultCallback =
4050 [&status, &offlineSessionInfo, &offlineSession] (auto s, auto info, auto session) {
4051 status = s;
4052 *offlineSessionInfo = info;
4053 *offlineSession = session;
4054 };
4055 auto err = mHidlSession_3_6->switchToOffline(streamsToKeep, resultCallback);
4056
4057 if (!err.isOk()) {
4058 ALOGE("%s: Transaction error: %s", __FUNCTION__, err.description().c_str());
4059 return DEAD_OBJECT;
4060 }
4061
4062 status_t ret = CameraProviderManager::mapToStatusT(status);
4063 if (ret != OK) {
4064 return ret;
4065 }
4066
4067 // TODO: assert no ongoing requestBuffer/returnBuffer call here
4068 // TODO: update RequestBufferStateMachine to block requestBuffer/returnBuffer once HAL
4069 // returns from switchToOffline.
4070
4071
4072 // Validate buffer caches
4073 std::vector<int32_t> streams;
4074 streams.reserve(offlineSessionInfo->offlineStreams.size());
4075 for (auto offlineStream : offlineSessionInfo->offlineStreams) {
4076 int32_t id = offlineStream.id;
4077 streams.push_back(id);
4078 // Verify buffer caches
4079 std::vector<uint64_t> bufIds(offlineStream.circulatingBufferIds.begin(),
4080 offlineStream.circulatingBufferIds.end());
4081 if (!verifyBufferIds(id, bufIds)) {
4082 ALOGE("%s: stream ID %d buffer cache records mismatch!", __FUNCTION__, id);
4083 return UNKNOWN_ERROR;
4084 }
4085 }
4086
4087 // Move buffer records
4088 bufferRecords->takeBufferCaches(mBufferRecords, streams);
4089 bufferRecords->takeInflightBufferMap(mBufferRecords);
4090 bufferRecords->takeRequestedBufferMap(mBufferRecords);
4091 return ret;
4092 }
4093
getInflightBufferKeys(std::vector<std::pair<int32_t,int32_t>> * out)4094 void Camera3Device::HalInterface::getInflightBufferKeys(
4095 std::vector<std::pair<int32_t, int32_t>>* out) {
4096 mBufferRecords.getInflightBufferKeys(out);
4097 return;
4098 }
4099
getInflightRequestBufferKeys(std::vector<uint64_t> * out)4100 void Camera3Device::HalInterface::getInflightRequestBufferKeys(
4101 std::vector<uint64_t>* out) {
4102 mBufferRecords.getInflightRequestBufferKeys(out);
4103 return;
4104 }
4105
verifyBufferIds(int32_t streamId,std::vector<uint64_t> & bufIds)4106 bool Camera3Device::HalInterface::verifyBufferIds(
4107 int32_t streamId, std::vector<uint64_t>& bufIds) {
4108 return mBufferRecords.verifyBufferIds(streamId, bufIds);
4109 }
4110
popInflightBuffer(int32_t frameNumber,int32_t streamId,buffer_handle_t ** buffer)4111 status_t Camera3Device::HalInterface::popInflightBuffer(
4112 int32_t frameNumber, int32_t streamId,
4113 /*out*/ buffer_handle_t **buffer) {
4114 return mBufferRecords.popInflightBuffer(frameNumber, streamId, buffer);
4115 }
4116
pushInflightRequestBuffer(uint64_t bufferId,buffer_handle_t * buf,int32_t streamId)4117 status_t Camera3Device::HalInterface::pushInflightRequestBuffer(
4118 uint64_t bufferId, buffer_handle_t* buf, int32_t streamId) {
4119 return mBufferRecords.pushInflightRequestBuffer(bufferId, buf, streamId);
4120 }
4121
4122 // Find and pop a buffer_handle_t based on bufferId
popInflightRequestBuffer(uint64_t bufferId,buffer_handle_t ** buffer,int32_t * streamId)4123 status_t Camera3Device::HalInterface::popInflightRequestBuffer(
4124 uint64_t bufferId,
4125 /*out*/ buffer_handle_t** buffer,
4126 /*optional out*/ int32_t* streamId) {
4127 return mBufferRecords.popInflightRequestBuffer(bufferId, buffer, streamId);
4128 }
4129
getBufferId(const buffer_handle_t & buf,int streamId)4130 std::pair<bool, uint64_t> Camera3Device::HalInterface::getBufferId(
4131 const buffer_handle_t& buf, int streamId) {
4132 return mBufferRecords.getBufferId(buf, streamId);
4133 }
4134
onBufferFreed(int streamId,const native_handle_t * handle)4135 void Camera3Device::HalInterface::onBufferFreed(
4136 int streamId, const native_handle_t* handle) {
4137 uint32_t bufferId = mBufferRecords.removeOneBufferCache(streamId, handle);
4138 std::lock_guard<std::mutex> lock(mFreedBuffersLock);
4139 if (bufferId != BUFFER_ID_NO_BUFFER) {
4140 mFreedBuffers.push_back(std::make_pair(streamId, bufferId));
4141 }
4142 }
4143
onStreamReConfigured(int streamId)4144 void Camera3Device::HalInterface::onStreamReConfigured(int streamId) {
4145 std::vector<uint64_t> bufIds = mBufferRecords.clearBufferCaches(streamId);
4146 std::lock_guard<std::mutex> lock(mFreedBuffersLock);
4147 for (auto bufferId : bufIds) {
4148 mFreedBuffers.push_back(std::make_pair(streamId, bufferId));
4149 }
4150 }
4151
4152 /**
4153 * RequestThread inner class methods
4154 */
4155
RequestThread(wp<Camera3Device> parent,sp<StatusTracker> statusTracker,sp<HalInterface> interface,const Vector<int32_t> & sessionParamKeys,bool useHalBufManager,bool supportCameraMute)4156 Camera3Device::RequestThread::RequestThread(wp<Camera3Device> parent,
4157 sp<StatusTracker> statusTracker,
4158 sp<HalInterface> interface, const Vector<int32_t>& sessionParamKeys,
4159 bool useHalBufManager,
4160 bool supportCameraMute) :
4161 Thread(/*canCallJava*/false),
4162 mParent(parent),
4163 mStatusTracker(statusTracker),
4164 mInterface(interface),
4165 mListener(nullptr),
4166 mId(getId(parent)),
4167 mFirstRepeating(false),
4168 mReconfigured(false),
4169 mDoPause(false),
4170 mPaused(true),
4171 mNotifyPipelineDrain(false),
4172 mFrameNumber(0),
4173 mLatestRequestId(NAME_NOT_FOUND),
4174 mCurrentAfTriggerId(0),
4175 mCurrentPreCaptureTriggerId(0),
4176 mRotateAndCropOverride(ANDROID_SCALER_ROTATE_AND_CROP_NONE),
4177 mCameraMute(ANDROID_SENSOR_TEST_PATTERN_MODE_OFF),
4178 mCameraMuteChanged(false),
4179 mRepeatingLastFrameNumber(
4180 hardware::camera2::ICameraDeviceUser::NO_IN_FLIGHT_REPEATING_FRAMES),
4181 mPrepareVideoStream(false),
4182 mConstrainedMode(false),
4183 mRequestLatency(kRequestLatencyBinSize),
4184 mSessionParamKeys(sessionParamKeys),
4185 mLatestSessionParams(sessionParamKeys.size()),
4186 mUseHalBufManager(useHalBufManager),
4187 mSupportCameraMute(supportCameraMute){
4188 mStatusId = statusTracker->addComponent("RequestThread");
4189 }
4190
~RequestThread()4191 Camera3Device::RequestThread::~RequestThread() {}
4192
setNotificationListener(wp<NotificationListener> listener)4193 void Camera3Device::RequestThread::setNotificationListener(
4194 wp<NotificationListener> listener) {
4195 ATRACE_CALL();
4196 Mutex::Autolock l(mRequestLock);
4197 mListener = listener;
4198 }
4199
configurationComplete(bool isConstrainedHighSpeed,const CameraMetadata & sessionParams,const std::map<int32_t,std::set<String8>> & groupIdPhysicalCameraMap)4200 void Camera3Device::RequestThread::configurationComplete(bool isConstrainedHighSpeed,
4201 const CameraMetadata& sessionParams,
4202 const std::map<int32_t, std::set<String8>>& groupIdPhysicalCameraMap) {
4203 ATRACE_CALL();
4204 Mutex::Autolock l(mRequestLock);
4205 mReconfigured = true;
4206 mLatestSessionParams = sessionParams;
4207 mGroupIdPhysicalCameraMap = groupIdPhysicalCameraMap;
4208 // Prepare video stream for high speed recording.
4209 mPrepareVideoStream = isConstrainedHighSpeed;
4210 mConstrainedMode = isConstrainedHighSpeed;
4211 }
4212
queueRequestList(List<sp<CaptureRequest>> & requests,int64_t * lastFrameNumber)4213 status_t Camera3Device::RequestThread::queueRequestList(
4214 List<sp<CaptureRequest> > &requests,
4215 /*out*/
4216 int64_t *lastFrameNumber) {
4217 ATRACE_CALL();
4218 Mutex::Autolock l(mRequestLock);
4219 for (List<sp<CaptureRequest> >::iterator it = requests.begin(); it != requests.end();
4220 ++it) {
4221 mRequestQueue.push_back(*it);
4222 }
4223
4224 if (lastFrameNumber != NULL) {
4225 *lastFrameNumber = mFrameNumber + mRequestQueue.size() - 1;
4226 ALOGV("%s: requestId %d, mFrameNumber %" PRId32 ", lastFrameNumber %" PRId64 ".",
4227 __FUNCTION__, (*(requests.begin()))->mResultExtras.requestId, mFrameNumber,
4228 *lastFrameNumber);
4229 }
4230
4231 unpauseForNewRequests();
4232
4233 return OK;
4234 }
4235
4236
queueTrigger(RequestTrigger trigger[],size_t count)4237 status_t Camera3Device::RequestThread::queueTrigger(
4238 RequestTrigger trigger[],
4239 size_t count) {
4240 ATRACE_CALL();
4241 Mutex::Autolock l(mTriggerMutex);
4242 status_t ret;
4243
4244 for (size_t i = 0; i < count; ++i) {
4245 ret = queueTriggerLocked(trigger[i]);
4246
4247 if (ret != OK) {
4248 return ret;
4249 }
4250 }
4251
4252 return OK;
4253 }
4254
getId(const wp<Camera3Device> & device)4255 const String8& Camera3Device::RequestThread::getId(const wp<Camera3Device> &device) {
4256 static String8 deadId("<DeadDevice>");
4257 sp<Camera3Device> d = device.promote();
4258 if (d != nullptr) return d->mId;
4259 return deadId;
4260 }
4261
queueTriggerLocked(RequestTrigger trigger)4262 status_t Camera3Device::RequestThread::queueTriggerLocked(
4263 RequestTrigger trigger) {
4264
4265 uint32_t tag = trigger.metadataTag;
4266 ssize_t index = mTriggerMap.indexOfKey(tag);
4267
4268 switch (trigger.getTagType()) {
4269 case TYPE_BYTE:
4270 // fall-through
4271 case TYPE_INT32:
4272 break;
4273 default:
4274 ALOGE("%s: Type not supported: 0x%x", __FUNCTION__,
4275 trigger.getTagType());
4276 return INVALID_OPERATION;
4277 }
4278
4279 /**
4280 * Collect only the latest trigger, since we only have 1 field
4281 * in the request settings per trigger tag, and can't send more than 1
4282 * trigger per request.
4283 */
4284 if (index != NAME_NOT_FOUND) {
4285 mTriggerMap.editValueAt(index) = trigger;
4286 } else {
4287 mTriggerMap.add(tag, trigger);
4288 }
4289
4290 return OK;
4291 }
4292
setRepeatingRequests(const RequestList & requests,int64_t * lastFrameNumber)4293 status_t Camera3Device::RequestThread::setRepeatingRequests(
4294 const RequestList &requests,
4295 /*out*/
4296 int64_t *lastFrameNumber) {
4297 ATRACE_CALL();
4298 Mutex::Autolock l(mRequestLock);
4299 if (lastFrameNumber != NULL) {
4300 *lastFrameNumber = mRepeatingLastFrameNumber;
4301 }
4302 mRepeatingRequests.clear();
4303 mFirstRepeating = true;
4304 mRepeatingRequests.insert(mRepeatingRequests.begin(),
4305 requests.begin(), requests.end());
4306
4307 unpauseForNewRequests();
4308
4309 mRepeatingLastFrameNumber = hardware::camera2::ICameraDeviceUser::NO_IN_FLIGHT_REPEATING_FRAMES;
4310 return OK;
4311 }
4312
isRepeatingRequestLocked(const sp<CaptureRequest> & requestIn)4313 bool Camera3Device::RequestThread::isRepeatingRequestLocked(const sp<CaptureRequest>& requestIn) {
4314 if (mRepeatingRequests.empty()) {
4315 return false;
4316 }
4317 int32_t requestId = requestIn->mResultExtras.requestId;
4318 const RequestList &repeatRequests = mRepeatingRequests;
4319 // All repeating requests are guaranteed to have same id so only check first quest
4320 const sp<CaptureRequest> firstRequest = *repeatRequests.begin();
4321 return (firstRequest->mResultExtras.requestId == requestId);
4322 }
4323
clearRepeatingRequests(int64_t * lastFrameNumber)4324 status_t Camera3Device::RequestThread::clearRepeatingRequests(/*out*/int64_t *lastFrameNumber) {
4325 ATRACE_CALL();
4326 Mutex::Autolock l(mRequestLock);
4327 return clearRepeatingRequestsLocked(lastFrameNumber);
4328
4329 }
4330
clearRepeatingRequestsLocked(int64_t * lastFrameNumber)4331 status_t Camera3Device::RequestThread::clearRepeatingRequestsLocked(/*out*/int64_t *lastFrameNumber) {
4332 mRepeatingRequests.clear();
4333 if (lastFrameNumber != NULL) {
4334 *lastFrameNumber = mRepeatingLastFrameNumber;
4335 }
4336 mRepeatingLastFrameNumber = hardware::camera2::ICameraDeviceUser::NO_IN_FLIGHT_REPEATING_FRAMES;
4337 return OK;
4338 }
4339
clear(int64_t * lastFrameNumber)4340 status_t Camera3Device::RequestThread::clear(
4341 /*out*/int64_t *lastFrameNumber) {
4342 ATRACE_CALL();
4343 Mutex::Autolock l(mRequestLock);
4344 ALOGV("RequestThread::%s:", __FUNCTION__);
4345
4346 mRepeatingRequests.clear();
4347
4348 // Send errors for all requests pending in the request queue, including
4349 // pending repeating requests
4350 sp<NotificationListener> listener = mListener.promote();
4351 if (listener != NULL) {
4352 for (RequestList::iterator it = mRequestQueue.begin();
4353 it != mRequestQueue.end(); ++it) {
4354 // Abort the input buffers for reprocess requests.
4355 if ((*it)->mInputStream != NULL) {
4356 camera_stream_buffer_t inputBuffer;
4357 camera3::Size inputBufferSize;
4358 status_t res = (*it)->mInputStream->getInputBuffer(&inputBuffer,
4359 &inputBufferSize, /*respectHalLimit*/ false);
4360 if (res != OK) {
4361 ALOGW("%s: %d: couldn't get input buffer while clearing the request "
4362 "list: %s (%d)", __FUNCTION__, __LINE__, strerror(-res), res);
4363 } else {
4364 inputBuffer.status = CAMERA_BUFFER_STATUS_ERROR;
4365 res = (*it)->mInputStream->returnInputBuffer(inputBuffer);
4366 if (res != OK) {
4367 ALOGE("%s: %d: couldn't return input buffer while clearing the request "
4368 "list: %s (%d)", __FUNCTION__, __LINE__, strerror(-res), res);
4369 }
4370 }
4371 }
4372 // Set the frame number this request would have had, if it
4373 // had been submitted; this frame number will not be reused.
4374 // The requestId and burstId fields were set when the request was
4375 // submitted originally (in convertMetadataListToRequestListLocked)
4376 (*it)->mResultExtras.frameNumber = mFrameNumber++;
4377 listener->notifyError(hardware::camera2::ICameraDeviceCallbacks::ERROR_CAMERA_REQUEST,
4378 (*it)->mResultExtras);
4379 }
4380 }
4381 mRequestQueue.clear();
4382
4383 Mutex::Autolock al(mTriggerMutex);
4384 mTriggerMap.clear();
4385 if (lastFrameNumber != NULL) {
4386 *lastFrameNumber = mRepeatingLastFrameNumber;
4387 }
4388 mRepeatingLastFrameNumber = hardware::camera2::ICameraDeviceUser::NO_IN_FLIGHT_REPEATING_FRAMES;
4389 mRequestSignal.signal();
4390 return OK;
4391 }
4392
flush()4393 status_t Camera3Device::RequestThread::flush() {
4394 ATRACE_CALL();
4395 Mutex::Autolock l(mFlushLock);
4396
4397 return mInterface->flush();
4398 }
4399
setPaused(bool paused)4400 void Camera3Device::RequestThread::setPaused(bool paused) {
4401 ATRACE_CALL();
4402 Mutex::Autolock l(mPauseLock);
4403 mDoPause = paused;
4404 mDoPauseSignal.signal();
4405 }
4406
waitUntilRequestProcessed(int32_t requestId,nsecs_t timeout)4407 status_t Camera3Device::RequestThread::waitUntilRequestProcessed(
4408 int32_t requestId, nsecs_t timeout) {
4409 ATRACE_CALL();
4410 Mutex::Autolock l(mLatestRequestMutex);
4411 status_t res;
4412 while (mLatestRequestId != requestId) {
4413 nsecs_t startTime = systemTime();
4414
4415 res = mLatestRequestSignal.waitRelative(mLatestRequestMutex, timeout);
4416 if (res != OK) return res;
4417
4418 timeout -= (systemTime() - startTime);
4419 }
4420
4421 return OK;
4422 }
4423
requestExit()4424 void Camera3Device::RequestThread::requestExit() {
4425 // Call parent to set up shutdown
4426 Thread::requestExit();
4427 // The exit from any possible waits
4428 mDoPauseSignal.signal();
4429 mRequestSignal.signal();
4430
4431 mRequestLatency.log("ProcessCaptureRequest latency histogram");
4432 mRequestLatency.reset();
4433 }
4434
checkAndStopRepeatingRequest()4435 void Camera3Device::RequestThread::checkAndStopRepeatingRequest() {
4436 ATRACE_CALL();
4437 bool surfaceAbandoned = false;
4438 int64_t lastFrameNumber = 0;
4439 sp<NotificationListener> listener;
4440 {
4441 Mutex::Autolock l(mRequestLock);
4442 // Check all streams needed by repeating requests are still valid. Otherwise, stop
4443 // repeating requests.
4444 for (const auto& request : mRepeatingRequests) {
4445 for (const auto& s : request->mOutputStreams) {
4446 if (s->isAbandoned()) {
4447 surfaceAbandoned = true;
4448 clearRepeatingRequestsLocked(&lastFrameNumber);
4449 break;
4450 }
4451 }
4452 if (surfaceAbandoned) {
4453 break;
4454 }
4455 }
4456 listener = mListener.promote();
4457 }
4458
4459 if (listener != NULL && surfaceAbandoned) {
4460 listener->notifyRepeatingRequestError(lastFrameNumber);
4461 }
4462 }
4463
sendRequestsBatch()4464 bool Camera3Device::RequestThread::sendRequestsBatch() {
4465 ATRACE_CALL();
4466 status_t res;
4467 size_t batchSize = mNextRequests.size();
4468 std::vector<camera_capture_request_t*> requests(batchSize);
4469 uint32_t numRequestProcessed = 0;
4470 for (size_t i = 0; i < batchSize; i++) {
4471 requests[i] = &mNextRequests.editItemAt(i).halRequest;
4472 ATRACE_ASYNC_BEGIN("frame capture", mNextRequests[i].halRequest.frame_number);
4473 }
4474
4475 res = mInterface->processBatchCaptureRequests(requests, &numRequestProcessed);
4476
4477 bool triggerRemoveFailed = false;
4478 NextRequest& triggerFailedRequest = mNextRequests.editItemAt(0);
4479 for (size_t i = 0; i < numRequestProcessed; i++) {
4480 NextRequest& nextRequest = mNextRequests.editItemAt(i);
4481 nextRequest.submitted = true;
4482
4483 updateNextRequest(nextRequest);
4484
4485 if (!triggerRemoveFailed) {
4486 // Remove any previously queued triggers (after unlock)
4487 status_t removeTriggerRes = removeTriggers(mPrevRequest);
4488 if (removeTriggerRes != OK) {
4489 triggerRemoveFailed = true;
4490 triggerFailedRequest = nextRequest;
4491 }
4492 }
4493 }
4494
4495 if (triggerRemoveFailed) {
4496 SET_ERR("RequestThread: Unable to remove triggers "
4497 "(capture request %d, HAL device: %s (%d)",
4498 triggerFailedRequest.halRequest.frame_number, strerror(-res), res);
4499 cleanUpFailedRequests(/*sendRequestError*/ false);
4500 return false;
4501 }
4502
4503 if (res != OK) {
4504 // Should only get a failure here for malformed requests or device-level
4505 // errors, so consider all errors fatal. Bad metadata failures should
4506 // come through notify.
4507 SET_ERR("RequestThread: Unable to submit capture request %d to HAL device: %s (%d)",
4508 mNextRequests[numRequestProcessed].halRequest.frame_number,
4509 strerror(-res), res);
4510 cleanUpFailedRequests(/*sendRequestError*/ false);
4511 return false;
4512 }
4513 return true;
4514 }
4515
calculateMaxExpectedDuration(const camera_metadata_t * request)4516 nsecs_t Camera3Device::RequestThread::calculateMaxExpectedDuration(const camera_metadata_t *request) {
4517 nsecs_t maxExpectedDuration = kDefaultExpectedDuration;
4518 camera_metadata_ro_entry_t e = camera_metadata_ro_entry_t();
4519 find_camera_metadata_ro_entry(request,
4520 ANDROID_CONTROL_AE_MODE,
4521 &e);
4522 if (e.count == 0) return maxExpectedDuration;
4523
4524 switch (e.data.u8[0]) {
4525 case ANDROID_CONTROL_AE_MODE_OFF:
4526 find_camera_metadata_ro_entry(request,
4527 ANDROID_SENSOR_EXPOSURE_TIME,
4528 &e);
4529 if (e.count > 0) {
4530 maxExpectedDuration = e.data.i64[0];
4531 }
4532 find_camera_metadata_ro_entry(request,
4533 ANDROID_SENSOR_FRAME_DURATION,
4534 &e);
4535 if (e.count > 0) {
4536 maxExpectedDuration = std::max(e.data.i64[0], maxExpectedDuration);
4537 }
4538 break;
4539 default:
4540 find_camera_metadata_ro_entry(request,
4541 ANDROID_CONTROL_AE_TARGET_FPS_RANGE,
4542 &e);
4543 if (e.count > 1) {
4544 maxExpectedDuration = 1e9 / e.data.u8[0];
4545 }
4546 break;
4547 }
4548
4549 return maxExpectedDuration;
4550 }
4551
skipHFRTargetFPSUpdate(int32_t tag,const camera_metadata_ro_entry_t & newEntry,const camera_metadata_entry_t & currentEntry)4552 bool Camera3Device::RequestThread::skipHFRTargetFPSUpdate(int32_t tag,
4553 const camera_metadata_ro_entry_t& newEntry, const camera_metadata_entry_t& currentEntry) {
4554 if (mConstrainedMode && (ANDROID_CONTROL_AE_TARGET_FPS_RANGE == tag) &&
4555 (newEntry.count == currentEntry.count) && (currentEntry.count == 2) &&
4556 (currentEntry.data.i32[1] == newEntry.data.i32[1])) {
4557 return true;
4558 }
4559
4560 return false;
4561 }
4562
updateNextRequest(NextRequest & nextRequest)4563 void Camera3Device::RequestThread::updateNextRequest(NextRequest& nextRequest) {
4564 // Update the latest request sent to HAL
4565 camera_capture_request_t& halRequest = nextRequest.halRequest;
4566 if (halRequest.settings != NULL) { // Don't update if they were unchanged
4567 Mutex::Autolock al(mLatestRequestMutex);
4568
4569 camera_metadata_t* cloned = clone_camera_metadata(halRequest.settings);
4570 mLatestRequest.acquire(cloned);
4571
4572 mLatestPhysicalRequest.clear();
4573 for (uint32_t i = 0; i < halRequest.num_physcam_settings; i++) {
4574 cloned = clone_camera_metadata(halRequest.physcam_settings[i]);
4575 mLatestPhysicalRequest.emplace(halRequest.physcam_id[i],
4576 CameraMetadata(cloned));
4577 }
4578
4579 sp<Camera3Device> parent = mParent.promote();
4580 if (parent != NULL) {
4581 parent->monitorMetadata(TagMonitor::REQUEST,
4582 halRequest.frame_number,
4583 0, mLatestRequest, mLatestPhysicalRequest);
4584 }
4585 }
4586
4587 if (halRequest.settings != NULL) {
4588 nextRequest.captureRequest->mSettingsList.begin()->metadata.unlock(
4589 halRequest.settings);
4590 }
4591
4592 cleanupPhysicalSettings(nextRequest.captureRequest, &halRequest);
4593 }
4594
updateSessionParameters(const CameraMetadata & settings)4595 bool Camera3Device::RequestThread::updateSessionParameters(const CameraMetadata& settings) {
4596 ATRACE_CALL();
4597 bool updatesDetected = false;
4598
4599 CameraMetadata updatedParams(mLatestSessionParams);
4600 for (auto tag : mSessionParamKeys) {
4601 camera_metadata_ro_entry entry = settings.find(tag);
4602 camera_metadata_entry lastEntry = updatedParams.find(tag);
4603
4604 if (entry.count > 0) {
4605 bool isDifferent = false;
4606 if (lastEntry.count > 0) {
4607 // Have a last value, compare to see if changed
4608 if (lastEntry.type == entry.type &&
4609 lastEntry.count == entry.count) {
4610 // Same type and count, compare values
4611 size_t bytesPerValue = camera_metadata_type_size[lastEntry.type];
4612 size_t entryBytes = bytesPerValue * lastEntry.count;
4613 int cmp = memcmp(entry.data.u8, lastEntry.data.u8, entryBytes);
4614 if (cmp != 0) {
4615 isDifferent = true;
4616 }
4617 } else {
4618 // Count or type has changed
4619 isDifferent = true;
4620 }
4621 } else {
4622 // No last entry, so always consider to be different
4623 isDifferent = true;
4624 }
4625
4626 if (isDifferent) {
4627 ALOGV("%s: Session parameter tag id %d changed", __FUNCTION__, tag);
4628 if (!skipHFRTargetFPSUpdate(tag, entry, lastEntry)) {
4629 updatesDetected = true;
4630 }
4631 updatedParams.update(entry);
4632 }
4633 } else if (lastEntry.count > 0) {
4634 // Value has been removed
4635 ALOGV("%s: Session parameter tag id %d removed", __FUNCTION__, tag);
4636 updatedParams.erase(tag);
4637 updatesDetected = true;
4638 }
4639 }
4640
4641 bool reconfigureRequired;
4642 if (updatesDetected) {
4643 reconfigureRequired = mInterface->isReconfigurationRequired(mLatestSessionParams,
4644 updatedParams);
4645 mLatestSessionParams = updatedParams;
4646 } else {
4647 reconfigureRequired = false;
4648 }
4649
4650 return reconfigureRequired;
4651 }
4652
threadLoop()4653 bool Camera3Device::RequestThread::threadLoop() {
4654 ATRACE_CALL();
4655 status_t res;
4656 // Any function called from threadLoop() must not hold mInterfaceLock since
4657 // it could lead to deadlocks (disconnect() -> hold mInterfaceMutex -> wait for request thread
4658 // to finish -> request thread waits on mInterfaceMutex) http://b/143513518
4659
4660 // Handle paused state.
4661 if (waitIfPaused()) {
4662 return true;
4663 }
4664
4665 // Wait for the next batch of requests.
4666 waitForNextRequestBatch();
4667 if (mNextRequests.size() == 0) {
4668 return true;
4669 }
4670
4671 // Get the latest request ID, if any
4672 int latestRequestId;
4673 camera_metadata_entry_t requestIdEntry = mNextRequests[mNextRequests.size() - 1].
4674 captureRequest->mSettingsList.begin()->metadata.find(ANDROID_REQUEST_ID);
4675 if (requestIdEntry.count > 0) {
4676 latestRequestId = requestIdEntry.data.i32[0];
4677 } else {
4678 ALOGW("%s: Did not have android.request.id set in the request.", __FUNCTION__);
4679 latestRequestId = NAME_NOT_FOUND;
4680 }
4681
4682 // 'mNextRequests' will at this point contain either a set of HFR batched requests
4683 // or a single request from streaming or burst. In either case the first element
4684 // should contain the latest camera settings that we need to check for any session
4685 // parameter updates.
4686 if (updateSessionParameters(mNextRequests[0].captureRequest->mSettingsList.begin()->metadata)) {
4687 res = OK;
4688
4689 //Input stream buffers are already acquired at this point so an input stream
4690 //will not be able to move to idle state unless we force it.
4691 if (mNextRequests[0].captureRequest->mInputStream != nullptr) {
4692 res = mNextRequests[0].captureRequest->mInputStream->forceToIdle();
4693 if (res != OK) {
4694 ALOGE("%s: Failed to force idle input stream: %d", __FUNCTION__, res);
4695 cleanUpFailedRequests(/*sendRequestError*/ false);
4696 return false;
4697 }
4698 }
4699
4700 if (res == OK) {
4701 sp<Camera3Device> parent = mParent.promote();
4702 if (parent != nullptr) {
4703 mReconfigured |= parent->reconfigureCamera(mLatestSessionParams, mStatusId);
4704 }
4705 setPaused(false);
4706
4707 if (mNextRequests[0].captureRequest->mInputStream != nullptr) {
4708 mNextRequests[0].captureRequest->mInputStream->restoreConfiguredState();
4709 if (res != OK) {
4710 ALOGE("%s: Failed to restore configured input stream: %d", __FUNCTION__, res);
4711 cleanUpFailedRequests(/*sendRequestError*/ false);
4712 return false;
4713 }
4714 }
4715 }
4716 }
4717
4718 // Prepare a batch of HAL requests and output buffers.
4719 res = prepareHalRequests();
4720 if (res == TIMED_OUT) {
4721 // Not a fatal error if getting output buffers time out.
4722 cleanUpFailedRequests(/*sendRequestError*/ true);
4723 // Check if any stream is abandoned.
4724 checkAndStopRepeatingRequest();
4725 return true;
4726 } else if (res != OK) {
4727 cleanUpFailedRequests(/*sendRequestError*/ false);
4728 return false;
4729 }
4730
4731 // Inform waitUntilRequestProcessed thread of a new request ID
4732 {
4733 Mutex::Autolock al(mLatestRequestMutex);
4734
4735 mLatestRequestId = latestRequestId;
4736 mLatestRequestSignal.signal();
4737 }
4738
4739 // Submit a batch of requests to HAL.
4740 // Use flush lock only when submitting multilple requests in a batch.
4741 // TODO: The problem with flush lock is flush() will be blocked by process_capture_request()
4742 // which may take a long time to finish so synchronizing flush() and
4743 // process_capture_request() defeats the purpose of cancelling requests ASAP with flush().
4744 // For now, only synchronize for high speed recording and we should figure something out for
4745 // removing the synchronization.
4746 bool useFlushLock = mNextRequests.size() > 1;
4747
4748 if (useFlushLock) {
4749 mFlushLock.lock();
4750 }
4751
4752 ALOGVV("%s: %d: submitting %zu requests in a batch.", __FUNCTION__, __LINE__,
4753 mNextRequests.size());
4754
4755 sp<Camera3Device> parent = mParent.promote();
4756 if (parent != nullptr) {
4757 parent->mRequestBufferSM.onSubmittingRequest();
4758 }
4759
4760 bool submitRequestSuccess = false;
4761 nsecs_t tRequestStart = systemTime(SYSTEM_TIME_MONOTONIC);
4762 submitRequestSuccess = sendRequestsBatch();
4763
4764 nsecs_t tRequestEnd = systemTime(SYSTEM_TIME_MONOTONIC);
4765 mRequestLatency.add(tRequestStart, tRequestEnd);
4766
4767 if (useFlushLock) {
4768 mFlushLock.unlock();
4769 }
4770
4771 // Unset as current request
4772 {
4773 Mutex::Autolock l(mRequestLock);
4774 mNextRequests.clear();
4775 }
4776 mRequestSubmittedSignal.signal();
4777
4778 return submitRequestSuccess;
4779 }
4780
prepareHalRequests()4781 status_t Camera3Device::RequestThread::prepareHalRequests() {
4782 ATRACE_CALL();
4783
4784 bool batchedRequest = mNextRequests[0].captureRequest->mBatchSize > 1;
4785 for (size_t i = 0; i < mNextRequests.size(); i++) {
4786 auto& nextRequest = mNextRequests.editItemAt(i);
4787 sp<CaptureRequest> captureRequest = nextRequest.captureRequest;
4788 camera_capture_request_t* halRequest = &nextRequest.halRequest;
4789 Vector<camera_stream_buffer_t>* outputBuffers = &nextRequest.outputBuffers;
4790
4791 // Prepare a request to HAL
4792 halRequest->frame_number = captureRequest->mResultExtras.frameNumber;
4793
4794 // Insert any queued triggers (before metadata is locked)
4795 status_t res = insertTriggers(captureRequest);
4796 if (res < 0) {
4797 SET_ERR("RequestThread: Unable to insert triggers "
4798 "(capture request %d, HAL device: %s (%d)",
4799 halRequest->frame_number, strerror(-res), res);
4800 return INVALID_OPERATION;
4801 }
4802
4803 int triggerCount = res;
4804 bool triggersMixedIn = (triggerCount > 0 || mPrevTriggers > 0);
4805 mPrevTriggers = triggerCount;
4806
4807 bool rotateAndCropChanged = overrideAutoRotateAndCrop(captureRequest);
4808 bool testPatternChanged = overrideTestPattern(captureRequest);
4809
4810 // If the request is the same as last, or we had triggers now or last time or
4811 // changing overrides this time
4812 bool newRequest =
4813 (mPrevRequest != captureRequest || triggersMixedIn ||
4814 rotateAndCropChanged || testPatternChanged) &&
4815 // Request settings are all the same within one batch, so only treat the first
4816 // request in a batch as new
4817 !(batchedRequest && i > 0);
4818 if (newRequest) {
4819 std::set<std::string> cameraIdsWithZoom;
4820 /**
4821 * HAL workaround:
4822 * Insert a fake trigger ID if a trigger is set but no trigger ID is
4823 */
4824 res = addFakeTriggerIds(captureRequest);
4825 if (res != OK) {
4826 SET_ERR("RequestThread: Unable to insert fake trigger IDs "
4827 "(capture request %d, HAL device: %s (%d)",
4828 halRequest->frame_number, strerror(-res), res);
4829 return INVALID_OPERATION;
4830 }
4831
4832 {
4833 sp<Camera3Device> parent = mParent.promote();
4834 if (parent != nullptr) {
4835 List<PhysicalCameraSettings>::iterator it;
4836 for (it = captureRequest->mSettingsList.begin();
4837 it != captureRequest->mSettingsList.end(); it++) {
4838 if (parent->mUHRCropAndMeteringRegionMappers.find(it->cameraId) ==
4839 parent->mUHRCropAndMeteringRegionMappers.end()) {
4840 continue;
4841 }
4842
4843 if (!captureRequest->mUHRCropAndMeteringRegionsUpdated) {
4844 res = parent->mUHRCropAndMeteringRegionMappers[it->cameraId].
4845 updateCaptureRequest(&(it->metadata));
4846 if (res != OK) {
4847 SET_ERR("RequestThread: Unable to correct capture requests "
4848 "for scaler crop region and metering regions for request "
4849 "%d: %s (%d)", halRequest->frame_number, strerror(-res),
4850 res);
4851 return INVALID_OPERATION;
4852 }
4853 captureRequest->mUHRCropAndMeteringRegionsUpdated = true;
4854 }
4855 }
4856
4857 // Correct metadata regions for distortion correction if enabled
4858 for (it = captureRequest->mSettingsList.begin();
4859 it != captureRequest->mSettingsList.end(); it++) {
4860 if (parent->mDistortionMappers.find(it->cameraId) ==
4861 parent->mDistortionMappers.end()) {
4862 continue;
4863 }
4864
4865 if (!captureRequest->mDistortionCorrectionUpdated) {
4866 res = parent->mDistortionMappers[it->cameraId].correctCaptureRequest(
4867 &(it->metadata));
4868 if (res != OK) {
4869 SET_ERR("RequestThread: Unable to correct capture requests "
4870 "for lens distortion for request %d: %s (%d)",
4871 halRequest->frame_number, strerror(-res), res);
4872 return INVALID_OPERATION;
4873 }
4874 captureRequest->mDistortionCorrectionUpdated = true;
4875 }
4876 }
4877
4878 for (it = captureRequest->mSettingsList.begin();
4879 it != captureRequest->mSettingsList.end(); it++) {
4880 if (parent->mZoomRatioMappers.find(it->cameraId) ==
4881 parent->mZoomRatioMappers.end()) {
4882 continue;
4883 }
4884
4885 if (!captureRequest->mZoomRatioIs1x) {
4886 cameraIdsWithZoom.insert(it->cameraId);
4887 }
4888
4889 if (!captureRequest->mZoomRatioUpdated) {
4890 res = parent->mZoomRatioMappers[it->cameraId].updateCaptureRequest(
4891 &(it->metadata));
4892 if (res != OK) {
4893 SET_ERR("RequestThread: Unable to correct capture requests "
4894 "for zoom ratio for request %d: %s (%d)",
4895 halRequest->frame_number, strerror(-res), res);
4896 return INVALID_OPERATION;
4897 }
4898 captureRequest->mZoomRatioUpdated = true;
4899 }
4900 }
4901 if (captureRequest->mRotateAndCropAuto &&
4902 !captureRequest->mRotationAndCropUpdated) {
4903 for (it = captureRequest->mSettingsList.begin();
4904 it != captureRequest->mSettingsList.end(); it++) {
4905 auto mapper = parent->mRotateAndCropMappers.find(it->cameraId);
4906 if (mapper != parent->mRotateAndCropMappers.end()) {
4907 res = mapper->second.updateCaptureRequest(&(it->metadata));
4908 if (res != OK) {
4909 SET_ERR("RequestThread: Unable to correct capture requests "
4910 "for rotate-and-crop for request %d: %s (%d)",
4911 halRequest->frame_number, strerror(-res), res);
4912 return INVALID_OPERATION;
4913 }
4914 }
4915 }
4916 captureRequest->mRotationAndCropUpdated = true;
4917 }
4918 }
4919 }
4920
4921 /**
4922 * The request should be presorted so accesses in HAL
4923 * are O(logn). Sidenote, sorting a sorted metadata is nop.
4924 */
4925 captureRequest->mSettingsList.begin()->metadata.sort();
4926 halRequest->settings = captureRequest->mSettingsList.begin()->metadata.getAndLock();
4927 mPrevRequest = captureRequest;
4928 mPrevCameraIdsWithZoom = cameraIdsWithZoom;
4929 ALOGVV("%s: Request settings are NEW", __FUNCTION__);
4930
4931 IF_ALOGV() {
4932 camera_metadata_ro_entry_t e = camera_metadata_ro_entry_t();
4933 find_camera_metadata_ro_entry(
4934 halRequest->settings,
4935 ANDROID_CONTROL_AF_TRIGGER,
4936 &e
4937 );
4938 if (e.count > 0) {
4939 ALOGV("%s: Request (frame num %d) had AF trigger 0x%x",
4940 __FUNCTION__,
4941 halRequest->frame_number,
4942 e.data.u8[0]);
4943 }
4944 }
4945 } else {
4946 // leave request.settings NULL to indicate 'reuse latest given'
4947 ALOGVV("%s: Request settings are REUSED",
4948 __FUNCTION__);
4949 }
4950
4951 if (captureRequest->mSettingsList.size() > 1) {
4952 halRequest->num_physcam_settings = captureRequest->mSettingsList.size() - 1;
4953 halRequest->physcam_id = new const char* [halRequest->num_physcam_settings];
4954 if (newRequest) {
4955 halRequest->physcam_settings =
4956 new const camera_metadata* [halRequest->num_physcam_settings];
4957 } else {
4958 halRequest->physcam_settings = nullptr;
4959 }
4960 auto it = ++captureRequest->mSettingsList.begin();
4961 size_t i = 0;
4962 for (; it != captureRequest->mSettingsList.end(); it++, i++) {
4963 halRequest->physcam_id[i] = it->cameraId.c_str();
4964 if (newRequest) {
4965 it->metadata.sort();
4966 halRequest->physcam_settings[i] = it->metadata.getAndLock();
4967 }
4968 }
4969 }
4970
4971 uint32_t totalNumBuffers = 0;
4972
4973 // Fill in buffers
4974 if (captureRequest->mInputStream != NULL) {
4975 halRequest->input_buffer = &captureRequest->mInputBuffer;
4976
4977 halRequest->input_width = captureRequest->mInputBufferSize.width;
4978 halRequest->input_height = captureRequest->mInputBufferSize.height;
4979 totalNumBuffers += 1;
4980 } else {
4981 halRequest->input_buffer = NULL;
4982 }
4983
4984 outputBuffers->insertAt(camera_stream_buffer_t(), 0,
4985 captureRequest->mOutputStreams.size());
4986 halRequest->output_buffers = outputBuffers->array();
4987 std::set<std::set<String8>> requestedPhysicalCameras;
4988
4989 sp<Camera3Device> parent = mParent.promote();
4990 if (parent == NULL) {
4991 // Should not happen, and nowhere to send errors to, so just log it
4992 CLOGE("RequestThread: Parent is gone");
4993 return INVALID_OPERATION;
4994 }
4995 nsecs_t waitDuration = kBaseGetBufferWait + parent->getExpectedInFlightDuration();
4996
4997 SurfaceMap uniqueSurfaceIdMap;
4998 for (size_t j = 0; j < captureRequest->mOutputStreams.size(); j++) {
4999 sp<Camera3OutputStreamInterface> outputStream =
5000 captureRequest->mOutputStreams.editItemAt(j);
5001 int streamId = outputStream->getId();
5002
5003 // Prepare video buffers for high speed recording on the first video request.
5004 if (mPrepareVideoStream && outputStream->isVideoStream()) {
5005 // Only try to prepare video stream on the first video request.
5006 mPrepareVideoStream = false;
5007
5008 res = outputStream->startPrepare(Camera3StreamInterface::ALLOCATE_PIPELINE_MAX,
5009 false /*blockRequest*/);
5010 while (res == NOT_ENOUGH_DATA) {
5011 res = outputStream->prepareNextBuffer();
5012 }
5013 if (res != OK) {
5014 ALOGW("%s: Preparing video buffers for high speed failed: %s (%d)",
5015 __FUNCTION__, strerror(-res), res);
5016 outputStream->cancelPrepare();
5017 }
5018 }
5019
5020 std::vector<size_t> uniqueSurfaceIds;
5021 res = outputStream->getUniqueSurfaceIds(
5022 captureRequest->mOutputSurfaces[streamId],
5023 &uniqueSurfaceIds);
5024 // INVALID_OPERATION is normal output for streams not supporting surfaceIds
5025 if (res != OK && res != INVALID_OPERATION) {
5026 ALOGE("%s: failed to query stream %d unique surface IDs",
5027 __FUNCTION__, streamId);
5028 return res;
5029 }
5030 if (res == OK) {
5031 uniqueSurfaceIdMap.insert({streamId, std::move(uniqueSurfaceIds)});
5032 }
5033
5034 if (mUseHalBufManager) {
5035 if (outputStream->isAbandoned()) {
5036 ALOGV("%s: stream %d is abandoned, skipping request", __FUNCTION__, streamId);
5037 return TIMED_OUT;
5038 }
5039 // HAL will request buffer through requestStreamBuffer API
5040 camera_stream_buffer_t& buffer = outputBuffers->editItemAt(j);
5041 buffer.stream = outputStream->asHalStream();
5042 buffer.buffer = nullptr;
5043 buffer.status = CAMERA_BUFFER_STATUS_OK;
5044 buffer.acquire_fence = -1;
5045 buffer.release_fence = -1;
5046 // Mark the output stream as unpreparable to block clients from calling
5047 // 'prepare' after this request reaches CameraHal and before the respective
5048 // buffers are requested.
5049 outputStream->markUnpreparable();
5050 } else {
5051 res = outputStream->getBuffer(&outputBuffers->editItemAt(j),
5052 waitDuration,
5053 captureRequest->mOutputSurfaces[streamId]);
5054 if (res != OK) {
5055 // Can't get output buffer from gralloc queue - this could be due to
5056 // abandoned queue or other consumer misbehavior, so not a fatal
5057 // error
5058 ALOGV("RequestThread: Can't get output buffer, skipping request:"
5059 " %s (%d)", strerror(-res), res);
5060
5061 return TIMED_OUT;
5062 }
5063 }
5064
5065 {
5066 sp<Camera3Device> parent = mParent.promote();
5067 if (parent != nullptr) {
5068 const String8& streamCameraId = outputStream->getPhysicalCameraId();
5069 for (const auto& settings : captureRequest->mSettingsList) {
5070 if ((streamCameraId.isEmpty() &&
5071 parent->getId() == settings.cameraId.c_str()) ||
5072 streamCameraId == settings.cameraId.c_str()) {
5073 outputStream->fireBufferRequestForFrameNumber(
5074 captureRequest->mResultExtras.frameNumber,
5075 settings.metadata);
5076 }
5077 }
5078 }
5079 }
5080
5081 String8 physicalCameraId = outputStream->getPhysicalCameraId();
5082 int32_t streamGroupId = outputStream->getHalStreamGroupId();
5083 if (streamGroupId != -1 && mGroupIdPhysicalCameraMap.count(streamGroupId) == 1) {
5084 requestedPhysicalCameras.insert(mGroupIdPhysicalCameraMap[streamGroupId]);
5085 } else if (!physicalCameraId.isEmpty()) {
5086 requestedPhysicalCameras.insert(std::set<String8>({physicalCameraId}));
5087 }
5088 halRequest->num_output_buffers++;
5089 }
5090 totalNumBuffers += halRequest->num_output_buffers;
5091
5092 // Log request in the in-flight queue
5093 // If this request list is for constrained high speed recording (not
5094 // preview), and the current request is not the last one in the batch,
5095 // do not send callback to the app.
5096 bool hasCallback = true;
5097 if (batchedRequest && i != mNextRequests.size()-1) {
5098 hasCallback = false;
5099 }
5100 bool isStillCapture = false;
5101 bool isZslCapture = false;
5102 const camera_metadata_t* settings = halRequest->settings;
5103 bool shouldUnlockSettings = false;
5104 if (settings == nullptr) {
5105 shouldUnlockSettings = true;
5106 settings = captureRequest->mSettingsList.begin()->metadata.getAndLock();
5107 }
5108 if (!mNextRequests[0].captureRequest->mSettingsList.begin()->metadata.isEmpty()) {
5109 camera_metadata_ro_entry_t e = camera_metadata_ro_entry_t();
5110 find_camera_metadata_ro_entry(settings, ANDROID_CONTROL_CAPTURE_INTENT, &e);
5111 if ((e.count > 0) && (e.data.u8[0] == ANDROID_CONTROL_CAPTURE_INTENT_STILL_CAPTURE)) {
5112 isStillCapture = true;
5113 ATRACE_ASYNC_BEGIN("still capture", mNextRequests[i].halRequest.frame_number);
5114 }
5115
5116 e = camera_metadata_ro_entry_t();
5117 find_camera_metadata_ro_entry(settings, ANDROID_CONTROL_ENABLE_ZSL, &e);
5118 if ((e.count > 0) && (e.data.u8[0] == ANDROID_CONTROL_ENABLE_ZSL_TRUE)) {
5119 isZslCapture = true;
5120 }
5121 }
5122 res = parent->registerInFlight(halRequest->frame_number,
5123 totalNumBuffers, captureRequest->mResultExtras,
5124 /*hasInput*/halRequest->input_buffer != NULL,
5125 hasCallback,
5126 calculateMaxExpectedDuration(settings),
5127 requestedPhysicalCameras, isStillCapture, isZslCapture,
5128 captureRequest->mRotateAndCropAuto, mPrevCameraIdsWithZoom,
5129 (mUseHalBufManager) ? uniqueSurfaceIdMap :
5130 SurfaceMap{}, captureRequest->mRequestTimeNs);
5131 ALOGVV("%s: registered in flight requestId = %" PRId32 ", frameNumber = %" PRId64
5132 ", burstId = %" PRId32 ".",
5133 __FUNCTION__,
5134 captureRequest->mResultExtras.requestId, captureRequest->mResultExtras.frameNumber,
5135 captureRequest->mResultExtras.burstId);
5136
5137 if (shouldUnlockSettings) {
5138 captureRequest->mSettingsList.begin()->metadata.unlock(settings);
5139 }
5140
5141 if (res != OK) {
5142 SET_ERR("RequestThread: Unable to register new in-flight request:"
5143 " %s (%d)", strerror(-res), res);
5144 return INVALID_OPERATION;
5145 }
5146 }
5147
5148 return OK;
5149 }
5150
getLatestRequest() const5151 CameraMetadata Camera3Device::RequestThread::getLatestRequest() const {
5152 ATRACE_CALL();
5153 Mutex::Autolock al(mLatestRequestMutex);
5154
5155 ALOGV("RequestThread::%s", __FUNCTION__);
5156
5157 return mLatestRequest;
5158 }
5159
isStreamPending(sp<Camera3StreamInterface> & stream)5160 bool Camera3Device::RequestThread::isStreamPending(
5161 sp<Camera3StreamInterface>& stream) {
5162 ATRACE_CALL();
5163 Mutex::Autolock l(mRequestLock);
5164
5165 for (const auto& nextRequest : mNextRequests) {
5166 if (!nextRequest.submitted) {
5167 for (const auto& s : nextRequest.captureRequest->mOutputStreams) {
5168 if (stream == s) return true;
5169 }
5170 if (stream == nextRequest.captureRequest->mInputStream) return true;
5171 }
5172 }
5173
5174 for (const auto& request : mRequestQueue) {
5175 for (const auto& s : request->mOutputStreams) {
5176 if (stream == s) return true;
5177 }
5178 if (stream == request->mInputStream) return true;
5179 }
5180
5181 for (const auto& request : mRepeatingRequests) {
5182 for (const auto& s : request->mOutputStreams) {
5183 if (stream == s) return true;
5184 }
5185 if (stream == request->mInputStream) return true;
5186 }
5187
5188 return false;
5189 }
5190
isOutputSurfacePending(int streamId,size_t surfaceId)5191 bool Camera3Device::RequestThread::isOutputSurfacePending(int streamId, size_t surfaceId) {
5192 ATRACE_CALL();
5193 Mutex::Autolock l(mRequestLock);
5194
5195 for (const auto& nextRequest : mNextRequests) {
5196 for (const auto& s : nextRequest.captureRequest->mOutputSurfaces) {
5197 if (s.first == streamId) {
5198 const auto &it = std::find(s.second.begin(), s.second.end(), surfaceId);
5199 if (it != s.second.end()) {
5200 return true;
5201 }
5202 }
5203 }
5204 }
5205
5206 for (const auto& request : mRequestQueue) {
5207 for (const auto& s : request->mOutputSurfaces) {
5208 if (s.first == streamId) {
5209 const auto &it = std::find(s.second.begin(), s.second.end(), surfaceId);
5210 if (it != s.second.end()) {
5211 return true;
5212 }
5213 }
5214 }
5215 }
5216
5217 for (const auto& request : mRepeatingRequests) {
5218 for (const auto& s : request->mOutputSurfaces) {
5219 if (s.first == streamId) {
5220 const auto &it = std::find(s.second.begin(), s.second.end(), surfaceId);
5221 if (it != s.second.end()) {
5222 return true;
5223 }
5224 }
5225 }
5226 }
5227
5228 return false;
5229 }
5230
signalPipelineDrain(const std::vector<int> & streamIds)5231 void Camera3Device::RequestThread::signalPipelineDrain(const std::vector<int>& streamIds) {
5232 if (!mUseHalBufManager) {
5233 ALOGE("%s called for camera device not supporting HAL buffer management", __FUNCTION__);
5234 return;
5235 }
5236
5237 Mutex::Autolock pl(mPauseLock);
5238 if (mPaused) {
5239 mInterface->signalPipelineDrain(streamIds);
5240 return;
5241 }
5242 // If request thread is still busy, wait until paused then notify HAL
5243 mNotifyPipelineDrain = true;
5244 mStreamIdsToBeDrained = streamIds;
5245 }
5246
resetPipelineDrain()5247 void Camera3Device::RequestThread::resetPipelineDrain() {
5248 Mutex::Autolock pl(mPauseLock);
5249 mNotifyPipelineDrain = false;
5250 mStreamIdsToBeDrained.clear();
5251 }
5252
clearPreviousRequest()5253 void Camera3Device::RequestThread::clearPreviousRequest() {
5254 Mutex::Autolock l(mRequestLock);
5255 mPrevRequest.clear();
5256 }
5257
switchToOffline(const std::vector<int32_t> & streamsToKeep,hardware::camera::device::V3_6::CameraOfflineSessionInfo * offlineSessionInfo,sp<hardware::camera::device::V3_6::ICameraOfflineSession> * offlineSession,camera3::BufferRecords * bufferRecords)5258 status_t Camera3Device::RequestThread::switchToOffline(
5259 const std::vector<int32_t>& streamsToKeep,
5260 /*out*/hardware::camera::device::V3_6::CameraOfflineSessionInfo* offlineSessionInfo,
5261 /*out*/sp<hardware::camera::device::V3_6::ICameraOfflineSession>* offlineSession,
5262 /*out*/camera3::BufferRecords* bufferRecords) {
5263 Mutex::Autolock l(mRequestLock);
5264 clearRepeatingRequestsLocked(/*lastFrameNumber*/nullptr);
5265
5266 // Wait until request thread is fully stopped
5267 // TBD: check if request thread is being paused by other APIs (shouldn't be)
5268
5269 // We could also check for mRepeatingRequests.empty(), but the API interface
5270 // is serialized by Camera3Device::mInterfaceLock so no one should be able to submit any
5271 // new requests during the call; hence skip that check.
5272 bool queueEmpty = mNextRequests.empty() && mRequestQueue.empty();
5273 while (!queueEmpty) {
5274 status_t res = mRequestSubmittedSignal.waitRelative(mRequestLock, kRequestSubmitTimeout);
5275 if (res == TIMED_OUT) {
5276 ALOGE("%s: request thread failed to submit one request within timeout!", __FUNCTION__);
5277 return res;
5278 } else if (res != OK) {
5279 ALOGE("%s: request thread failed to submit a request: %s (%d)!",
5280 __FUNCTION__, strerror(-res), res);
5281 return res;
5282 }
5283 queueEmpty = mNextRequests.empty() && mRequestQueue.empty();
5284 }
5285
5286 return mInterface->switchToOffline(
5287 streamsToKeep, offlineSessionInfo, offlineSession, bufferRecords);
5288 }
5289
setRotateAndCropAutoBehavior(camera_metadata_enum_android_scaler_rotate_and_crop_t rotateAndCropValue)5290 status_t Camera3Device::RequestThread::setRotateAndCropAutoBehavior(
5291 camera_metadata_enum_android_scaler_rotate_and_crop_t rotateAndCropValue) {
5292 ATRACE_CALL();
5293 Mutex::Autolock l(mTriggerMutex);
5294 if (rotateAndCropValue == ANDROID_SCALER_ROTATE_AND_CROP_AUTO) {
5295 return BAD_VALUE;
5296 }
5297 mRotateAndCropOverride = rotateAndCropValue;
5298 return OK;
5299 }
5300
setCameraMute(int32_t muteMode)5301 status_t Camera3Device::RequestThread::setCameraMute(int32_t muteMode) {
5302 ATRACE_CALL();
5303 Mutex::Autolock l(mTriggerMutex);
5304 if (muteMode != mCameraMute) {
5305 mCameraMute = muteMode;
5306 mCameraMuteChanged = true;
5307 }
5308 return OK;
5309 }
5310
getExpectedInFlightDuration()5311 nsecs_t Camera3Device::getExpectedInFlightDuration() {
5312 ATRACE_CALL();
5313 std::lock_guard<std::mutex> l(mInFlightLock);
5314 return mExpectedInflightDuration > kMinInflightDuration ?
5315 mExpectedInflightDuration : kMinInflightDuration;
5316 }
5317
cleanupPhysicalSettings(sp<CaptureRequest> request,camera_capture_request_t * halRequest)5318 void Camera3Device::RequestThread::cleanupPhysicalSettings(sp<CaptureRequest> request,
5319 camera_capture_request_t *halRequest) {
5320 if ((request == nullptr) || (halRequest == nullptr)) {
5321 ALOGE("%s: Invalid request!", __FUNCTION__);
5322 return;
5323 }
5324
5325 if (halRequest->num_physcam_settings > 0) {
5326 if (halRequest->physcam_id != nullptr) {
5327 delete [] halRequest->physcam_id;
5328 halRequest->physcam_id = nullptr;
5329 }
5330 if (halRequest->physcam_settings != nullptr) {
5331 auto it = ++(request->mSettingsList.begin());
5332 size_t i = 0;
5333 for (; it != request->mSettingsList.end(); it++, i++) {
5334 it->metadata.unlock(halRequest->physcam_settings[i]);
5335 }
5336 delete [] halRequest->physcam_settings;
5337 halRequest->physcam_settings = nullptr;
5338 }
5339 }
5340 }
5341
cleanUpFailedRequests(bool sendRequestError)5342 void Camera3Device::RequestThread::cleanUpFailedRequests(bool sendRequestError) {
5343 if (mNextRequests.empty()) {
5344 return;
5345 }
5346
5347 for (auto& nextRequest : mNextRequests) {
5348 // Skip the ones that have been submitted successfully.
5349 if (nextRequest.submitted) {
5350 continue;
5351 }
5352
5353 sp<CaptureRequest> captureRequest = nextRequest.captureRequest;
5354 camera_capture_request_t* halRequest = &nextRequest.halRequest;
5355 Vector<camera_stream_buffer_t>* outputBuffers = &nextRequest.outputBuffers;
5356
5357 if (halRequest->settings != NULL) {
5358 captureRequest->mSettingsList.begin()->metadata.unlock(halRequest->settings);
5359 }
5360
5361 cleanupPhysicalSettings(captureRequest, halRequest);
5362
5363 if (captureRequest->mInputStream != NULL) {
5364 captureRequest->mInputBuffer.status = CAMERA_BUFFER_STATUS_ERROR;
5365 captureRequest->mInputStream->returnInputBuffer(captureRequest->mInputBuffer);
5366 }
5367
5368 // No output buffer can be returned when using HAL buffer manager
5369 if (!mUseHalBufManager) {
5370 for (size_t i = 0; i < halRequest->num_output_buffers; i++) {
5371 //Buffers that failed processing could still have
5372 //valid acquire fence.
5373 int acquireFence = (*outputBuffers)[i].acquire_fence;
5374 if (0 <= acquireFence) {
5375 close(acquireFence);
5376 outputBuffers->editItemAt(i).acquire_fence = -1;
5377 }
5378 outputBuffers->editItemAt(i).status = CAMERA_BUFFER_STATUS_ERROR;
5379 captureRequest->mOutputStreams.editItemAt(i)->returnBuffer((*outputBuffers)[i], 0,
5380 /*timestampIncreasing*/true, std::vector<size_t> (),
5381 captureRequest->mResultExtras.frameNumber);
5382 }
5383 }
5384
5385 if (sendRequestError) {
5386 Mutex::Autolock l(mRequestLock);
5387 sp<NotificationListener> listener = mListener.promote();
5388 if (listener != NULL) {
5389 listener->notifyError(
5390 hardware::camera2::ICameraDeviceCallbacks::ERROR_CAMERA_REQUEST,
5391 captureRequest->mResultExtras);
5392 }
5393 }
5394
5395 // Remove yet-to-be submitted inflight request from inflightMap
5396 {
5397 sp<Camera3Device> parent = mParent.promote();
5398 if (parent != NULL) {
5399 std::lock_guard<std::mutex> l(parent->mInFlightLock);
5400 ssize_t idx = parent->mInFlightMap.indexOfKey(captureRequest->mResultExtras.frameNumber);
5401 if (idx >= 0) {
5402 ALOGV("%s: Remove inflight request from queue: frameNumber %" PRId64,
5403 __FUNCTION__, captureRequest->mResultExtras.frameNumber);
5404 parent->removeInFlightMapEntryLocked(idx);
5405 }
5406 }
5407 }
5408 }
5409
5410 Mutex::Autolock l(mRequestLock);
5411 mNextRequests.clear();
5412 }
5413
waitForNextRequestBatch()5414 void Camera3Device::RequestThread::waitForNextRequestBatch() {
5415 ATRACE_CALL();
5416 // Optimized a bit for the simple steady-state case (single repeating
5417 // request), to avoid putting that request in the queue temporarily.
5418 Mutex::Autolock l(mRequestLock);
5419
5420 assert(mNextRequests.empty());
5421
5422 NextRequest nextRequest;
5423 nextRequest.captureRequest = waitForNextRequestLocked();
5424 if (nextRequest.captureRequest == nullptr) {
5425 return;
5426 }
5427
5428 nextRequest.halRequest = camera_capture_request_t();
5429 nextRequest.submitted = false;
5430 mNextRequests.add(nextRequest);
5431
5432 // Wait for additional requests
5433 const size_t batchSize = nextRequest.captureRequest->mBatchSize;
5434
5435 for (size_t i = 1; i < batchSize; i++) {
5436 NextRequest additionalRequest;
5437 additionalRequest.captureRequest = waitForNextRequestLocked();
5438 if (additionalRequest.captureRequest == nullptr) {
5439 break;
5440 }
5441
5442 additionalRequest.halRequest = camera_capture_request_t();
5443 additionalRequest.submitted = false;
5444 mNextRequests.add(additionalRequest);
5445 }
5446
5447 if (mNextRequests.size() < batchSize) {
5448 ALOGE("RequestThread: only get %zu out of %zu requests. Skipping requests.",
5449 mNextRequests.size(), batchSize);
5450 cleanUpFailedRequests(/*sendRequestError*/true);
5451 }
5452
5453 return;
5454 }
5455
5456 sp<Camera3Device::CaptureRequest>
waitForNextRequestLocked()5457 Camera3Device::RequestThread::waitForNextRequestLocked() {
5458 status_t res;
5459 sp<CaptureRequest> nextRequest;
5460
5461 while (mRequestQueue.empty()) {
5462 if (!mRepeatingRequests.empty()) {
5463 // Always atomically enqueue all requests in a repeating request
5464 // list. Guarantees a complete in-sequence set of captures to
5465 // application.
5466 const RequestList &requests = mRepeatingRequests;
5467 if (mFirstRepeating) {
5468 mFirstRepeating = false;
5469 } else {
5470 for (auto& request : requests) {
5471 // For repeating requests, override timestamp request using
5472 // the time a request is inserted into the request queue,
5473 // because the original repeating request will have an old
5474 // fixed timestamp.
5475 request->mRequestTimeNs = systemTime();
5476 }
5477 }
5478 RequestList::const_iterator firstRequest =
5479 requests.begin();
5480 nextRequest = *firstRequest;
5481 mRequestQueue.insert(mRequestQueue.end(),
5482 ++firstRequest,
5483 requests.end());
5484 // No need to wait any longer
5485
5486 mRepeatingLastFrameNumber = mFrameNumber + requests.size() - 1;
5487
5488 break;
5489 }
5490
5491 res = mRequestSignal.waitRelative(mRequestLock, kRequestTimeout);
5492
5493 if ((mRequestQueue.empty() && mRepeatingRequests.empty()) ||
5494 exitPending()) {
5495 Mutex::Autolock pl(mPauseLock);
5496 if (mPaused == false) {
5497 ALOGV("%s: RequestThread: Going idle", __FUNCTION__);
5498 mPaused = true;
5499 if (mNotifyPipelineDrain) {
5500 mInterface->signalPipelineDrain(mStreamIdsToBeDrained);
5501 mNotifyPipelineDrain = false;
5502 mStreamIdsToBeDrained.clear();
5503 }
5504 // Let the tracker know
5505 sp<StatusTracker> statusTracker = mStatusTracker.promote();
5506 if (statusTracker != 0) {
5507 statusTracker->markComponentIdle(mStatusId, Fence::NO_FENCE);
5508 }
5509 sp<Camera3Device> parent = mParent.promote();
5510 if (parent != nullptr) {
5511 parent->mRequestBufferSM.onRequestThreadPaused();
5512 }
5513 }
5514 // Stop waiting for now and let thread management happen
5515 return NULL;
5516 }
5517 }
5518
5519 if (nextRequest == NULL) {
5520 // Don't have a repeating request already in hand, so queue
5521 // must have an entry now.
5522 RequestList::iterator firstRequest =
5523 mRequestQueue.begin();
5524 nextRequest = *firstRequest;
5525 mRequestQueue.erase(firstRequest);
5526 if (mRequestQueue.empty() && !nextRequest->mRepeating) {
5527 sp<NotificationListener> listener = mListener.promote();
5528 if (listener != NULL) {
5529 listener->notifyRequestQueueEmpty();
5530 }
5531 }
5532 }
5533
5534 // In case we've been unpaused by setPaused clearing mDoPause, need to
5535 // update internal pause state (capture/setRepeatingRequest unpause
5536 // directly).
5537 Mutex::Autolock pl(mPauseLock);
5538 if (mPaused) {
5539 ALOGV("%s: RequestThread: Unpaused", __FUNCTION__);
5540 sp<StatusTracker> statusTracker = mStatusTracker.promote();
5541 if (statusTracker != 0) {
5542 statusTracker->markComponentActive(mStatusId);
5543 }
5544 }
5545 mPaused = false;
5546
5547 // Check if we've reconfigured since last time, and reset the preview
5548 // request if so. Can't use 'NULL request == repeat' across configure calls.
5549 if (mReconfigured) {
5550 mPrevRequest.clear();
5551 mReconfigured = false;
5552 }
5553
5554 if (nextRequest != NULL) {
5555 nextRequest->mResultExtras.frameNumber = mFrameNumber++;
5556 nextRequest->mResultExtras.afTriggerId = mCurrentAfTriggerId;
5557 nextRequest->mResultExtras.precaptureTriggerId = mCurrentPreCaptureTriggerId;
5558
5559 // Since RequestThread::clear() removes buffers from the input stream,
5560 // get the right buffer here before unlocking mRequestLock
5561 if (nextRequest->mInputStream != NULL) {
5562 res = nextRequest->mInputStream->getInputBuffer(&nextRequest->mInputBuffer,
5563 &nextRequest->mInputBufferSize);
5564 if (res != OK) {
5565 // Can't get input buffer from gralloc queue - this could be due to
5566 // disconnected queue or other producer misbehavior, so not a fatal
5567 // error
5568 ALOGE("%s: Can't get input buffer, skipping request:"
5569 " %s (%d)", __FUNCTION__, strerror(-res), res);
5570
5571 sp<NotificationListener> listener = mListener.promote();
5572 if (listener != NULL) {
5573 listener->notifyError(
5574 hardware::camera2::ICameraDeviceCallbacks::ERROR_CAMERA_REQUEST,
5575 nextRequest->mResultExtras);
5576 }
5577 return NULL;
5578 }
5579 }
5580 }
5581
5582 return nextRequest;
5583 }
5584
waitIfPaused()5585 bool Camera3Device::RequestThread::waitIfPaused() {
5586 ATRACE_CALL();
5587 status_t res;
5588 Mutex::Autolock l(mPauseLock);
5589 while (mDoPause) {
5590 if (mPaused == false) {
5591 mPaused = true;
5592 ALOGV("%s: RequestThread: Paused", __FUNCTION__);
5593 if (mNotifyPipelineDrain) {
5594 mInterface->signalPipelineDrain(mStreamIdsToBeDrained);
5595 mNotifyPipelineDrain = false;
5596 mStreamIdsToBeDrained.clear();
5597 }
5598 // Let the tracker know
5599 sp<StatusTracker> statusTracker = mStatusTracker.promote();
5600 if (statusTracker != 0) {
5601 statusTracker->markComponentIdle(mStatusId, Fence::NO_FENCE);
5602 }
5603 sp<Camera3Device> parent = mParent.promote();
5604 if (parent != nullptr) {
5605 parent->mRequestBufferSM.onRequestThreadPaused();
5606 }
5607 }
5608
5609 res = mDoPauseSignal.waitRelative(mPauseLock, kRequestTimeout);
5610 if (res == TIMED_OUT || exitPending()) {
5611 return true;
5612 }
5613 }
5614 // We don't set mPaused to false here, because waitForNextRequest needs
5615 // to further manage the paused state in case of starvation.
5616 return false;
5617 }
5618
unpauseForNewRequests()5619 void Camera3Device::RequestThread::unpauseForNewRequests() {
5620 ATRACE_CALL();
5621 // With work to do, mark thread as unpaused.
5622 // If paused by request (setPaused), don't resume, to avoid
5623 // extra signaling/waiting overhead to waitUntilPaused
5624 mRequestSignal.signal();
5625 Mutex::Autolock p(mPauseLock);
5626 if (!mDoPause) {
5627 ALOGV("%s: RequestThread: Going active", __FUNCTION__);
5628 if (mPaused) {
5629 sp<StatusTracker> statusTracker = mStatusTracker.promote();
5630 if (statusTracker != 0) {
5631 statusTracker->markComponentActive(mStatusId);
5632 }
5633 }
5634 mPaused = false;
5635 }
5636 }
5637
setErrorState(const char * fmt,...)5638 void Camera3Device::RequestThread::setErrorState(const char *fmt, ...) {
5639 sp<Camera3Device> parent = mParent.promote();
5640 if (parent != NULL) {
5641 va_list args;
5642 va_start(args, fmt);
5643
5644 parent->setErrorStateV(fmt, args);
5645
5646 va_end(args);
5647 }
5648 }
5649
insertTriggers(const sp<CaptureRequest> & request)5650 status_t Camera3Device::RequestThread::insertTriggers(
5651 const sp<CaptureRequest> &request) {
5652 ATRACE_CALL();
5653 Mutex::Autolock al(mTriggerMutex);
5654
5655 sp<Camera3Device> parent = mParent.promote();
5656 if (parent == NULL) {
5657 CLOGE("RequestThread: Parent is gone");
5658 return DEAD_OBJECT;
5659 }
5660
5661 CameraMetadata &metadata = request->mSettingsList.begin()->metadata;
5662 size_t count = mTriggerMap.size();
5663
5664 for (size_t i = 0; i < count; ++i) {
5665 RequestTrigger trigger = mTriggerMap.valueAt(i);
5666 uint32_t tag = trigger.metadataTag;
5667
5668 if (tag == ANDROID_CONTROL_AF_TRIGGER_ID || tag == ANDROID_CONTROL_AE_PRECAPTURE_ID) {
5669 bool isAeTrigger = (trigger.metadataTag == ANDROID_CONTROL_AE_PRECAPTURE_ID);
5670 uint32_t triggerId = static_cast<uint32_t>(trigger.entryValue);
5671 if (isAeTrigger) {
5672 request->mResultExtras.precaptureTriggerId = triggerId;
5673 mCurrentPreCaptureTriggerId = triggerId;
5674 } else {
5675 request->mResultExtras.afTriggerId = triggerId;
5676 mCurrentAfTriggerId = triggerId;
5677 }
5678 continue;
5679 }
5680
5681 camera_metadata_entry entry = metadata.find(tag);
5682
5683 if (entry.count > 0) {
5684 /**
5685 * Already has an entry for this trigger in the request.
5686 * Rewrite it with our requested trigger value.
5687 */
5688 RequestTrigger oldTrigger = trigger;
5689
5690 oldTrigger.entryValue = entry.data.u8[0];
5691
5692 mTriggerReplacedMap.add(tag, oldTrigger);
5693 } else {
5694 /**
5695 * More typical, no trigger entry, so we just add it
5696 */
5697 mTriggerRemovedMap.add(tag, trigger);
5698 }
5699
5700 status_t res;
5701
5702 switch (trigger.getTagType()) {
5703 case TYPE_BYTE: {
5704 uint8_t entryValue = static_cast<uint8_t>(trigger.entryValue);
5705 res = metadata.update(tag,
5706 &entryValue,
5707 /*count*/1);
5708 break;
5709 }
5710 case TYPE_INT32:
5711 res = metadata.update(tag,
5712 &trigger.entryValue,
5713 /*count*/1);
5714 break;
5715 default:
5716 ALOGE("%s: Type not supported: 0x%x",
5717 __FUNCTION__,
5718 trigger.getTagType());
5719 return INVALID_OPERATION;
5720 }
5721
5722 if (res != OK) {
5723 ALOGE("%s: Failed to update request metadata with trigger tag %s"
5724 ", value %d", __FUNCTION__, trigger.getTagName(),
5725 trigger.entryValue);
5726 return res;
5727 }
5728
5729 ALOGV("%s: Mixed in trigger %s, value %d", __FUNCTION__,
5730 trigger.getTagName(),
5731 trigger.entryValue);
5732 }
5733
5734 mTriggerMap.clear();
5735
5736 return count;
5737 }
5738
removeTriggers(const sp<CaptureRequest> & request)5739 status_t Camera3Device::RequestThread::removeTriggers(
5740 const sp<CaptureRequest> &request) {
5741 ATRACE_CALL();
5742 Mutex::Autolock al(mTriggerMutex);
5743
5744 CameraMetadata &metadata = request->mSettingsList.begin()->metadata;
5745
5746 /**
5747 * Replace all old entries with their old values.
5748 */
5749 for (size_t i = 0; i < mTriggerReplacedMap.size(); ++i) {
5750 RequestTrigger trigger = mTriggerReplacedMap.valueAt(i);
5751
5752 status_t res;
5753
5754 uint32_t tag = trigger.metadataTag;
5755 switch (trigger.getTagType()) {
5756 case TYPE_BYTE: {
5757 uint8_t entryValue = static_cast<uint8_t>(trigger.entryValue);
5758 res = metadata.update(tag,
5759 &entryValue,
5760 /*count*/1);
5761 break;
5762 }
5763 case TYPE_INT32:
5764 res = metadata.update(tag,
5765 &trigger.entryValue,
5766 /*count*/1);
5767 break;
5768 default:
5769 ALOGE("%s: Type not supported: 0x%x",
5770 __FUNCTION__,
5771 trigger.getTagType());
5772 return INVALID_OPERATION;
5773 }
5774
5775 if (res != OK) {
5776 ALOGE("%s: Failed to restore request metadata with trigger tag %s"
5777 ", trigger value %d", __FUNCTION__,
5778 trigger.getTagName(), trigger.entryValue);
5779 return res;
5780 }
5781 }
5782 mTriggerReplacedMap.clear();
5783
5784 /**
5785 * Remove all new entries.
5786 */
5787 for (size_t i = 0; i < mTriggerRemovedMap.size(); ++i) {
5788 RequestTrigger trigger = mTriggerRemovedMap.valueAt(i);
5789 status_t res = metadata.erase(trigger.metadataTag);
5790
5791 if (res != OK) {
5792 ALOGE("%s: Failed to erase metadata with trigger tag %s"
5793 ", trigger value %d", __FUNCTION__,
5794 trigger.getTagName(), trigger.entryValue);
5795 return res;
5796 }
5797 }
5798 mTriggerRemovedMap.clear();
5799
5800 return OK;
5801 }
5802
addFakeTriggerIds(const sp<CaptureRequest> & request)5803 status_t Camera3Device::RequestThread::addFakeTriggerIds(
5804 const sp<CaptureRequest> &request) {
5805 // Trigger ID 0 had special meaning in the HAL2 spec, so avoid it here
5806 static const int32_t fakeTriggerId = 1;
5807 status_t res;
5808
5809 CameraMetadata &metadata = request->mSettingsList.begin()->metadata;
5810
5811 // If AF trigger is active, insert a fake AF trigger ID if none already
5812 // exists
5813 camera_metadata_entry afTrigger = metadata.find(ANDROID_CONTROL_AF_TRIGGER);
5814 camera_metadata_entry afId = metadata.find(ANDROID_CONTROL_AF_TRIGGER_ID);
5815 if (afTrigger.count > 0 &&
5816 afTrigger.data.u8[0] != ANDROID_CONTROL_AF_TRIGGER_IDLE &&
5817 afId.count == 0) {
5818 res = metadata.update(ANDROID_CONTROL_AF_TRIGGER_ID, &fakeTriggerId, 1);
5819 if (res != OK) return res;
5820 }
5821
5822 // If AE precapture trigger is active, insert a fake precapture trigger ID
5823 // if none already exists
5824 camera_metadata_entry pcTrigger =
5825 metadata.find(ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER);
5826 camera_metadata_entry pcId = metadata.find(ANDROID_CONTROL_AE_PRECAPTURE_ID);
5827 if (pcTrigger.count > 0 &&
5828 pcTrigger.data.u8[0] != ANDROID_CONTROL_AE_PRECAPTURE_TRIGGER_IDLE &&
5829 pcId.count == 0) {
5830 res = metadata.update(ANDROID_CONTROL_AE_PRECAPTURE_ID,
5831 &fakeTriggerId, 1);
5832 if (res != OK) return res;
5833 }
5834
5835 return OK;
5836 }
5837
overrideAutoRotateAndCrop(const sp<CaptureRequest> & request)5838 bool Camera3Device::RequestThread::overrideAutoRotateAndCrop(
5839 const sp<CaptureRequest> &request) {
5840 ATRACE_CALL();
5841
5842 if (request->mRotateAndCropAuto) {
5843 Mutex::Autolock l(mTriggerMutex);
5844 CameraMetadata &metadata = request->mSettingsList.begin()->metadata;
5845
5846 auto rotateAndCropEntry = metadata.find(ANDROID_SCALER_ROTATE_AND_CROP);
5847 if (rotateAndCropEntry.count > 0) {
5848 if (rotateAndCropEntry.data.u8[0] == mRotateAndCropOverride) {
5849 return false;
5850 } else {
5851 rotateAndCropEntry.data.u8[0] = mRotateAndCropOverride;
5852 return true;
5853 }
5854 } else {
5855 uint8_t rotateAndCrop_u8 = mRotateAndCropOverride;
5856 metadata.update(ANDROID_SCALER_ROTATE_AND_CROP,
5857 &rotateAndCrop_u8, 1);
5858 return true;
5859 }
5860 }
5861 return false;
5862 }
5863
overrideTestPattern(const sp<CaptureRequest> & request)5864 bool Camera3Device::RequestThread::overrideTestPattern(
5865 const sp<CaptureRequest> &request) {
5866 ATRACE_CALL();
5867
5868 if (!mSupportCameraMute) return false;
5869
5870 Mutex::Autolock l(mTriggerMutex);
5871
5872 bool changed = false;
5873
5874 int32_t testPatternMode = request->mOriginalTestPatternMode;
5875 int32_t testPatternData[4] = {
5876 request->mOriginalTestPatternData[0],
5877 request->mOriginalTestPatternData[1],
5878 request->mOriginalTestPatternData[2],
5879 request->mOriginalTestPatternData[3]
5880 };
5881
5882 if (mCameraMute != ANDROID_SENSOR_TEST_PATTERN_MODE_OFF) {
5883 testPatternMode = mCameraMute;
5884 testPatternData[0] = 0;
5885 testPatternData[1] = 0;
5886 testPatternData[2] = 0;
5887 testPatternData[3] = 0;
5888 }
5889
5890 CameraMetadata &metadata = request->mSettingsList.begin()->metadata;
5891
5892 auto testPatternEntry = metadata.find(ANDROID_SENSOR_TEST_PATTERN_MODE);
5893 if (testPatternEntry.count > 0) {
5894 if (testPatternEntry.data.i32[0] != testPatternMode) {
5895 testPatternEntry.data.i32[0] = testPatternMode;
5896 changed = true;
5897 }
5898 } else {
5899 metadata.update(ANDROID_SENSOR_TEST_PATTERN_MODE,
5900 &testPatternMode, 1);
5901 changed = true;
5902 }
5903
5904 auto testPatternColor = metadata.find(ANDROID_SENSOR_TEST_PATTERN_DATA);
5905 if (testPatternColor.count >= 4) {
5906 for (size_t i = 0; i < 4; i++) {
5907 if (testPatternColor.data.i32[i] != testPatternData[i]) {
5908 testPatternColor.data.i32[i] = testPatternData[i];
5909 changed = true;
5910 }
5911 }
5912 } else {
5913 metadata.update(ANDROID_SENSOR_TEST_PATTERN_DATA,
5914 testPatternData, 4);
5915 changed = true;
5916 }
5917
5918 return changed;
5919 }
5920
setHalInterface(sp<HalInterface> newHalInterface)5921 status_t Camera3Device::RequestThread::setHalInterface(
5922 sp<HalInterface> newHalInterface) {
5923 if (newHalInterface.get() == nullptr) {
5924 ALOGE("%s: The newHalInterface does not exist!", __FUNCTION__);
5925 return DEAD_OBJECT;
5926 }
5927
5928 mInterface = newHalInterface;
5929
5930 return OK;
5931 }
5932
5933 /**
5934 * PreparerThread inner class methods
5935 */
5936
PreparerThread()5937 Camera3Device::PreparerThread::PreparerThread() :
5938 Thread(/*canCallJava*/false), mListener(nullptr),
5939 mActive(false), mCancelNow(false), mCurrentMaxCount(0), mCurrentPrepareComplete(false) {
5940 }
5941
~PreparerThread()5942 Camera3Device::PreparerThread::~PreparerThread() {
5943 Thread::requestExitAndWait();
5944 if (mCurrentStream != nullptr) {
5945 mCurrentStream->cancelPrepare();
5946 ATRACE_ASYNC_END("stream prepare", mCurrentStream->getId());
5947 mCurrentStream.clear();
5948 }
5949 clear();
5950 }
5951
prepare(int maxCount,sp<Camera3StreamInterface> & stream)5952 status_t Camera3Device::PreparerThread::prepare(int maxCount, sp<Camera3StreamInterface>& stream) {
5953 ATRACE_CALL();
5954 status_t res;
5955
5956 Mutex::Autolock l(mLock);
5957 sp<NotificationListener> listener = mListener.promote();
5958
5959 res = stream->startPrepare(maxCount, true /*blockRequest*/);
5960 if (res == OK) {
5961 // No preparation needed, fire listener right off
5962 ALOGV("%s: Stream %d already prepared", __FUNCTION__, stream->getId());
5963 if (listener != NULL) {
5964 listener->notifyPrepared(stream->getId());
5965 }
5966 return OK;
5967 } else if (res != NOT_ENOUGH_DATA) {
5968 return res;
5969 }
5970
5971 // Need to prepare, start up thread if necessary
5972 if (!mActive) {
5973 // mRunning will change to false before the thread fully shuts down, so wait to be sure it
5974 // isn't running
5975 Thread::requestExitAndWait();
5976 res = Thread::run("C3PrepThread", PRIORITY_BACKGROUND);
5977 if (res != OK) {
5978 ALOGE("%s: Unable to start preparer stream: %d (%s)", __FUNCTION__, res, strerror(-res));
5979 if (listener != NULL) {
5980 listener->notifyPrepared(stream->getId());
5981 }
5982 return res;
5983 }
5984 mCancelNow = false;
5985 mActive = true;
5986 ALOGV("%s: Preparer stream started", __FUNCTION__);
5987 }
5988
5989 // queue up the work
5990 mPendingStreams.emplace(maxCount, stream);
5991 ALOGV("%s: Stream %d queued for preparing", __FUNCTION__, stream->getId());
5992
5993 return OK;
5994 }
5995
pause()5996 void Camera3Device::PreparerThread::pause() {
5997 ATRACE_CALL();
5998
5999 Mutex::Autolock l(mLock);
6000
6001 std::unordered_map<int, sp<camera3::Camera3StreamInterface> > pendingStreams;
6002 pendingStreams.insert(mPendingStreams.begin(), mPendingStreams.end());
6003 sp<camera3::Camera3StreamInterface> currentStream = mCurrentStream;
6004 int currentMaxCount = mCurrentMaxCount;
6005 mPendingStreams.clear();
6006 mCancelNow = true;
6007 while (mActive) {
6008 auto res = mThreadActiveSignal.waitRelative(mLock, kActiveTimeout);
6009 if (res == TIMED_OUT) {
6010 ALOGE("%s: Timed out waiting on prepare thread!", __FUNCTION__);
6011 return;
6012 } else if (res != OK) {
6013 ALOGE("%s: Encountered an error: %d waiting on prepare thread!", __FUNCTION__, res);
6014 return;
6015 }
6016 }
6017
6018 //Check whether the prepare thread was able to complete the current
6019 //stream. In case work is still pending emplace it along with the rest
6020 //of the streams in the pending list.
6021 if (currentStream != nullptr) {
6022 if (!mCurrentPrepareComplete) {
6023 pendingStreams.emplace(currentMaxCount, currentStream);
6024 }
6025 }
6026
6027 mPendingStreams.insert(pendingStreams.begin(), pendingStreams.end());
6028 for (const auto& it : mPendingStreams) {
6029 it.second->cancelPrepare();
6030 }
6031 }
6032
resume()6033 status_t Camera3Device::PreparerThread::resume() {
6034 ATRACE_CALL();
6035 status_t res;
6036
6037 Mutex::Autolock l(mLock);
6038 sp<NotificationListener> listener = mListener.promote();
6039
6040 if (mActive) {
6041 ALOGE("%s: Trying to resume an already active prepare thread!", __FUNCTION__);
6042 return NO_INIT;
6043 }
6044
6045 auto it = mPendingStreams.begin();
6046 for (; it != mPendingStreams.end();) {
6047 res = it->second->startPrepare(it->first, true /*blockRequest*/);
6048 if (res == OK) {
6049 if (listener != NULL) {
6050 listener->notifyPrepared(it->second->getId());
6051 }
6052 it = mPendingStreams.erase(it);
6053 } else if (res != NOT_ENOUGH_DATA) {
6054 ALOGE("%s: Unable to start preparer stream: %d (%s)", __FUNCTION__,
6055 res, strerror(-res));
6056 it = mPendingStreams.erase(it);
6057 } else {
6058 it++;
6059 }
6060 }
6061
6062 if (mPendingStreams.empty()) {
6063 return OK;
6064 }
6065
6066 res = Thread::run("C3PrepThread", PRIORITY_BACKGROUND);
6067 if (res != OK) {
6068 ALOGE("%s: Unable to start preparer stream: %d (%s)",
6069 __FUNCTION__, res, strerror(-res));
6070 return res;
6071 }
6072 mCancelNow = false;
6073 mActive = true;
6074 ALOGV("%s: Preparer stream started", __FUNCTION__);
6075
6076 return OK;
6077 }
6078
clear()6079 status_t Camera3Device::PreparerThread::clear() {
6080 ATRACE_CALL();
6081 Mutex::Autolock l(mLock);
6082
6083 for (const auto& it : mPendingStreams) {
6084 it.second->cancelPrepare();
6085 }
6086 mPendingStreams.clear();
6087 mCancelNow = true;
6088
6089 return OK;
6090 }
6091
setNotificationListener(wp<NotificationListener> listener)6092 void Camera3Device::PreparerThread::setNotificationListener(wp<NotificationListener> listener) {
6093 ATRACE_CALL();
6094 Mutex::Autolock l(mLock);
6095 mListener = listener;
6096 }
6097
threadLoop()6098 bool Camera3Device::PreparerThread::threadLoop() {
6099 status_t res;
6100 {
6101 Mutex::Autolock l(mLock);
6102 if (mCurrentStream == nullptr) {
6103 // End thread if done with work
6104 if (mPendingStreams.empty()) {
6105 ALOGV("%s: Preparer stream out of work", __FUNCTION__);
6106 // threadLoop _must not_ re-acquire mLock after it sets mActive to false; would
6107 // cause deadlock with prepare()'s requestExitAndWait triggered by !mActive.
6108 mActive = false;
6109 mThreadActiveSignal.signal();
6110 return false;
6111 }
6112
6113 // Get next stream to prepare
6114 auto it = mPendingStreams.begin();
6115 mCurrentStream = it->second;
6116 mCurrentMaxCount = it->first;
6117 mCurrentPrepareComplete = false;
6118 mPendingStreams.erase(it);
6119 ATRACE_ASYNC_BEGIN("stream prepare", mCurrentStream->getId());
6120 ALOGV("%s: Preparing stream %d", __FUNCTION__, mCurrentStream->getId());
6121 } else if (mCancelNow) {
6122 mCurrentStream->cancelPrepare();
6123 ATRACE_ASYNC_END("stream prepare", mCurrentStream->getId());
6124 ALOGV("%s: Cancelling stream %d prepare", __FUNCTION__, mCurrentStream->getId());
6125 mCurrentStream.clear();
6126 mCancelNow = false;
6127 return true;
6128 }
6129 }
6130
6131 res = mCurrentStream->prepareNextBuffer();
6132 if (res == NOT_ENOUGH_DATA) return true;
6133 if (res != OK) {
6134 // Something bad happened; try to recover by cancelling prepare and
6135 // signalling listener anyway
6136 ALOGE("%s: Stream %d returned error %d (%s) during prepare", __FUNCTION__,
6137 mCurrentStream->getId(), res, strerror(-res));
6138 mCurrentStream->cancelPrepare();
6139 }
6140
6141 // This stream has finished, notify listener
6142 Mutex::Autolock l(mLock);
6143 sp<NotificationListener> listener = mListener.promote();
6144 if (listener != NULL) {
6145 ALOGV("%s: Stream %d prepare done, signaling listener", __FUNCTION__,
6146 mCurrentStream->getId());
6147 listener->notifyPrepared(mCurrentStream->getId());
6148 }
6149
6150 ATRACE_ASYNC_END("stream prepare", mCurrentStream->getId());
6151 mCurrentStream.clear();
6152 mCurrentPrepareComplete = true;
6153
6154 return true;
6155 }
6156
initialize(sp<camera3::StatusTracker> statusTracker)6157 status_t Camera3Device::RequestBufferStateMachine::initialize(
6158 sp<camera3::StatusTracker> statusTracker) {
6159 if (statusTracker == nullptr) {
6160 ALOGE("%s: statusTracker is null", __FUNCTION__);
6161 return BAD_VALUE;
6162 }
6163
6164 std::lock_guard<std::mutex> lock(mLock);
6165 mStatusTracker = statusTracker;
6166 mRequestBufferStatusId = statusTracker->addComponent("BufferRequestSM");
6167 return OK;
6168 }
6169
startRequestBuffer()6170 bool Camera3Device::RequestBufferStateMachine::startRequestBuffer() {
6171 std::lock_guard<std::mutex> lock(mLock);
6172 if (mStatus == RB_STATUS_READY || mStatus == RB_STATUS_PENDING_STOP) {
6173 mRequestBufferOngoing = true;
6174 notifyTrackerLocked(/*active*/true);
6175 return true;
6176 }
6177 return false;
6178 }
6179
endRequestBuffer()6180 void Camera3Device::RequestBufferStateMachine::endRequestBuffer() {
6181 std::lock_guard<std::mutex> lock(mLock);
6182 if (!mRequestBufferOngoing) {
6183 ALOGE("%s called without a successful startRequestBuffer call first!", __FUNCTION__);
6184 return;
6185 }
6186 mRequestBufferOngoing = false;
6187 if (mStatus == RB_STATUS_PENDING_STOP) {
6188 checkSwitchToStopLocked();
6189 }
6190 notifyTrackerLocked(/*active*/false);
6191 }
6192
onStreamsConfigured()6193 void Camera3Device::RequestBufferStateMachine::onStreamsConfigured() {
6194 std::lock_guard<std::mutex> lock(mLock);
6195 mSwitchedToOffline = false;
6196 mStatus = RB_STATUS_READY;
6197 return;
6198 }
6199
onSubmittingRequest()6200 void Camera3Device::RequestBufferStateMachine::onSubmittingRequest() {
6201 std::lock_guard<std::mutex> lock(mLock);
6202 mRequestThreadPaused = false;
6203 // inflight map register actually happens in prepareHalRequest now, but it is close enough
6204 // approximation.
6205 mInflightMapEmpty = false;
6206 if (mStatus == RB_STATUS_STOPPED) {
6207 mStatus = RB_STATUS_READY;
6208 }
6209 return;
6210 }
6211
onRequestThreadPaused()6212 void Camera3Device::RequestBufferStateMachine::onRequestThreadPaused() {
6213 std::lock_guard<std::mutex> lock(mLock);
6214 mRequestThreadPaused = true;
6215 if (mStatus == RB_STATUS_PENDING_STOP) {
6216 checkSwitchToStopLocked();
6217 }
6218 return;
6219 }
6220
onInflightMapEmpty()6221 void Camera3Device::RequestBufferStateMachine::onInflightMapEmpty() {
6222 std::lock_guard<std::mutex> lock(mLock);
6223 mInflightMapEmpty = true;
6224 if (mStatus == RB_STATUS_PENDING_STOP) {
6225 checkSwitchToStopLocked();
6226 }
6227 return;
6228 }
6229
onWaitUntilIdle()6230 void Camera3Device::RequestBufferStateMachine::onWaitUntilIdle() {
6231 std::lock_guard<std::mutex> lock(mLock);
6232 if (!checkSwitchToStopLocked()) {
6233 mStatus = RB_STATUS_PENDING_STOP;
6234 }
6235 return;
6236 }
6237
onSwitchToOfflineSuccess()6238 bool Camera3Device::RequestBufferStateMachine::onSwitchToOfflineSuccess() {
6239 std::lock_guard<std::mutex> lock(mLock);
6240 if (mRequestBufferOngoing) {
6241 ALOGE("%s: HAL must not be requesting buffer after HAL returns switchToOffline!",
6242 __FUNCTION__);
6243 return false;
6244 }
6245 mSwitchedToOffline = true;
6246 mInflightMapEmpty = true;
6247 mRequestThreadPaused = true;
6248 mStatus = RB_STATUS_STOPPED;
6249 return true;
6250 }
6251
notifyTrackerLocked(bool active)6252 void Camera3Device::RequestBufferStateMachine::notifyTrackerLocked(bool active) {
6253 sp<StatusTracker> statusTracker = mStatusTracker.promote();
6254 if (statusTracker != nullptr) {
6255 if (active) {
6256 statusTracker->markComponentActive(mRequestBufferStatusId);
6257 } else {
6258 statusTracker->markComponentIdle(mRequestBufferStatusId, Fence::NO_FENCE);
6259 }
6260 }
6261 }
6262
checkSwitchToStopLocked()6263 bool Camera3Device::RequestBufferStateMachine::checkSwitchToStopLocked() {
6264 if (mInflightMapEmpty && mRequestThreadPaused && !mRequestBufferOngoing) {
6265 mStatus = RB_STATUS_STOPPED;
6266 return true;
6267 }
6268 return false;
6269 }
6270
startRequestBuffer()6271 bool Camera3Device::startRequestBuffer() {
6272 return mRequestBufferSM.startRequestBuffer();
6273 }
6274
endRequestBuffer()6275 void Camera3Device::endRequestBuffer() {
6276 mRequestBufferSM.endRequestBuffer();
6277 }
6278
getWaitDuration()6279 nsecs_t Camera3Device::getWaitDuration() {
6280 return kBaseGetBufferWait + getExpectedInFlightDuration();
6281 }
6282
getInflightBufferKeys(std::vector<std::pair<int32_t,int32_t>> * out)6283 void Camera3Device::getInflightBufferKeys(std::vector<std::pair<int32_t, int32_t>>* out) {
6284 mInterface->getInflightBufferKeys(out);
6285 }
6286
getInflightRequestBufferKeys(std::vector<uint64_t> * out)6287 void Camera3Device::getInflightRequestBufferKeys(std::vector<uint64_t>* out) {
6288 mInterface->getInflightRequestBufferKeys(out);
6289 }
6290
getAllStreams()6291 std::vector<sp<Camera3StreamInterface>> Camera3Device::getAllStreams() {
6292 std::vector<sp<Camera3StreamInterface>> ret;
6293 bool hasInputStream = mInputStream != nullptr;
6294 ret.reserve(mOutputStreams.size() + mDeletedStreams.size() + ((hasInputStream) ? 1 : 0));
6295 if (hasInputStream) {
6296 ret.push_back(mInputStream);
6297 }
6298 for (size_t i = 0; i < mOutputStreams.size(); i++) {
6299 ret.push_back(mOutputStreams[i]);
6300 }
6301 for (size_t i = 0; i < mDeletedStreams.size(); i++) {
6302 ret.push_back(mDeletedStreams[i]);
6303 }
6304 return ret;
6305 }
6306
switchToOffline(const std::vector<int32_t> & streamsToKeep,sp<CameraOfflineSessionBase> * session)6307 status_t Camera3Device::switchToOffline(
6308 const std::vector<int32_t>& streamsToKeep,
6309 /*out*/ sp<CameraOfflineSessionBase>* session) {
6310 ATRACE_CALL();
6311 if (session == nullptr) {
6312 ALOGE("%s: session must not be null", __FUNCTION__);
6313 return BAD_VALUE;
6314 }
6315
6316 Mutex::Autolock il(mInterfaceLock);
6317
6318 bool hasInputStream = mInputStream != nullptr;
6319 int32_t inputStreamId = hasInputStream ? mInputStream->getId() : -1;
6320 bool inputStreamSupportsOffline = hasInputStream ?
6321 mInputStream->getOfflineProcessingSupport() : false;
6322 auto outputStreamIds = mOutputStreams.getStreamIds();
6323 auto streamIds = outputStreamIds;
6324 if (hasInputStream) {
6325 streamIds.push_back(mInputStream->getId());
6326 }
6327
6328 // Check all streams in streamsToKeep supports offline mode
6329 for (auto id : streamsToKeep) {
6330 if (std::find(streamIds.begin(), streamIds.end(), id) == streamIds.end()) {
6331 ALOGE("%s: Unknown stream ID %d", __FUNCTION__, id);
6332 return BAD_VALUE;
6333 } else if (id == inputStreamId) {
6334 if (!inputStreamSupportsOffline) {
6335 ALOGE("%s: input stream %d cannot be switched to offline",
6336 __FUNCTION__, id);
6337 return BAD_VALUE;
6338 }
6339 } else {
6340 sp<camera3::Camera3OutputStreamInterface> stream = mOutputStreams.get(id);
6341 if (!stream->getOfflineProcessingSupport()) {
6342 ALOGE("%s: output stream %d cannot be switched to offline",
6343 __FUNCTION__, id);
6344 return BAD_VALUE;
6345 }
6346 }
6347 }
6348
6349 // TODO: block surface sharing and surface group streams until we can support them
6350
6351 // Stop repeating request, wait until all remaining requests are submitted, then call into
6352 // HAL switchToOffline
6353 hardware::camera::device::V3_6::CameraOfflineSessionInfo offlineSessionInfo;
6354 sp<hardware::camera::device::V3_6::ICameraOfflineSession> offlineSession;
6355 camera3::BufferRecords bufferRecords;
6356 status_t ret = mRequestThread->switchToOffline(
6357 streamsToKeep, &offlineSessionInfo, &offlineSession, &bufferRecords);
6358
6359 if (ret != OK) {
6360 SET_ERR("Switch to offline failed: %s (%d)", strerror(-ret), ret);
6361 return ret;
6362 }
6363
6364 bool succ = mRequestBufferSM.onSwitchToOfflineSuccess();
6365 if (!succ) {
6366 SET_ERR("HAL must not be calling requestStreamBuffers call");
6367 // TODO: block ALL callbacks from HAL till app configured new streams?
6368 return UNKNOWN_ERROR;
6369 }
6370
6371 // Verify offlineSessionInfo
6372 std::vector<int32_t> offlineStreamIds;
6373 offlineStreamIds.reserve(offlineSessionInfo.offlineStreams.size());
6374 for (auto offlineStream : offlineSessionInfo.offlineStreams) {
6375 // verify stream IDs
6376 int32_t id = offlineStream.id;
6377 if (std::find(streamIds.begin(), streamIds.end(), id) == streamIds.end()) {
6378 SET_ERR("stream ID %d not found!", id);
6379 return UNKNOWN_ERROR;
6380 }
6381
6382 // When not using HAL buf manager, only allow streams requested by app to be preserved
6383 if (!mUseHalBufManager) {
6384 if (std::find(streamsToKeep.begin(), streamsToKeep.end(), id) == streamsToKeep.end()) {
6385 SET_ERR("stream ID %d must not be switched to offline!", id);
6386 return UNKNOWN_ERROR;
6387 }
6388 }
6389
6390 offlineStreamIds.push_back(id);
6391 sp<Camera3StreamInterface> stream = (id == inputStreamId) ?
6392 static_cast<sp<Camera3StreamInterface>>(mInputStream) :
6393 static_cast<sp<Camera3StreamInterface>>(mOutputStreams.get(id));
6394 // Verify number of outstanding buffers
6395 if (stream->getOutstandingBuffersCount() != offlineStream.numOutstandingBuffers) {
6396 SET_ERR("Offline stream %d # of remaining buffer mismatch: (%zu,%d) (service/HAL)",
6397 id, stream->getOutstandingBuffersCount(), offlineStream.numOutstandingBuffers);
6398 return UNKNOWN_ERROR;
6399 }
6400 }
6401
6402 // Verify all streams to be deleted don't have any outstanding buffers
6403 if (hasInputStream && std::find(offlineStreamIds.begin(), offlineStreamIds.end(),
6404 inputStreamId) == offlineStreamIds.end()) {
6405 if (mInputStream->hasOutstandingBuffers()) {
6406 SET_ERR("Input stream %d still has %zu outstanding buffer!",
6407 inputStreamId, mInputStream->getOutstandingBuffersCount());
6408 return UNKNOWN_ERROR;
6409 }
6410 }
6411
6412 for (const auto& outStreamId : outputStreamIds) {
6413 if (std::find(offlineStreamIds.begin(), offlineStreamIds.end(),
6414 outStreamId) == offlineStreamIds.end()) {
6415 auto outStream = mOutputStreams.get(outStreamId);
6416 if (outStream->hasOutstandingBuffers()) {
6417 SET_ERR("Output stream %d still has %zu outstanding buffer!",
6418 outStreamId, outStream->getOutstandingBuffersCount());
6419 return UNKNOWN_ERROR;
6420 }
6421 }
6422 }
6423
6424 InFlightRequestMap offlineReqs;
6425 // Verify inflight requests and their pending buffers
6426 {
6427 std::lock_guard<std::mutex> l(mInFlightLock);
6428 for (auto offlineReq : offlineSessionInfo.offlineRequests) {
6429 int idx = mInFlightMap.indexOfKey(offlineReq.frameNumber);
6430 if (idx == NAME_NOT_FOUND) {
6431 SET_ERR("Offline request frame number %d not found!", offlineReq.frameNumber);
6432 return UNKNOWN_ERROR;
6433 }
6434
6435 const auto& inflightReq = mInFlightMap.valueAt(idx);
6436 // TODO: check specific stream IDs
6437 size_t numBuffersLeft = static_cast<size_t>(inflightReq.numBuffersLeft);
6438 if (numBuffersLeft != offlineReq.pendingStreams.size()) {
6439 SET_ERR("Offline request # of remaining buffer mismatch: (%d,%d) (service/HAL)",
6440 inflightReq.numBuffersLeft, offlineReq.pendingStreams.size());
6441 return UNKNOWN_ERROR;
6442 }
6443 offlineReqs.add(offlineReq.frameNumber, inflightReq);
6444 }
6445 }
6446
6447 // Create Camera3OfflineSession and transfer object ownership
6448 // (streams, inflight requests, buffer caches)
6449 camera3::StreamSet offlineStreamSet;
6450 sp<camera3::Camera3Stream> inputStream;
6451 for (auto offlineStream : offlineSessionInfo.offlineStreams) {
6452 int32_t id = offlineStream.id;
6453 if (mInputStream != nullptr && id == mInputStream->getId()) {
6454 inputStream = mInputStream;
6455 } else {
6456 offlineStreamSet.add(id, mOutputStreams.get(id));
6457 }
6458 }
6459
6460 // TODO: check if we need to lock before copying states
6461 // though technically no other thread should be talking to Camera3Device at this point
6462 Camera3OfflineStates offlineStates(
6463 mTagMonitor, mVendorTagId, mUseHalBufManager, mNeedFixupMonochromeTags,
6464 mUsePartialResult, mNumPartialResults, mLastCompletedRegularFrameNumber,
6465 mLastCompletedReprocessFrameNumber, mLastCompletedZslFrameNumber,
6466 mNextResultFrameNumber, mNextReprocessResultFrameNumber,
6467 mNextZslStillResultFrameNumber, mNextShutterFrameNumber,
6468 mNextReprocessShutterFrameNumber, mNextZslStillShutterFrameNumber,
6469 mDeviceInfo, mPhysicalDeviceInfoMap, mDistortionMappers,
6470 mZoomRatioMappers, mRotateAndCropMappers);
6471
6472 *session = new Camera3OfflineSession(mId, inputStream, offlineStreamSet,
6473 std::move(bufferRecords), offlineReqs, offlineStates, offlineSession);
6474
6475 // Delete all streams that has been transferred to offline session
6476 Mutex::Autolock l(mLock);
6477 for (auto offlineStream : offlineSessionInfo.offlineStreams) {
6478 int32_t id = offlineStream.id;
6479 if (mInputStream != nullptr && id == mInputStream->getId()) {
6480 mInputStream.clear();
6481 } else {
6482 mOutputStreams.remove(id);
6483 }
6484 }
6485
6486 // disconnect all other streams and switch to UNCONFIGURED state
6487 if (mInputStream != nullptr) {
6488 ret = mInputStream->disconnect();
6489 if (ret != OK) {
6490 SET_ERR_L("disconnect input stream failed!");
6491 return UNKNOWN_ERROR;
6492 }
6493 }
6494
6495 for (auto streamId : mOutputStreams.getStreamIds()) {
6496 sp<Camera3StreamInterface> stream = mOutputStreams.get(streamId);
6497 ret = stream->disconnect();
6498 if (ret != OK) {
6499 SET_ERR_L("disconnect output stream %d failed!", streamId);
6500 return UNKNOWN_ERROR;
6501 }
6502 }
6503
6504 mInputStream.clear();
6505 mOutputStreams.clear();
6506 mNeedConfig = true;
6507 internalUpdateStatusLocked(STATUS_UNCONFIGURED);
6508 mOperatingMode = NO_MODE;
6509 mIsConstrainedHighSpeedConfiguration = false;
6510 mRequestThread->clearPreviousRequest();
6511
6512 return OK;
6513 // TO be done by CameraDeviceClient/Camera3OfflineSession
6514 // register the offline client to camera service
6515 // Setup result passthing threads etc
6516 // Initialize offline session so HAL can start sending callback to it (result Fmq)
6517 // TODO: check how many onIdle callback will be sent
6518 // Java side to make sure the CameraCaptureSession is properly closed
6519 }
6520
getOfflineStreamIds(std::vector<int> * offlineStreamIds)6521 void Camera3Device::getOfflineStreamIds(std::vector<int> *offlineStreamIds) {
6522 ATRACE_CALL();
6523
6524 if (offlineStreamIds == nullptr) {
6525 return;
6526 }
6527
6528 Mutex::Autolock il(mInterfaceLock);
6529
6530 auto streamIds = mOutputStreams.getStreamIds();
6531 bool hasInputStream = mInputStream != nullptr;
6532 if (hasInputStream && mInputStream->getOfflineProcessingSupport()) {
6533 offlineStreamIds->push_back(mInputStream->getId());
6534 }
6535
6536 for (const auto & streamId : streamIds) {
6537 sp<camera3::Camera3OutputStreamInterface> stream = mOutputStreams.get(streamId);
6538 // Streams that use the camera buffer manager are currently not supported in
6539 // offline mode
6540 if (stream->getOfflineProcessingSupport() &&
6541 (stream->getStreamSetId() == CAMERA3_STREAM_SET_ID_INVALID)) {
6542 offlineStreamIds->push_back(streamId);
6543 }
6544 }
6545 }
6546
setRotateAndCropAutoBehavior(camera_metadata_enum_android_scaler_rotate_and_crop_t rotateAndCropValue)6547 status_t Camera3Device::setRotateAndCropAutoBehavior(
6548 camera_metadata_enum_android_scaler_rotate_and_crop_t rotateAndCropValue) {
6549 ATRACE_CALL();
6550 Mutex::Autolock il(mInterfaceLock);
6551 Mutex::Autolock l(mLock);
6552 if (mRequestThread == nullptr) {
6553 return INVALID_OPERATION;
6554 }
6555 return mRequestThread->setRotateAndCropAutoBehavior(rotateAndCropValue);
6556 }
6557
supportsCameraMute()6558 bool Camera3Device::supportsCameraMute() {
6559 Mutex::Autolock il(mInterfaceLock);
6560 Mutex::Autolock l(mLock);
6561
6562 return mSupportCameraMute;
6563 }
6564
setCameraMute(bool enabled)6565 status_t Camera3Device::setCameraMute(bool enabled) {
6566 ATRACE_CALL();
6567 Mutex::Autolock il(mInterfaceLock);
6568 Mutex::Autolock l(mLock);
6569
6570 if (mRequestThread == nullptr || !mSupportCameraMute) {
6571 return INVALID_OPERATION;
6572 }
6573 int32_t muteMode =
6574 !enabled ? ANDROID_SENSOR_TEST_PATTERN_MODE_OFF :
6575 mSupportTestPatternSolidColor ? ANDROID_SENSOR_TEST_PATTERN_MODE_SOLID_COLOR :
6576 ANDROID_SENSOR_TEST_PATTERN_MODE_BLACK;
6577 return mRequestThread->setCameraMute(muteMode);
6578 }
6579
injectCamera(const String8 & injectedCamId,sp<CameraProviderManager> manager)6580 status_t Camera3Device::injectCamera(const String8& injectedCamId,
6581 sp<CameraProviderManager> manager) {
6582 ALOGI("%s Injection camera: injectedCamId = %s", __FUNCTION__, injectedCamId.string());
6583 ATRACE_CALL();
6584 Mutex::Autolock il(mInterfaceLock);
6585
6586 status_t res = NO_ERROR;
6587 if (mInjectionMethods->isInjecting()) {
6588 if (injectedCamId == mInjectionMethods->getInjectedCamId()) {
6589 return OK;
6590 } else {
6591 res = mInjectionMethods->stopInjection();
6592 if (res != OK) {
6593 ALOGE("%s: Failed to stop the injection camera! ret != NO_ERROR: %d",
6594 __FUNCTION__, res);
6595 return res;
6596 }
6597 }
6598 }
6599
6600 res = mInjectionMethods->injectionInitialize(injectedCamId, manager, this);
6601 if (res != OK) {
6602 ALOGE("%s: Failed to initialize the injection camera! ret != NO_ERROR: %d",
6603 __FUNCTION__, res);
6604 return res;
6605 }
6606
6607 camera3::camera_stream_configuration injectionConfig;
6608 std::vector<uint32_t> injectionBufferSizes;
6609 mInjectionMethods->getInjectionConfig(&injectionConfig, &injectionBufferSizes);
6610 // When the second display of android is cast to the remote device, and the opened camera is
6611 // also cast to the second display, in this case, because the camera has configured the streams
6612 // at this time, we can directly call injectCamera() to replace the internal camera with
6613 // injection camera.
6614 if (mOperatingMode >= 0 && injectionConfig.num_streams > 0
6615 && injectionBufferSizes.size() > 0) {
6616 ALOGV("%s: The opened camera is directly cast to the remote device.", __FUNCTION__);
6617 res = mInjectionMethods->injectCamera(
6618 injectionConfig, injectionBufferSizes);
6619 if (res != OK) {
6620 ALOGE("Can't finish inject camera process!");
6621 return res;
6622 }
6623 }
6624
6625 return OK;
6626 }
6627
stopInjection()6628 status_t Camera3Device::stopInjection() {
6629 ALOGI("%s: Injection camera: stopInjection", __FUNCTION__);
6630 Mutex::Autolock il(mInterfaceLock);
6631 return mInjectionMethods->stopInjection();
6632 }
6633
6634 }; // namespace android
6635