1 /*
2 * Copyright (C) 2022 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 "AidlCamera3-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.c_str(), __FUNCTION__, \
30 ##__VA_ARGS__)
31
32 #define CLOGW(fmt, ...) ALOGW("Camera %s: %s: " fmt, mId.c_str(), __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 <aidl/android/hardware/camera/device/ICameraDeviceSession.h>
53 #include <aidl/android/hardware/camera/device/ICameraInjectionSession.h>
54 #include <aidlcommonsupport/NativeHandle.h>
55 #include <android-base/properties.h>
56 #include <android/binder_ibinder_platform.h>
57 #include <android/hardware/camera2/ICameraDeviceUser.h>
58 #include <camera/StringUtils.h>
59 #include <com_android_internal_camera_flags.h>
60
61 #include "utils/CameraTraces.h"
62 #include "utils/SessionConfigurationUtils.h"
63 #include "mediautils/SchedulingPolicyService.h"
64 #include "device3/Camera3OutputStream.h"
65 #include "device3/Camera3InputStream.h"
66 #include "device3/Camera3FakeStream.h"
67 #include "device3/Camera3SharedOutputStream.h"
68 #include "device3/aidl/AidlCamera3OutputUtils.h"
69 #include "device3/aidl/AidlCamera3OfflineSession.h"
70 #include "CameraService.h"
71 #include "utils/SessionConfigurationUtils.h"
72 #include "utils/TraceHFR.h"
73 #include "utils/CameraServiceProxyWrapper.h"
74
75 #include "../../common/aidl/AidlProviderInfo.h"
76
77 #include <algorithm>
78
79 #include "AidlCamera3Device.h"
80
81 using namespace android::camera3;
82 using namespace android::camera3::SessionConfigurationUtils;
83 using namespace aidl::android::hardware;
84 using aidl::android::hardware::camera::metadata::SensorPixelMode;
85 using aidl::android::hardware::camera::metadata::RequestAvailableDynamicRangeProfilesMap;
86 using aidl::android::hardware::camera::metadata::ScalerAvailableStreamUseCases;
87
88 namespace flags = com::android::internal::camera::flags;
89
90 const int32_t AIDL_DEVICE_SESSION_V3 = 3;
91 namespace android {
92
93 RequestAvailableDynamicRangeProfilesMap
mapToAidlDynamicProfile(int64_t dynamicRangeProfile)94 mapToAidlDynamicProfile(int64_t dynamicRangeProfile) {
95 return static_cast<RequestAvailableDynamicRangeProfilesMap>(dynamicRangeProfile);
96 }
97
mapToAidlPixelFormat(int frameworkFormat)98 aidl::android::hardware::graphics::common::PixelFormat AidlCamera3Device::mapToAidlPixelFormat(
99 int frameworkFormat) {
100 return (aidl::android::hardware::graphics::common::PixelFormat) frameworkFormat;
101 }
102
mapToAidlDataspace(android_dataspace dataSpace)103 aidl::android::hardware::graphics::common::Dataspace AidlCamera3Device::mapToAidlDataspace(
104 android_dataspace dataSpace) {
105 return (aidl::android::hardware::graphics::common::Dataspace)dataSpace;
106 }
107
mapToAidlConsumerUsage(uint64_t usage)108 aidl::android::hardware::graphics::common::BufferUsage AidlCamera3Device::mapToAidlConsumerUsage(
109 uint64_t usage) {
110 return (aidl::android::hardware::graphics::common::BufferUsage)usage;
111 }
112
113 aidl::android::hardware::camera::device::StreamRotation
mapToAidlStreamRotation(camera_stream_rotation_t rotation)114 AidlCamera3Device::mapToAidlStreamRotation(camera_stream_rotation_t rotation) {
115 switch (rotation) {
116 case CAMERA_STREAM_ROTATION_0:
117 return aidl::android::hardware::camera::device::StreamRotation::ROTATION_0;
118 case CAMERA_STREAM_ROTATION_90:
119 return aidl::android::hardware::camera::device::StreamRotation::ROTATION_90;
120 case CAMERA_STREAM_ROTATION_180:
121 return aidl::android::hardware::camera::device::StreamRotation::ROTATION_180;
122 case CAMERA_STREAM_ROTATION_270:
123 return aidl::android::hardware::camera::device::StreamRotation::ROTATION_270;
124 }
125 ALOGE("%s: Unknown stream rotation %d", __FUNCTION__, rotation);
126 return aidl::android::hardware::camera::device::StreamRotation::ROTATION_0;
127 }
128
mapToAidlStreamConfigurationMode(camera_stream_configuration_mode_t operationMode,aidl::android::hardware::camera::device::StreamConfigurationMode * mode)129 status_t AidlCamera3Device::mapToAidlStreamConfigurationMode(
130 camera_stream_configuration_mode_t operationMode,
131 aidl::android::hardware::camera::device::StreamConfigurationMode *mode) {
132 using StreamConfigurationMode =
133 aidl::android::hardware::camera::device::StreamConfigurationMode;
134 if (mode == nullptr) return BAD_VALUE;
135 if (operationMode < CAMERA_VENDOR_STREAM_CONFIGURATION_MODE_START) {
136 switch(operationMode) {
137 case CAMERA_STREAM_CONFIGURATION_NORMAL_MODE:
138 *mode = StreamConfigurationMode::NORMAL_MODE;
139 break;
140 case CAMERA_STREAM_CONFIGURATION_CONSTRAINED_HIGH_SPEED_MODE:
141 *mode = StreamConfigurationMode::CONSTRAINED_HIGH_SPEED_MODE;
142 break;
143 default:
144 ALOGE("%s: Unknown stream configuration mode %d", __FUNCTION__, operationMode);
145 return BAD_VALUE;
146 }
147 } else {
148 *mode = static_cast<StreamConfigurationMode>(operationMode);
149 }
150 return OK;
151 }
152
mapToFrameworkFormat(aidl::android::hardware::graphics::common::PixelFormat pixelFormat)153 int AidlCamera3Device::mapToFrameworkFormat(
154 aidl::android::hardware::graphics::common::PixelFormat pixelFormat) {
155 return static_cast<uint32_t>(pixelFormat);
156 }
157
mapToFrameworkDataspace(aidl::android::hardware::graphics::common::Dataspace dataSpace)158 android_dataspace AidlCamera3Device::mapToFrameworkDataspace(
159 aidl::android::hardware::graphics::common::Dataspace dataSpace) {
160 return static_cast<android_dataspace>(dataSpace);
161 }
162
mapConsumerToFrameworkUsage(aidl::android::hardware::graphics::common::BufferUsage usage)163 uint64_t AidlCamera3Device::mapConsumerToFrameworkUsage(
164 aidl::android::hardware::graphics::common::BufferUsage usage) {
165 return (uint64_t)usage;
166 }
167
mapProducerToFrameworkUsage(aidl::android::hardware::graphics::common::BufferUsage usage)168 uint64_t AidlCamera3Device::mapProducerToFrameworkUsage(
169 aidl::android::hardware::graphics::common::BufferUsage usage) {
170 return (uint64_t)usage;
171 }
172
AidlCamera3Device(std::shared_ptr<CameraServiceProxyWrapper> & cameraServiceProxyWrapper,std::shared_ptr<AttributionAndPermissionUtils> attributionAndPermissionUtils,const std::string & id,bool overrideForPerfClass,int rotationOverride,bool legacyClient)173 AidlCamera3Device::AidlCamera3Device(
174 std::shared_ptr<CameraServiceProxyWrapper>& cameraServiceProxyWrapper,
175 std::shared_ptr<AttributionAndPermissionUtils> attributionAndPermissionUtils,
176 const std::string& id, bool overrideForPerfClass, int rotationOverride,
177 bool legacyClient) :
178 Camera3Device(cameraServiceProxyWrapper, attributionAndPermissionUtils, id,
179 overrideForPerfClass, rotationOverride, legacyClient) {
180 mCallbacks = ndk::SharedRefBase::make<AidlCameraDeviceCallbacks>(this);
181 }
182
initialize(sp<CameraProviderManager> manager,const std::string & monitorTags)183 status_t AidlCamera3Device::initialize(sp<CameraProviderManager> manager,
184 const std::string& monitorTags) {
185 ATRACE_CALL();
186 Mutex::Autolock il(mInterfaceLock);
187 Mutex::Autolock l(mLock);
188
189 ALOGV("%s: Initializing AIDL device for camera %s", __FUNCTION__, mId.c_str());
190 if (mStatus != STATUS_UNINITIALIZED) {
191 CLOGE("Already initialized!");
192 return INVALID_OPERATION;
193 }
194 if (manager == nullptr) return INVALID_OPERATION;
195
196 std::shared_ptr<camera::device::ICameraDeviceSession> session;
197 ATRACE_BEGIN("CameraHal::openSession");
198 status_t res = manager->openAidlSession(mId, mCallbacks,
199 /*out*/ &session);
200 ATRACE_END();
201 if (res != OK) {
202 SET_ERR_L("Could not open camera session: %s (%d)", strerror(-res), res);
203 return res;
204 }
205 if (session == nullptr) {
206 SET_ERR("Session iface returned is null");
207 return INVALID_OPERATION;
208 }
209 res = manager->getCameraCharacteristics(mId, mOverrideForPerfClass, &mDeviceInfo,
210 mRotationOverride);
211 if (res != OK) {
212 SET_ERR_L("Could not retrieve camera characteristics: %s (%d)", strerror(-res), res);
213 session->close();
214 return res;
215 }
216 mSupportNativeZoomRatio = manager->supportNativeZoomRatio(mId);
217 mIsCompositeJpegRDisabled = manager->isCompositeJpegRDisabled(mId);
218
219 std::vector<std::string> physicalCameraIds;
220 bool isLogical = manager->isLogicalCamera(mId, &physicalCameraIds);
221 if (isLogical) {
222 for (auto& physicalId : physicalCameraIds) {
223 // Do not override characteristics for physical cameras
224 res = manager->getCameraCharacteristics(
225 physicalId, /*overrideForPerfClass*/false, &mPhysicalDeviceInfoMap[physicalId],
226 mRotationOverride);
227 if (res != OK) {
228 SET_ERR_L("Could not retrieve camera %s characteristics: %s (%d)",
229 physicalId.c_str(), strerror(-res), res);
230 session->close();
231 return res;
232 }
233
234 bool usePrecorrectArray =
235 DistortionMapper::isDistortionSupported(mPhysicalDeviceInfoMap[physicalId]);
236 if (usePrecorrectArray) {
237 res = mDistortionMappers[physicalId].setupStaticInfo(
238 mPhysicalDeviceInfoMap[physicalId]);
239 if (res != OK) {
240 SET_ERR_L("Unable to read camera %s's calibration fields for distortion "
241 "correction", physicalId.c_str());
242 session->close();
243 return res;
244 }
245 }
246
247 mZoomRatioMappers[physicalId] = ZoomRatioMapper(
248 &mPhysicalDeviceInfoMap[physicalId],
249 mSupportNativeZoomRatio, usePrecorrectArray);
250
251 if (SessionConfigurationUtils::supportsUltraHighResolutionCapture(
252 mPhysicalDeviceInfoMap[physicalId])) {
253 mUHRCropAndMeteringRegionMappers[physicalId] =
254 UHRCropAndMeteringRegionMapper(mPhysicalDeviceInfoMap[physicalId],
255 usePrecorrectArray);
256 }
257 }
258 }
259
260 std::shared_ptr<AidlRequestMetadataQueue> queue;
261 ::aidl::android::hardware::common::fmq::MQDescriptor<
262 int8_t, ::aidl::android::hardware::common::fmq::SynchronizedReadWrite> desc;
263
264 ::ndk::ScopedAStatus requestQueueRet = session->getCaptureRequestMetadataQueue(&desc);
265 if (!requestQueueRet.isOk()) {
266 ALOGE("Transaction error when getting result metadata queue from camera session: %s",
267 requestQueueRet.getMessage());
268 return AidlProviderInfo::mapToStatusT(requestQueueRet);
269 }
270 queue = std::make_unique<AidlRequestMetadataQueue>(desc);
271 if (!queue->isValid() || queue->availableToWrite() <= 0) {
272 ALOGE("HAL returns empty result metadata fmq, not use it");
273 queue = nullptr;
274 // Don't use resQueue onwards.
275 }
276
277 std::unique_ptr<AidlResultMetadataQueue>& resQueue = mResultMetadataQueue;
278 ::aidl::android::hardware::common::fmq::MQDescriptor<
279 int8_t, ::aidl::android::hardware::common::fmq::SynchronizedReadWrite> resDesc;
280 ::ndk::ScopedAStatus resultQueueRet = session->getCaptureResultMetadataQueue(&resDesc);
281 if (!resultQueueRet.isOk()) {
282 ALOGE("Transaction error when getting result metadata queue from camera session: %s",
283 resultQueueRet.getMessage());
284 return AidlProviderInfo::mapToStatusT(resultQueueRet);
285 }
286 resQueue = std::make_unique<AidlResultMetadataQueue>(resDesc);
287 if (!resQueue->isValid() || resQueue->availableToWrite() <= 0) {
288 ALOGE("HAL returns empty result metadata fmq, not use it");
289 resQueue = nullptr;
290 // Don't use resQueue onwards.
291 }
292
293 camera_metadata_entry bufMgrMode =
294 mDeviceInfo.find(ANDROID_INFO_SUPPORTED_BUFFER_MANAGEMENT_VERSION);
295 if (bufMgrMode.count > 0) {
296 mUseHalBufManager = (bufMgrMode.data.u8[0] ==
297 ANDROID_INFO_SUPPORTED_BUFFER_MANAGEMENT_VERSION_HIDL_DEVICE_3_5);
298 mSessionHalBufManager = (bufMgrMode.data.u8[0] ==
299 ANDROID_INFO_SUPPORTED_BUFFER_MANAGEMENT_VERSION_SESSION_CONFIGURABLE);
300 }
301
302 camera_metadata_entry_t capabilities = mDeviceInfo.find(ANDROID_REQUEST_AVAILABLE_CAPABILITIES);
303 for (size_t i = 0; i < capabilities.count; i++) {
304 uint8_t capability = capabilities.data.u8[i];
305 if (capability == ANDROID_REQUEST_AVAILABLE_CAPABILITIES_OFFLINE_PROCESSING) {
306 mSupportOfflineProcessing = true;
307 }
308 }
309
310 mInterface =
311 new AidlHalInterface(session, queue, mUseHalBufManager, mSupportOfflineProcessing,
312 mSessionHalBufManager);
313
314 std::string providerType;
315 mVendorTagId = manager->getProviderTagIdLocked(mId);
316 mTagMonitor.initialize(mVendorTagId);
317 if (!monitorTags.empty()) {
318 mTagMonitor.parseTagsToMonitor(monitorTags);
319 }
320
321 for (size_t i = 0; i < capabilities.count; i++) {
322 uint8_t capability = capabilities.data.u8[i];
323 if (capability == ANDROID_REQUEST_AVAILABLE_CAPABILITIES_MONOCHROME) {
324 mNeedFixupMonochromeTags = true;
325 }
326 }
327
328 // batch size limit is applied to the device with camera device version larger than 3.2 which is
329 // AIDL v2
330 hardware::hidl_version maxVersion{0, 0};
331 IPCTransport transport = IPCTransport::AIDL;
332 res = manager->getHighestSupportedVersion(mId, &maxVersion, &transport);
333 if (res != OK) {
334 ALOGE("%s: Error in getting camera device version id: %s (%d)", __FUNCTION__,
335 strerror(-res), res);
336 return res;
337 }
338 int deviceVersion = HARDWARE_DEVICE_API_VERSION(maxVersion.get_major(), maxVersion.get_minor());
339
340 mBatchSizeLimitEnabled = (deviceVersion >= CAMERA_DEVICE_API_VERSION_1_2);
341
342 camera_metadata_entry readoutSupported = mDeviceInfo.find(ANDROID_SENSOR_READOUT_TIMESTAMP);
343 if (readoutSupported.count == 0) {
344 ALOGW("%s: Could not find value corresponding to ANDROID_SENSOR_READOUT_TIMESTAMP. "
345 "Assuming true.", __FUNCTION__);
346 mSensorReadoutTimestampSupported = true;
347 } else {
348 mSensorReadoutTimestampSupported =
349 readoutSupported.data.u8[0] == ANDROID_SENSOR_READOUT_TIMESTAMP_HARDWARE;
350 }
351
352 return initializeCommonLocked(manager);
353 }
354
processCaptureResult(const std::vector<camera::device::CaptureResult> & results)355 ::ndk::ScopedAStatus AidlCamera3Device::AidlCameraDeviceCallbacks::processCaptureResult(
356 const std::vector<camera::device::CaptureResult>& results) {
357 sp<AidlCamera3Device> p = mParent.promote();
358 if (p == nullptr) {
359 ALOGE("%s Parent AidlCameraDevice not alive, can't process callbacks", __FUNCTION__);
360 return ::ndk::ScopedAStatus::ok();
361 }
362 return p->processCaptureResult(results);
363 }
364
notify(const std::vector<camera::device::NotifyMsg> & msgs)365 ::ndk::ScopedAStatus AidlCamera3Device::AidlCameraDeviceCallbacks::notify(
366 const std::vector<camera::device::NotifyMsg>& msgs) {
367 sp<AidlCamera3Device> p = mParent.promote();
368 if (p == nullptr) {
369 ALOGE("%s Parent AidlCameraDevice not alive, can't process callbacks", __FUNCTION__);
370 return ::ndk::ScopedAStatus::ok();
371 }
372 return p->notify(msgs);
373 }
374
processCaptureResult(const std::vector<camera::device::CaptureResult> & results)375 ::ndk::ScopedAStatus AidlCamera3Device::processCaptureResult(
376 const std::vector<camera::device::CaptureResult>& results) {
377 // Ideally we should grab mLock, but that can lead to deadlock, and
378 // it's not super important to get up to date value of mStatus for this
379 // warning print, hence skipping the lock here
380 if (mStatus == STATUS_ERROR) {
381 // Per API contract, HAL should act as closed after device error
382 // But mStatus can be set to error by framework as well, so just log
383 // a warning here.
384 ALOGW("%s: received capture result in error state.", __FUNCTION__);
385 }
386
387 sp<NotificationListener> listener;
388 {
389 std::lock_guard<std::mutex> l(mOutputLock);
390 listener = mListener.promote();
391 }
392
393 if (mProcessCaptureResultLock.tryLock() != OK) {
394 // This should never happen; it indicates a wrong client implementation
395 // that doesn't follow the contract. But, we can be tolerant here.
396 ALOGE("%s: callback overlapped! waiting 1s...",
397 __FUNCTION__);
398 if (mProcessCaptureResultLock.timedLock(1000000000 /* 1s */) != OK) {
399 ALOGE("%s: cannot acquire lock in 1s, dropping results",
400 __FUNCTION__);
401 // really don't know what to do, so bail out.
402 return ::ndk::ScopedAStatus::ok();
403 }
404 }
405 AidlCaptureOutputStates states {
406 {
407 mId,
408 mInFlightLock, mLastCompletedRegularFrameNumber,
409 mLastCompletedReprocessFrameNumber, mLastCompletedZslFrameNumber,
410 mInFlightMap, mOutputLock, mResultQueue, mResultSignal,
411 mNextShutterFrameNumber,
412 mNextReprocessShutterFrameNumber, mNextZslStillShutterFrameNumber,
413 mNextResultFrameNumber,
414 mNextReprocessResultFrameNumber, mNextZslStillResultFrameNumber,
415 mUseHalBufManager, mHalBufManagedStreamIds, mUsePartialResult, mNeedFixupMonochromeTags,
416 mNumPartialResults, mVendorTagId, mDeviceInfo, mPhysicalDeviceInfoMap,
417 mDistortionMappers, mZoomRatioMappers, mRotateAndCropMappers,
418 mTagMonitor, mInputStream, mOutputStreams, mSessionStatsBuilder, listener, *this,
419 *this, *(mInterface), mLegacyClient, mMinExpectedDuration, mIsFixedFps,
420 mRotationOverride, mActivePhysicalId}, mResultMetadataQueue
421 };
422
423 for (const auto& result : results) {
424 processOneCaptureResultLocked(states, result, result.physicalCameraMetadata);
425 }
426 mProcessCaptureResultLock.unlock();
427 return ::ndk::ScopedAStatus::ok();
428 }
429
notify(const std::vector<camera::device::NotifyMsg> & msgs)430 ::ndk::ScopedAStatus AidlCamera3Device::notify(
431 const std::vector<camera::device::NotifyMsg>& msgs) {
432 // Ideally we should grab mLock, but that can lead to deadlock, and
433 // it's not super important to get up to date value of mStatus for this
434 // warning print, hence skipping the lock here
435 if (mStatus == STATUS_ERROR) {
436 // Per API contract, HAL should act as closed after device error
437 // But mStatus can be set to error by framework as well, so just log
438 // a warning here.
439 ALOGW("%s: received notify message in error state.", __FUNCTION__);
440 }
441
442 sp<NotificationListener> listener;
443 {
444 std::lock_guard<std::mutex> l(mOutputLock);
445 listener = mListener.promote();
446 }
447
448 AidlCaptureOutputStates states {
449 { mId,
450 mInFlightLock, mLastCompletedRegularFrameNumber,
451 mLastCompletedReprocessFrameNumber, mLastCompletedZslFrameNumber,
452 mInFlightMap, mOutputLock, mResultQueue, mResultSignal,
453 mNextShutterFrameNumber,
454 mNextReprocessShutterFrameNumber, mNextZslStillShutterFrameNumber,
455 mNextResultFrameNumber,
456 mNextReprocessResultFrameNumber, mNextZslStillResultFrameNumber,
457 mUseHalBufManager, mHalBufManagedStreamIds, mUsePartialResult, mNeedFixupMonochromeTags,
458 mNumPartialResults, mVendorTagId, mDeviceInfo, mPhysicalDeviceInfoMap,
459 mDistortionMappers, mZoomRatioMappers, mRotateAndCropMappers,
460 mTagMonitor, mInputStream, mOutputStreams, mSessionStatsBuilder, listener, *this,
461 *this, *(mInterface), mLegacyClient, mMinExpectedDuration, mIsFixedFps,
462 mRotationOverride, mActivePhysicalId}, mResultMetadataQueue
463 };
464 for (const auto& msg : msgs) {
465 camera3::notify(states, msg, mSensorReadoutTimestampSupported);
466 }
467 return ::ndk::ScopedAStatus::ok();
468
469 }
470
switchToOffline(const std::vector<int32_t> & streamsToKeep,sp<CameraOfflineSessionBase> * session)471 status_t AidlCamera3Device::switchToOffline(
472 const std::vector<int32_t>& streamsToKeep,
473 /*out*/ sp<CameraOfflineSessionBase>* session) {
474 ATRACE_CALL();
475 if (session == nullptr) {
476 ALOGE("%s: session must not be null", __FUNCTION__);
477 return BAD_VALUE;
478 }
479
480 Mutex::Autolock il(mInterfaceLock);
481
482 bool hasInputStream = mInputStream != nullptr;
483 int32_t inputStreamId = hasInputStream ? mInputStream->getId() : -1;
484 bool inputStreamSupportsOffline = hasInputStream ?
485 mInputStream->getOfflineProcessingSupport() : false;
486 auto outputStreamIds = mOutputStreams.getStreamIds();
487 auto streamIds = outputStreamIds;
488 if (hasInputStream) {
489 streamIds.push_back(mInputStream->getId());
490 }
491
492 // Check all streams in streamsToKeep supports offline mode
493 for (auto id : streamsToKeep) {
494 if (std::find(streamIds.begin(), streamIds.end(), id) == streamIds.end()) {
495 ALOGE("%s: Unknown stream ID %d", __FUNCTION__, id);
496 return BAD_VALUE;
497 } else if (id == inputStreamId) {
498 if (!inputStreamSupportsOffline) {
499 ALOGE("%s: input stream %d cannot be switched to offline",
500 __FUNCTION__, id);
501 return BAD_VALUE;
502 }
503 } else {
504 sp<camera3::Camera3OutputStreamInterface> stream = mOutputStreams.get(id);
505 if (!stream->getOfflineProcessingSupport()) {
506 ALOGE("%s: output stream %d cannot be switched to offline",
507 __FUNCTION__, id);
508 return BAD_VALUE;
509 }
510 }
511 }
512 // TODO: block surface sharing and surface group streams until we can support them
513
514 // Stop repeating request, wait until all remaining requests are submitted, then call into
515 // HAL switchToOffline
516 camera::device::CameraOfflineSessionInfo offlineSessionInfo;
517 std::shared_ptr<camera::device::ICameraOfflineSession> offlineSession;
518 camera3::BufferRecords bufferRecords;
519 status_t ret = static_cast<AidlRequestThread *>(mRequestThread.get())->switchToOffline(
520 streamsToKeep, &offlineSessionInfo, &offlineSession, &bufferRecords);
521
522 if (ret != OK) {
523 SET_ERR("Switch to offline failed: %s (%d)", strerror(-ret), ret);
524 return ret;
525 }
526
527 bool succ = mRequestBufferSM.onSwitchToOfflineSuccess();
528 if (!succ) {
529 SET_ERR("HAL must not be calling requestStreamBuffers call");
530 // TODO: block ALL callbacks from HAL till app configured new streams?
531 return UNKNOWN_ERROR;
532 }
533
534 // Verify offlineSessionInfo
535 std::vector<int32_t> offlineStreamIds;
536 offlineStreamIds.reserve(offlineSessionInfo.offlineStreams.size());
537 for (auto offlineStream : offlineSessionInfo.offlineStreams) {
538 // verify stream IDs
539 int32_t id = offlineStream.id;
540 if (std::find(streamIds.begin(), streamIds.end(), id) == streamIds.end()) {
541 SET_ERR("stream ID %d not found!", id);
542 return UNKNOWN_ERROR;
543 }
544
545 // When not using HAL buf manager, only allow streams requested by app to be preserved
546 if (!isHalBufferManagedStream(id)) {
547 if (std::find(streamsToKeep.begin(), streamsToKeep.end(), id) == streamsToKeep.end()) {
548 SET_ERR("stream ID %d must not be switched to offline!", id);
549 return UNKNOWN_ERROR;
550 }
551 }
552
553 offlineStreamIds.push_back(id);
554 sp<Camera3StreamInterface> stream = (id == inputStreamId) ?
555 static_cast<sp<Camera3StreamInterface>>(mInputStream) :
556 static_cast<sp<Camera3StreamInterface>>(mOutputStreams.get(id));
557 // Verify number of outstanding buffers
558 if (stream->getOutstandingBuffersCount() != (uint32_t)offlineStream.numOutstandingBuffers) {
559 SET_ERR("Offline stream %d # of remaining buffer mismatch: (%zu,%d) (service/HAL)",
560 id, stream->getOutstandingBuffersCount(), offlineStream.numOutstandingBuffers);
561 return UNKNOWN_ERROR;
562 }
563 }
564
565 // Verify all streams to be deleted don't have any outstanding buffers
566 if (hasInputStream && std::find(offlineStreamIds.begin(), offlineStreamIds.end(),
567 inputStreamId) == offlineStreamIds.end()) {
568 if (mInputStream->hasOutstandingBuffers()) {
569 SET_ERR("Input stream %d still has %zu outstanding buffer!",
570 inputStreamId, mInputStream->getOutstandingBuffersCount());
571 return UNKNOWN_ERROR;
572 }
573 }
574
575 for (const auto& outStreamId : outputStreamIds) {
576 if (std::find(offlineStreamIds.begin(), offlineStreamIds.end(),
577 outStreamId) == offlineStreamIds.end()) {
578 auto outStream = mOutputStreams.get(outStreamId);
579 if (outStream->hasOutstandingBuffers()) {
580 SET_ERR("Output stream %d still has %zu outstanding buffer!",
581 outStreamId, outStream->getOutstandingBuffersCount());
582 return UNKNOWN_ERROR;
583 }
584 }
585 }
586
587 InFlightRequestMap offlineReqs;
588 // Verify inflight requests and their pending buffers
589 {
590 std::lock_guard<std::mutex> l(mInFlightLock);
591 for (auto offlineReq : offlineSessionInfo.offlineRequests) {
592 int idx = mInFlightMap.indexOfKey(offlineReq.frameNumber);
593 if (idx == NAME_NOT_FOUND) {
594 SET_ERR("Offline request frame number %d not found!", offlineReq.frameNumber);
595 return UNKNOWN_ERROR;
596 }
597
598 const auto& inflightReq = mInFlightMap.valueAt(idx);
599 // TODO: check specific stream IDs
600 size_t numBuffersLeft = static_cast<size_t>(inflightReq.numBuffersLeft);
601 if (numBuffersLeft != offlineReq.pendingStreams.size()) {
602 SET_ERR("Offline request # of remaining buffer mismatch: (%d,%d) (service/HAL)",
603 inflightReq.numBuffersLeft, offlineReq.pendingStreams.size());
604 return UNKNOWN_ERROR;
605 }
606 offlineReqs.add(offlineReq.frameNumber, inflightReq);
607 }
608 }
609
610 // Create Camera3OfflineSession and transfer object ownership
611 // (streams, inflight requests, buffer caches)
612 camera3::StreamSet offlineStreamSet;
613 sp<camera3::Camera3Stream> inputStream;
614 for (auto offlineStream : offlineSessionInfo.offlineStreams) {
615 int32_t id = offlineStream.id;
616 if (mInputStream != nullptr && id == mInputStream->getId()) {
617 inputStream = mInputStream;
618 } else {
619 offlineStreamSet.add(id, mOutputStreams.get(id));
620 }
621 }
622
623 // TODO: check if we need to lock before copying states
624 // though technically no other thread should be talking to Camera3Device at this point
625 Camera3OfflineStates offlineStates(
626 mTagMonitor, mVendorTagId, mUseHalBufManager, mHalBufManagedStreamIds,
627 mNeedFixupMonochromeTags, mUsePartialResult, mNumPartialResults,
628 mLastCompletedRegularFrameNumber, mLastCompletedReprocessFrameNumber,
629 mLastCompletedZslFrameNumber, mNextResultFrameNumber,
630 mNextReprocessResultFrameNumber, mNextZslStillResultFrameNumber,
631 mNextShutterFrameNumber, mNextReprocessShutterFrameNumber,
632 mNextZslStillShutterFrameNumber, mDeviceInfo, mPhysicalDeviceInfoMap,
633 mDistortionMappers, mZoomRatioMappers, mRotateAndCropMappers);
634
635 *session = new AidlCamera3OfflineSession(mId, inputStream, offlineStreamSet,
636 std::move(bufferRecords), offlineReqs, offlineStates,
637 offlineSession, mSensorReadoutTimestampSupported);
638
639 // Delete all streams that has been transferred to offline session
640 Mutex::Autolock l(mLock);
641 for (auto offlineStream : offlineSessionInfo.offlineStreams) {
642 int32_t id = offlineStream.id;
643 if (mInputStream != nullptr && id == mInputStream->getId()) {
644 mInputStream.clear();
645 } else {
646 mOutputStreams.remove(id);
647 }
648 }
649
650 // disconnect all other streams and switch to UNCONFIGURED state
651 if (mInputStream != nullptr) {
652 ret = mInputStream->disconnect();
653 if (ret != OK) {
654 SET_ERR_L("disconnect input stream failed!");
655 return UNKNOWN_ERROR;
656 }
657 }
658
659 for (auto streamId : mOutputStreams.getStreamIds()) {
660 sp<Camera3StreamInterface> stream = mOutputStreams.get(streamId);
661 ret = stream->disconnect();
662 if (ret != OK) {
663 SET_ERR_L("disconnect output stream %d failed!", streamId);
664 return UNKNOWN_ERROR;
665 }
666 }
667
668 mInputStream.clear();
669 mOutputStreams.clear();
670 mNeedConfig = true;
671 internalUpdateStatusLocked(STATUS_UNCONFIGURED);
672 mOperatingMode = NO_MODE;
673 mIsConstrainedHighSpeedConfiguration = false;
674 mRequestThread->clearPreviousRequest();
675
676 return OK;
677 // TO be done by CameraDeviceClient/Camera3OfflineSession
678 // register the offline client to camera service
679 // Setup result passthing threads etc
680 // Initialize offline session so HAL can start sending callback to it (result Fmq)
681 // TODO: check how many onIdle callback will be sent
682 // Java side to make sure the CameraCaptureSession is properly closed
683 }
684
requestStreamBuffers(const std::vector<camera::device::BufferRequest> & bufReqs,std::vector<aidl::android::hardware::camera::device::StreamBufferRet> * outBuffers,aidl::android::hardware::camera::device::BufferRequestStatus * status)685 ::ndk::ScopedAStatus AidlCamera3Device::AidlCameraDeviceCallbacks::requestStreamBuffers(
686 const std::vector<camera::device::BufferRequest>& bufReqs,
687 std::vector<aidl::android::hardware::camera::device::StreamBufferRet>* outBuffers,
688 aidl::android::hardware::camera::device::BufferRequestStatus* status) {
689
690 sp<AidlCamera3Device> p = mParent.promote();
691 if (p == nullptr) {
692 ALOGE("%s Parent AidlCameraDevice not alive, can't process callbacks", __FUNCTION__);
693 return ::ndk::ScopedAStatus::ok();
694 }
695 return p->requestStreamBuffers(bufReqs, outBuffers, status);
696 }
697
requestStreamBuffers(const std::vector<camera::device::BufferRequest> & bufReqs,std::vector<aidl::android::hardware::camera::device::StreamBufferRet> * outBuffers,aidl::android::hardware::camera::device::BufferRequestStatus * status)698 ::ndk::ScopedAStatus AidlCamera3Device::requestStreamBuffers(
699 const std::vector<camera::device::BufferRequest>& bufReqs,
700 std::vector<aidl::android::hardware::camera::device::StreamBufferRet>* outBuffers,
701 aidl::android::hardware::camera::device::BufferRequestStatus* status) {
702
703 RequestBufferStates states {
704 mId, mRequestBufferInterfaceLock, mUseHalBufManager, mHalBufManagedStreamIds,
705 mOutputStreams, mSessionStatsBuilder, *this, *(mInterface), *this};
706 camera3::requestStreamBuffers(states, bufReqs, outBuffers, status);
707 return ::ndk::ScopedAStatus::ok();
708 }
709
returnStreamBuffers(const std::vector<camera::device::StreamBuffer> & buffers)710 ::ndk::ScopedAStatus AidlCamera3Device::AidlCameraDeviceCallbacks::returnStreamBuffers(
711 const std::vector<camera::device::StreamBuffer>& buffers) {
712 sp<AidlCamera3Device> p = mParent.promote();
713 if (p == nullptr) {
714 ALOGE("%s Parent AidlCameraDevice not alive, can't process callbacks", __FUNCTION__);
715 return ::ndk::ScopedAStatus::ok();
716 }
717 return p->returnStreamBuffers(buffers);
718 }
719
createBinder()720 ::ndk::SpAIBinder AidlCamera3Device::AidlCameraDeviceCallbacks::createBinder() {
721 auto binder = BnCameraDeviceCallback::createBinder();
722 AIBinder_setInheritRt(binder.get(), /*inheritRt*/ true);
723 return binder;
724 }
725
returnStreamBuffers(const std::vector<camera::device::StreamBuffer> & buffers)726 ::ndk::ScopedAStatus AidlCamera3Device::returnStreamBuffers(
727 const std::vector<camera::device::StreamBuffer>& buffers) {
728 ReturnBufferStates states {
729 mId, mUseHalBufManager, mHalBufManagedStreamIds, mOutputStreams, mSessionStatsBuilder,
730 *(mInterface)};
731 camera3::returnStreamBuffers(states, buffers);
732 return ::ndk::ScopedAStatus::ok();
733 }
734
AidlHalInterface(std::shared_ptr<aidl::android::hardware::camera::device::ICameraDeviceSession> & session,std::shared_ptr<AidlRequestMetadataQueue> queue,bool useHalBufManager,bool supportOfflineProcessing,bool supportSessionHalBufManager)735 AidlCamera3Device::AidlHalInterface::AidlHalInterface(
736 std::shared_ptr<aidl::android::hardware::camera::device::ICameraDeviceSession> &session,
737 std::shared_ptr<AidlRequestMetadataQueue> queue,
738 bool useHalBufManager, bool supportOfflineProcessing,
739 bool supportSessionHalBufManager) :
740 HalInterface(useHalBufManager, supportOfflineProcessing),
741 mAidlSession(session),
742 mRequestMetadataQueue(queue),
743 mSupportSessionHalBufManager(supportSessionHalBufManager) { }
744
AidlHalInterface(std::shared_ptr<aidl::android::hardware::camera::device::ICameraDeviceSession> & deviceSession,std::shared_ptr<aidl::android::hardware::camera::device::ICameraInjectionSession> & injectionSession,std::shared_ptr<AidlRequestMetadataQueue> queue,bool useHalBufManager,bool supportOfflineProcessing,bool supportSessionHalBufManager)745 AidlCamera3Device::AidlHalInterface::AidlHalInterface(
746 std::shared_ptr<aidl::android::hardware::camera::device::ICameraDeviceSession>
747 &deviceSession,
748 std::shared_ptr<aidl::android::hardware::camera::device::ICameraInjectionSession>
749 &injectionSession, std::shared_ptr<AidlRequestMetadataQueue> queue,
750 bool useHalBufManager, bool supportOfflineProcessing,
751 bool supportSessionHalBufManager) :
752 HalInterface(useHalBufManager, supportOfflineProcessing),
753 mAidlSession(deviceSession),
754 mAidlInjectionSession(injectionSession),
755 mRequestMetadataQueue(queue),
756 mSupportSessionHalBufManager(supportSessionHalBufManager) { }
757
valid()758 bool AidlCamera3Device::AidlHalInterface::valid() {
759 return (mAidlSession != nullptr);
760 }
761
clear()762 void AidlCamera3Device::AidlHalInterface::clear() {
763 mAidlSession.reset();
764 }
765
flush()766 status_t AidlCamera3Device::AidlHalInterface::flush() {
767 ATRACE_NAME("CameraHal::flush");
768 if (!valid()) return INVALID_OPERATION;
769 status_t res = OK;
770
771 auto err = mAidlSession->flush();
772 if (!err.isOk()) {
773 ALOGE("%s: Transaction error: %s", __FUNCTION__, err.getMessage());
774 res = AidlProviderInfo::mapToStatusT(err);
775 }
776
777 return res;
778 }
779
dump(int)780 status_t AidlCamera3Device::AidlHalInterface::dump(int /*fd*/) {
781 ATRACE_NAME("CameraHal::dump");
782 if (!valid()) return INVALID_OPERATION;
783
784 // Handled by CameraProviderManager::dump
785
786 return OK;
787 }
788
repeatingRequestEnd(uint32_t frameNumber,const std::vector<int32_t> & streamIds)789 status_t AidlCamera3Device::AidlHalInterface::repeatingRequestEnd(uint32_t frameNumber,
790 const std::vector<int32_t> &streamIds) {
791 ATRACE_NAME("AidlCameraHal::repeatingRequestEnd");
792 if (!valid()) return INVALID_OPERATION;
793
794 auto err = mAidlSession->repeatingRequestEnd(frameNumber, streamIds);
795 if (!err.isOk()) {
796 ALOGE("%s: Transaction error: %s", __FUNCTION__, err.getMessage());
797 return AidlProviderInfo::mapToStatusT(err);
798 }
799
800 return OK;
801 }
802
close()803 status_t AidlCamera3Device::AidlHalInterface::close() {
804 ATRACE_NAME("CameraHal::close()");
805 if (!valid()) return INVALID_OPERATION;
806 status_t res = OK;
807
808 auto err = mAidlSession->close();
809 // Interface will be dead shortly anyway, so don't log errors
810 if (!err.isOk()) {
811 res = DEAD_OBJECT;
812 }
813
814 return res;
815 }
816
signalPipelineDrain(const std::vector<int> & streamIds)817 void AidlCamera3Device::AidlHalInterface::signalPipelineDrain(const std::vector<int>& streamIds) {
818 ATRACE_NAME("CameraHal::signalPipelineDrain");
819 if (!valid()) {
820 ALOGE("%s called on invalid camera!", __FUNCTION__);
821 return;
822 }
823
824 auto err = mAidlSession->signalStreamFlush(streamIds, mNextStreamConfigCounter - 1);
825 if (!err.isOk()) {
826 ALOGE("%s: Transaction error: %s", __FUNCTION__, err.getMessage());
827 return;
828 }
829 }
830
isReconfigurationRequired(CameraMetadata & oldSessionParams,CameraMetadata & newSessionParams)831 bool AidlCamera3Device::AidlHalInterface::isReconfigurationRequired(
832 CameraMetadata& oldSessionParams, CameraMetadata& newSessionParams) {
833 // We do reconfiguration by default;
834 bool required = true;
835 if (mIsReconfigurationQuerySupported) {
836 aidl::android::hardware::camera::device::CameraMetadata oldParams, newParams;
837 camera_metadata_t* oldSessionMeta = const_cast<camera_metadata_t*>(
838 oldSessionParams.getAndLock());
839 uint8_t *oldSessionByteP = reinterpret_cast<uint8_t*>(oldSessionMeta);
840
841 camera_metadata_t* newSessionMeta = const_cast<camera_metadata_t*>(
842 newSessionParams.getAndLock());
843 uint8_t *newSessionByteP = reinterpret_cast<uint8_t*>(newSessionMeta);
844 // std::vector has no setToExternal, so we hacve to copy
845 oldParams.metadata.assign(oldSessionByteP,
846 oldSessionByteP + get_camera_metadata_size(oldSessionMeta));
847 newParams.metadata.assign(newSessionByteP,
848 newSessionByteP + get_camera_metadata_size(newSessionMeta));
849 auto err = mAidlSession->isReconfigurationRequired(oldParams, newParams, &required);
850 oldSessionParams.unlock(oldSessionMeta);
851 newSessionParams.unlock(newSessionMeta);
852 if (!err.isOk()) {
853 ALOGE("%s: Unexpected binder error: %s", __FUNCTION__, err.getMessage());
854 return true;
855 }
856 }
857
858 return required;
859 }
860
constructDefaultRequestSettings(camera_request_template_t templateId,camera_metadata_t ** requestTemplate)861 status_t AidlCamera3Device::AidlHalInterface::constructDefaultRequestSettings(
862 camera_request_template_t templateId,
863 /*out*/ camera_metadata_t **requestTemplate) {
864 ATRACE_NAME("CameraAidlHal::constructDefaultRequestSettings");
865 using aidl::android::hardware::camera::device::RequestTemplate;
866 if (!valid()) return INVALID_OPERATION;
867
868 RequestTemplate id;
869 status_t res = SessionConfigurationUtils::mapRequestTemplateToAidl(
870 templateId, &id);
871 if (res != OK) {
872 return res;
873 }
874
875 aidl::android::hardware::camera::device::CameraMetadata request;
876 auto err = mAidlSession->constructDefaultRequestSettings(id, &request);
877
878 if (!err.isOk()) {
879 ALOGE("%s: Transaction error: %s", __FUNCTION__, err.getMessage());
880 return AidlProviderInfo::mapToStatusT(err);
881 }
882 const camera_metadata *r =
883 reinterpret_cast<const camera_metadata_t*>(request.metadata.data());
884 size_t expectedSize = request.metadata.size();
885 int ret = validate_camera_metadata_structure(r, &expectedSize);
886 if (ret == OK || ret == CAMERA_METADATA_VALIDATION_SHIFTED) {
887 *requestTemplate = clone_camera_metadata(r);
888 if (*requestTemplate == nullptr) {
889 ALOGE("%s: Unable to clone camera metadata received from HAL",
890 __FUNCTION__);
891 res = UNKNOWN_ERROR;
892 }
893 } else {
894 ALOGE("%s: Malformed camera metadata received from HAL", __FUNCTION__);
895 res = UNKNOWN_ERROR;
896 }
897
898 return res;
899 }
900
configureStreams(const camera_metadata_t * sessionParams,camera_stream_configuration * config,const std::vector<uint32_t> & bufferSizes,int64_t logId)901 status_t AidlCamera3Device::AidlHalInterface::configureStreams(
902 const camera_metadata_t *sessionParams,
903 camera_stream_configuration *config, const std::vector<uint32_t>& bufferSizes,
904 int64_t logId) {
905 using camera::device::StreamType;
906 using camera::device::StreamConfigurationMode;
907
908 ATRACE_NAME("CameraHal::configureStreams");
909 if (!valid()) return INVALID_OPERATION;
910 status_t res = OK;
911
912 // Convert stream config to AIDL
913 std::set<int> activeStreams;
914 camera::device::StreamConfiguration requestedConfiguration;
915 requestedConfiguration.streams.resize(config->num_streams);
916 for (size_t i = 0; i < config->num_streams; i++) {
917 camera::device::Stream &dst = requestedConfiguration.streams[i];
918 camera3::camera_stream_t *src = config->streams[i];
919
920 Camera3Stream* cam3stream = Camera3Stream::cast(src);
921 cam3stream->setBufferFreedListener(this);
922 int streamId = cam3stream->getId();
923 StreamType streamType;
924 switch (src->stream_type) {
925 case CAMERA_STREAM_OUTPUT:
926 streamType = StreamType::OUTPUT;
927 break;
928 case CAMERA_STREAM_INPUT:
929 streamType = StreamType::INPUT;
930 break;
931 default:
932 ALOGE("%s: Stream %d: Unsupported stream type %d",
933 __FUNCTION__, streamId, config->streams[i]->stream_type);
934 return BAD_VALUE;
935 }
936 dst.id = streamId;
937 dst.streamType = streamType;
938 dst.width = src->width;
939 dst.height = src->height;
940 dst.usage = mapToAidlConsumerUsage(cam3stream->getUsage());
941 dst.rotation = mapToAidlStreamRotation((camera_stream_rotation_t) src->rotation);
942 dst.format = mapToAidlPixelFormat(cam3stream->isFormatOverridden() ?
943 cam3stream->getOriginalFormat() : src->format);
944 dst.dataSpace = mapToAidlDataspace(cam3stream->isDataSpaceOverridden() ?
945 cam3stream->getOriginalDataSpace() : src->data_space);
946 dst.colorSpace = src->color_space;
947
948 dst.bufferSize = bufferSizes[i];
949 if (!src->physical_camera_id.empty()) {
950 dst.physicalCameraId = src->physical_camera_id;
951 }
952 dst.groupId = cam3stream->getHalStreamGroupId();
953 dst.sensorPixelModesUsed.resize(src->sensor_pixel_modes_used.size());
954 size_t j = 0;
955 for (int mode : src->sensor_pixel_modes_used) {
956 dst.sensorPixelModesUsed[j++] = static_cast<SensorPixelMode>(mode);
957 }
958 dst.dynamicRangeProfile = mapToAidlDynamicProfile(src->dynamic_range_profile);
959 dst.useCase = static_cast<ScalerAvailableStreamUseCases>(src->use_case);
960 activeStreams.insert(streamId);
961 // Create Buffer ID map if necessary
962 mBufferRecords.tryCreateBufferCache(streamId);
963 }
964 // remove BufferIdMap for deleted streams
965 mBufferRecords.removeInactiveBufferCaches(activeStreams);
966
967 StreamConfigurationMode operationMode;
968 res = mapToAidlStreamConfigurationMode(
969 (camera_stream_configuration_mode_t) config->operation_mode,
970 /*out*/ &operationMode);
971 if (res != OK) {
972 return res;
973 }
974 requestedConfiguration.operationMode = operationMode;
975 size_t sessionParamSize = get_camera_metadata_size(sessionParams);
976 uint8_t *sessionParamP =
977 reinterpret_cast<uint8_t*>(const_cast<camera_metadata_t*>(sessionParams));
978
979 // std::vector has no setToExternal, so we have to copy
980 requestedConfiguration.sessionParams.metadata.assign(
981 sessionParamP, sessionParamP + sessionParamSize);
982 requestedConfiguration.operationMode = operationMode;
983
984 // Invoke configureStreams
985 std::vector<camera::device::HalStream> finalConfiguration;
986
987 requestedConfiguration.streamConfigCounter = mNextStreamConfigCounter++;
988 requestedConfiguration.multiResolutionInputImage = config->input_is_multi_resolution;
989 requestedConfiguration.logId = logId;
990 ndk::ScopedAStatus err = ndk::ScopedAStatus::ok();
991 int32_t interfaceVersion = 0;
992 camera::device::ConfigureStreamsRet configureStreamsRet;
993 err = mAidlSession->getInterfaceVersion(&interfaceVersion);
994 if (!err.isOk()) {
995 ALOGE("%s: Transaction error getting interface version: %s", __FUNCTION__,
996 err.getMessage());
997 return AidlProviderInfo::mapToStatusT(err);
998 }
999 if (interfaceVersion >= AIDL_DEVICE_SESSION_V3 && mSupportSessionHalBufManager) {
1000 err = mAidlSession->configureStreamsV2(requestedConfiguration, &configureStreamsRet);
1001 finalConfiguration = std::move(configureStreamsRet.halStreams);
1002 } else {
1003 err = mAidlSession->configureStreams(requestedConfiguration, &finalConfiguration);
1004 }
1005
1006 if (!err.isOk()) {
1007 ALOGE("%s: Transaction error: %s", __FUNCTION__, err.getMessage());
1008 return AidlProviderInfo::mapToStatusT(err);
1009 }
1010
1011 std::set<int32_t> halBufferManagedStreamIds;
1012 for (const auto &halStream: finalConfiguration) {
1013 if ((interfaceVersion >= AIDL_DEVICE_SESSION_V3 &&
1014 mSupportSessionHalBufManager && halStream.enableHalBufferManager)
1015 || mUseHalBufManager) {
1016 halBufferManagedStreamIds.insert(halStream.id);
1017 }
1018 }
1019 mHalBufManagedStreamIds = std::move(halBufferManagedStreamIds);
1020 config->hal_buffer_managed_streams = mHalBufManagedStreamIds;
1021 // And convert output stream configuration from AIDL
1022 for (size_t i = 0; i < config->num_streams; i++) {
1023 camera3::camera_stream_t *dst = config->streams[i];
1024 int streamId = Camera3Stream::cast(dst)->getId();
1025
1026 // Start scan at i, with the assumption that the stream order matches
1027 size_t realIdx = i;
1028 bool found = false;
1029 size_t halStreamCount = finalConfiguration.size();
1030 for (size_t idx = 0; idx < halStreamCount; idx++) {
1031 if (finalConfiguration[realIdx].id == streamId) {
1032 found = true;
1033 break;
1034 }
1035 realIdx = (realIdx >= halStreamCount - 1) ? 0 : realIdx + 1;
1036 }
1037 if (!found) {
1038 ALOGE("%s: Stream %d not found in stream configuration response from HAL",
1039 __FUNCTION__, streamId);
1040 return INVALID_OPERATION;
1041 }
1042 camera::device::HalStream &src = finalConfiguration[realIdx];
1043
1044 Camera3Stream* dstStream = Camera3Stream::cast(dst);
1045 int overrideFormat = mapToFrameworkFormat(src.overrideFormat);
1046 android_dataspace overrideDataSpace = mapToFrameworkDataspace(src.overrideDataSpace);
1047
1048 dstStream->setOfflineProcessingSupport(src.supportOffline);
1049
1050 if (dstStream->getOriginalFormat() != HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED) {
1051 dstStream->setFormatOverride(false);
1052 dstStream->setDataSpaceOverride(false);
1053 if (dst->format != overrideFormat) {
1054 ALOGE("%s: Stream %d: Format override not allowed for format 0x%x", __FUNCTION__,
1055 streamId, dst->format);
1056 }
1057 if (dst->data_space != overrideDataSpace) {
1058 ALOGE("%s: Stream %d: DataSpace override not allowed for format 0x%x", __FUNCTION__,
1059 streamId, dst->format);
1060 }
1061 } else {
1062 bool needFormatOverride =
1063 requestedConfiguration.streams[i].format != src.overrideFormat;
1064 bool needDataspaceOverride =
1065 requestedConfiguration.streams[i].dataSpace != src.overrideDataSpace;
1066 // Override allowed with IMPLEMENTATION_DEFINED
1067 dstStream->setFormatOverride(needFormatOverride);
1068 dstStream->setDataSpaceOverride(needDataspaceOverride);
1069 dst->format = overrideFormat;
1070 dst->data_space = overrideDataSpace;
1071 }
1072
1073 if (dst->stream_type == CAMERA_STREAM_INPUT) {
1074 if (static_cast<int64_t>(src.producerUsage) != 0) {
1075 ALOGE("%s: Stream %d: INPUT streams must have 0 for producer usage",
1076 __FUNCTION__, streamId);
1077 return INVALID_OPERATION;
1078 }
1079 dstStream->setUsage(
1080 mapConsumerToFrameworkUsage(src.consumerUsage));
1081 } else {
1082 // OUTPUT
1083 if (static_cast<int64_t>(src.consumerUsage) != 0) {
1084 ALOGE("%s: Stream %d: OUTPUT streams must have 0 for consumer usage",
1085 __FUNCTION__, streamId);
1086 return INVALID_OPERATION;
1087 }
1088 dstStream->setUsage(
1089 mapProducerToFrameworkUsage(src.producerUsage));
1090 dstStream->setHalBufferManager(
1091 contains(config->hal_buffer_managed_streams, streamId));
1092 }
1093 dst->max_buffers = src.maxBuffers;
1094 }
1095
1096 return res;
1097 }
1098
configureInjectedStreams(const camera_metadata_t * sessionParams,camera_stream_configuration * config,const std::vector<uint32_t> & bufferSizes,const CameraMetadata & cameraCharacteristics)1099 status_t AidlCamera3Device::AidlHalInterface::configureInjectedStreams(
1100 const camera_metadata_t* sessionParams, camera_stream_configuration* config,
1101 const std::vector<uint32_t>& bufferSizes,
1102 const CameraMetadata& cameraCharacteristics) {
1103 using camera::device::StreamType;
1104 using camera::device::StreamConfigurationMode;
1105
1106 ATRACE_NAME("InjectionCameraHal::configureStreams");
1107 if (!valid()) return INVALID_OPERATION;
1108 status_t res = OK;
1109
1110 if (config->input_is_multi_resolution) {
1111 ALOGE("%s: Injection camera device doesn't support multi-resolution input "
1112 "stream", __FUNCTION__);
1113 return BAD_VALUE;
1114 }
1115
1116 // Convert stream config to AIDL
1117 std::set<int> activeStreams;
1118 camera::device::StreamConfiguration requestedConfiguration;
1119 requestedConfiguration.streams.resize(config->num_streams);
1120 for (size_t i = 0; i < config->num_streams; i++) {
1121 camera::device::Stream& dst = requestedConfiguration.streams[i];
1122 camera3::camera_stream_t* src = config->streams[i];
1123
1124 Camera3Stream* cam3stream = Camera3Stream::cast(src);
1125 cam3stream->setBufferFreedListener(this);
1126 int streamId = cam3stream->getId();
1127 StreamType streamType;
1128 switch (src->stream_type) {
1129 case CAMERA_STREAM_OUTPUT:
1130 streamType = StreamType::OUTPUT;
1131 break;
1132 case CAMERA_STREAM_INPUT:
1133 streamType = StreamType::INPUT;
1134 break;
1135 default:
1136 ALOGE("%s: Stream %d: Unsupported stream type %d", __FUNCTION__,
1137 streamId, config->streams[i]->stream_type);
1138 return BAD_VALUE;
1139 }
1140 dst.id = streamId;
1141 dst.streamType = streamType;
1142 dst.width = src->width;
1143 dst.height = src->height;
1144 dst.usage = mapToAidlConsumerUsage(cam3stream->getUsage());
1145 dst.rotation = mapToAidlStreamRotation((camera_stream_rotation_t)src->rotation);
1146 dst.format =
1147 mapToAidlPixelFormat(cam3stream->isFormatOverridden() ? cam3stream->getOriginalFormat()
1148 : src->format);
1149 dst.dataSpace =
1150 mapToAidlDataspace(cam3stream->isDataSpaceOverridden() ?
1151 cam3stream->getOriginalDataSpace() : src->data_space);
1152 dst.bufferSize = bufferSizes[i];
1153 if (!src->physical_camera_id.empty()) {
1154 dst.physicalCameraId = src->physical_camera_id;
1155 }
1156 dst.groupId = cam3stream->getHalStreamGroupId();
1157 dst.sensorPixelModesUsed.resize(src->sensor_pixel_modes_used.size());
1158 size_t j = 0;
1159 for (int mode : src->sensor_pixel_modes_used) {
1160 dst.sensorPixelModesUsed[j++] = static_cast<SensorPixelMode>(mode);
1161 }
1162 activeStreams.insert(streamId);
1163 // Create Buffer ID map if necessary
1164 mBufferRecords.tryCreateBufferCache(streamId);
1165 }
1166 // remove BufferIdMap for deleted streams
1167 mBufferRecords.removeInactiveBufferCaches(activeStreams);
1168
1169 StreamConfigurationMode operationMode;
1170 res = mapToAidlStreamConfigurationMode(
1171 (camera_stream_configuration_mode_t)config->operation_mode,
1172 /*out*/ &operationMode);
1173 if (res != OK) {
1174 return res;
1175 }
1176 requestedConfiguration.operationMode = operationMode;
1177 size_t sessionParamSize = get_camera_metadata_size(sessionParams);
1178 uint8_t *sessionParamP =
1179 reinterpret_cast<uint8_t*>(const_cast<camera_metadata_t*>(sessionParams));
1180 requestedConfiguration.operationMode = operationMode;
1181 requestedConfiguration.sessionParams.metadata.assign(
1182 sessionParamP, sessionParamP + sessionParamSize);
1183
1184 // See which version of HAL we have
1185 if (mAidlInjectionSession != nullptr) {
1186 requestedConfiguration.streamConfigCounter = mNextStreamConfigCounter++;
1187 requestedConfiguration.multiResolutionInputImage = config->input_is_multi_resolution;
1188
1189 const camera_metadata_t* rawMetadata = cameraCharacteristics.getAndLock();
1190 uint8_t *aidlCharsP =
1191 reinterpret_cast<uint8_t*>(const_cast<camera_metadata_t*>(rawMetadata));
1192 aidl::android::hardware::camera::device::CameraMetadata aidlChars;
1193 aidlChars.metadata.assign(aidlCharsP, aidlCharsP + get_camera_metadata_size(rawMetadata));
1194 cameraCharacteristics.unlock(rawMetadata);
1195
1196 auto err = mAidlInjectionSession->configureInjectionStreams(requestedConfiguration,
1197 aidlChars);
1198 if (!err.isOk()) {
1199 ALOGE("%s: Transaction error: %s", __FUNCTION__, err.getMessage());
1200 return AidlProviderInfo::mapToStatusT(err);
1201 }
1202 } else {
1203 ALOGE("%s: mAidlInjectionSession == nullptr, the injection not supported ", __FUNCTION__);
1204 return INVALID_OPERATION;
1205 }
1206
1207 return res;
1208 }
1209
processBatchCaptureRequests(std::vector<camera_capture_request_t * > & requests,uint32_t * numRequestProcessed)1210 status_t AidlCamera3Device::AidlHalInterface::processBatchCaptureRequests(
1211 std::vector<camera_capture_request_t*>& requests,/*out*/uint32_t* numRequestProcessed) {
1212 ATRACE_NAME("CameraHal::processBatchCaptureRequests");
1213 if (!valid()) return INVALID_OPERATION;
1214
1215 std::vector<camera::device::CaptureRequest> captureRequests;
1216 size_t batchSize = requests.size();
1217 if (batchSize > INT_MAX) {
1218 ALOGE("%s batchSize %zu > INT_MAX, aidl interface cannot handle batch size", __FUNCTION__,
1219 batchSize);
1220 return BAD_VALUE;
1221 }
1222 captureRequests.resize(batchSize);
1223 std::vector<native_handle_t*> handlesCreated;
1224 std::vector<std::pair<int32_t, int32_t>> inflightBuffers;
1225
1226 status_t res = OK;
1227 for (size_t i = 0; i < batchSize; i++) {
1228 res = wrapAsAidlRequest(requests[i], /*out*/&captureRequests[i],
1229 /*out*/&handlesCreated, /*out*/&inflightBuffers);
1230
1231 if (res != OK) {
1232 mBufferRecords.popInflightBuffers(inflightBuffers);
1233 cleanupNativeHandles(&handlesCreated);
1234 return res;
1235 }
1236 }
1237
1238 std::vector<camera::device::BufferCache> cachesToRemove;
1239 {
1240 std::lock_guard<std::mutex> lock(mFreedBuffersLock);
1241 for (auto& pair : mFreedBuffers) {
1242 // The stream might have been removed since onBufferFreed
1243 if (mBufferRecords.isStreamCached(pair.first)) {
1244 cachesToRemove.push_back({pair.first, static_cast<int64_t>(pair.second)});
1245 }
1246 }
1247 mFreedBuffers.clear();
1248 }
1249
1250 *numRequestProcessed = 0;
1251
1252 // Write metadata to FMQ.
1253 for (size_t i = 0; i < batchSize; i++) {
1254 camera_capture_request_t* request = requests[i];
1255 camera::device::CaptureRequest* captureRequest;
1256 captureRequest = &captureRequests[i];
1257
1258 if (request->settings != nullptr) {
1259 size_t settingsSize = get_camera_metadata_size(request->settings);
1260 if (mRequestMetadataQueue != nullptr && mRequestMetadataQueue->write(
1261 reinterpret_cast<const int8_t*>(request->settings), settingsSize)) {
1262 captureRequest->settings.metadata.resize(0);
1263 captureRequest->fmqSettingsSize = settingsSize;
1264 } else {
1265 if (mRequestMetadataQueue != nullptr) {
1266 ALOGW("%s: couldn't utilize fmq, fallback to hwbinder", __FUNCTION__);
1267 }
1268 uint8_t *settingsP =
1269 reinterpret_cast<uint8_t*>(
1270 const_cast<camera_metadata_t*>(request->settings));
1271 size_t settingsSize = get_camera_metadata_size(request->settings);
1272 captureRequest->settings.metadata.assign(settingsP, settingsP + settingsSize);
1273 captureRequest->fmqSettingsSize = 0u;
1274 }
1275 } else {
1276 // A null request settings maps to a size-0 CameraMetadata
1277 captureRequest->settings.metadata.resize(0);
1278 captureRequest->fmqSettingsSize = 0u;
1279 }
1280
1281 captureRequest ->inputWidth = request->input_width;
1282 captureRequest->inputHeight = request->input_height;
1283
1284 std::vector<camera::device::PhysicalCameraSetting>& physicalCameraSettings =
1285 captureRequest->physicalCameraSettings;
1286 physicalCameraSettings.resize(request->num_physcam_settings);
1287 for (size_t j = 0; j < request->num_physcam_settings; j++) {
1288 if (request->physcam_settings != nullptr) {
1289 size_t settingsSize = get_camera_metadata_size(request->physcam_settings[j]);
1290 if (mRequestMetadataQueue != nullptr && mRequestMetadataQueue->write(
1291 reinterpret_cast<const int8_t*>(request->physcam_settings[j]),
1292 settingsSize)) {
1293 physicalCameraSettings[j].settings.metadata.resize(0);
1294 physicalCameraSettings[j].fmqSettingsSize = settingsSize;
1295 } else {
1296 if (mRequestMetadataQueue != nullptr) {
1297 ALOGW("%s: couldn't utilize fmq, fallback to hwbinder", __FUNCTION__);
1298 }
1299 uint8_t *physicalSettingsP =
1300 reinterpret_cast<uint8_t*>(const_cast<camera_metadata_t*>(
1301 request->physcam_settings[j]));
1302 physicalCameraSettings[j].settings.metadata.assign(physicalSettingsP,
1303 physicalSettingsP + settingsSize);
1304 physicalCameraSettings[j].fmqSettingsSize = 0u;
1305 }
1306 } else {
1307 physicalCameraSettings[j].fmqSettingsSize = 0u;
1308 physicalCameraSettings[j].settings.metadata.resize(0);
1309 }
1310 physicalCameraSettings[j].physicalCameraId = request->physcam_id[j];
1311 }
1312 }
1313
1314 int32_t numRequests = 0;
1315 auto retS = mAidlSession->processCaptureRequest(captureRequests, cachesToRemove,
1316 &numRequests);
1317 if (!retS.isOk()) {
1318 res = AidlProviderInfo::mapToStatusT(retS);
1319 }
1320 if (res == OK) {
1321 if (numRequests < 0) {
1322 res = INVALID_OPERATION;
1323 } else {
1324 *numRequestProcessed = static_cast<uint32_t>(numRequests);
1325 }
1326
1327 }
1328 if (res == OK && *numRequestProcessed == batchSize) {
1329 if (mAidlSession->isRemote()) {
1330 // Only close acquire fence FDs when the AIDL transaction succeeds (so the FDs have been
1331 // sent to camera HAL processes)
1332 cleanupNativeHandles(&handlesCreated, /*closeFd*/true);
1333 } else {
1334 // In passthrough mode the FDs are now owned by HAL
1335 cleanupNativeHandles(&handlesCreated);
1336 }
1337 } else {
1338 ALOGE("%s Error with processCaptureRequest %s ", __FUNCTION__, retS.getMessage());
1339 mBufferRecords.popInflightBuffers(inflightBuffers);
1340 cleanupNativeHandles(&handlesCreated);
1341 }
1342 return res;
1343 }
1344
wrapAsAidlRequest(camera_capture_request_t * request,camera::device::CaptureRequest * captureRequest,std::vector<native_handle_t * > * handlesCreated,std::vector<std::pair<int32_t,int32_t>> * inflightBuffers)1345 status_t AidlCamera3Device::AidlHalInterface::wrapAsAidlRequest(camera_capture_request_t* request,
1346 /*out*/camera::device::CaptureRequest* captureRequest,
1347 /*out*/std::vector<native_handle_t*>* handlesCreated,
1348 /*out*/std::vector<std::pair<int32_t, int32_t>>* inflightBuffers) {
1349 using camera::device::BufferStatus;
1350 using camera::device::StreamBuffer;
1351 ATRACE_CALL();
1352 if (captureRequest == nullptr || handlesCreated == nullptr || inflightBuffers == nullptr) {
1353 ALOGE("%s: captureRequest (%p), handlesCreated (%p), and inflightBuffers(%p) "
1354 "must not be null", __FUNCTION__, captureRequest, handlesCreated, inflightBuffers);
1355 return BAD_VALUE;
1356 }
1357
1358 captureRequest->frameNumber = request->frame_number;
1359
1360 captureRequest->fmqSettingsSize = 0;
1361
1362 {
1363 if (request->input_buffer != nullptr) {
1364 int32_t streamId = Camera3Stream::cast(request->input_buffer->stream)->getId();
1365 buffer_handle_t buf = *(request->input_buffer->buffer);
1366 auto pair = getBufferId(buf, streamId);
1367 bool isNewBuffer = pair.first;
1368 uint64_t bufferId = pair.second;
1369 captureRequest->inputBuffer.streamId = streamId;
1370 captureRequest->inputBuffer.bufferId = bufferId;
1371 captureRequest->inputBuffer.buffer =
1372 (isNewBuffer) ? camera3::dupToAidlIfNotNull(buf) :
1373 aidl::android::hardware::common::NativeHandle();
1374 captureRequest->inputBuffer.status = BufferStatus::OK;
1375 native_handle_t *acquireFence = nullptr;
1376 if (request->input_buffer->acquire_fence != -1) {
1377 acquireFence = native_handle_create(1,0);
1378 acquireFence->data[0] = request->input_buffer->acquire_fence;
1379 handlesCreated->push_back(acquireFence);
1380 }
1381 // duping here is okay, in aidl ownership is not given to aidl_handle
1382 captureRequest->inputBuffer.acquireFence = camera3::dupToAidlIfNotNull(acquireFence);
1383 captureRequest->inputBuffer.releaseFence =
1384 aidl::android::hardware::common::NativeHandle();
1385
1386 mBufferRecords.pushInflightBuffer(captureRequest->frameNumber, streamId,
1387 request->input_buffer->buffer);
1388 inflightBuffers->push_back(std::make_pair(captureRequest->frameNumber, streamId));
1389 } else {
1390 captureRequest->inputBuffer.streamId = -1;
1391 captureRequest->inputBuffer.bufferId = BUFFER_ID_NO_BUFFER;
1392 }
1393
1394 captureRequest->outputBuffers.resize(request->num_output_buffers);
1395 for (size_t i = 0; i < request->num_output_buffers; i++) {
1396 const camera_stream_buffer_t *src = request->output_buffers + i;
1397 StreamBuffer &dst = captureRequest->outputBuffers[i];
1398 int32_t streamId = Camera3Stream::cast(src->stream)->getId();
1399 if (src->buffer != nullptr) {
1400 buffer_handle_t buf = *(src->buffer);
1401 auto pair = getBufferId(buf, streamId);
1402 bool isNewBuffer = pair.first;
1403 dst.bufferId = pair.second;
1404 dst.buffer = isNewBuffer ?
1405 camera3::dupToAidlIfNotNull(buf) :
1406 aidl::android::hardware::common::NativeHandle();
1407 native_handle_t *acquireFence = nullptr;
1408 if (src->acquire_fence != -1) {
1409 acquireFence = native_handle_create(1,0);
1410 acquireFence->data[0] = src->acquire_fence;
1411 handlesCreated->push_back(acquireFence);
1412 }
1413 dst.acquireFence = camera3::dupToAidlIfNotNull(acquireFence);
1414 } else if (isHalBufferManagedStream(streamId)) {
1415 // HAL buffer management path
1416 dst.bufferId = BUFFER_ID_NO_BUFFER;
1417 dst.buffer = aidl::android::hardware::common::NativeHandle();
1418 dst.acquireFence = aidl::android::hardware::common::NativeHandle();
1419 } else {
1420 ALOGE("%s: cannot send a null buffer in capture request!", __FUNCTION__);
1421 return BAD_VALUE;
1422 }
1423 dst.streamId = streamId;
1424 dst.status = BufferStatus::OK;
1425 dst.releaseFence = aidl::android::hardware::common::NativeHandle();
1426
1427 // Output buffers are empty when using HAL buffer manager
1428 if (!isHalBufferManagedStream(streamId)) {
1429 mBufferRecords.pushInflightBuffer(
1430 captureRequest->frameNumber, streamId, src->buffer);
1431 inflightBuffers->push_back(std::make_pair(captureRequest->frameNumber, streamId));
1432 }
1433 }
1434 }
1435 return OK;
1436 }
1437
switchToOffline(const std::vector<int32_t> & streamsToKeep,aidl::android::hardware::camera::device::CameraOfflineSessionInfo * offlineSessionInfo,std::shared_ptr<aidl::android::hardware::camera::device::ICameraOfflineSession> * offlineSession,camera3::BufferRecords * bufferRecords)1438 status_t AidlCamera3Device::AidlHalInterface::switchToOffline(
1439 const std::vector<int32_t>& streamsToKeep,
1440 /*out*/aidl::android::hardware::camera::device::CameraOfflineSessionInfo*
1441 offlineSessionInfo,
1442 /*out*/std::shared_ptr<aidl::android::hardware::camera::device::ICameraOfflineSession>*
1443 offlineSession,
1444 /*out*/camera3::BufferRecords* bufferRecords) {
1445 ATRACE_NAME("CameraHal::switchToOffline");
1446 if (!valid()) {
1447 ALOGE("%s called on invalid camera!", __FUNCTION__);
1448 return INVALID_OPERATION;
1449 }
1450
1451 if (offlineSessionInfo == nullptr || offlineSession == nullptr || bufferRecords == nullptr) {
1452 ALOGE("%s: output arguments must not be null!", __FUNCTION__);
1453 return INVALID_OPERATION;
1454 }
1455
1456 auto err = mAidlSession->switchToOffline(streamsToKeep, offlineSessionInfo, offlineSession);
1457
1458 if (!err.isOk()) {
1459 ALOGE("%s: Transaction error: %s", __FUNCTION__, err.getMessage());
1460 return AidlProviderInfo::mapToStatusT(err);
1461 }
1462
1463 return verifyBufferCaches(offlineSessionInfo, bufferRecords);
1464 }
1465
AidlRequestThread(wp<Camera3Device> parent,sp<camera3::StatusTracker> statusTracker,sp<HalInterface> interface,const Vector<int32_t> & sessionParamKeys,bool useHalBufManager,bool supportCameraMute,int rotationOverride,bool supportSettingsOverride)1466 AidlCamera3Device::AidlRequestThread::AidlRequestThread(wp<Camera3Device> parent,
1467 sp<camera3::StatusTracker> statusTracker,
1468 sp<HalInterface> interface,
1469 const Vector<int32_t>& sessionParamKeys,
1470 bool useHalBufManager,
1471 bool supportCameraMute,
1472 int rotationOverride,
1473 bool supportSettingsOverride) :
1474 RequestThread(parent, statusTracker, interface, sessionParamKeys,
1475 useHalBufManager, supportCameraMute, rotationOverride,
1476 supportSettingsOverride) {}
1477
switchToOffline(const std::vector<int32_t> & streamsToKeep,camera::device::CameraOfflineSessionInfo * offlineSessionInfo,std::shared_ptr<camera::device::ICameraOfflineSession> * offlineSession,camera3::BufferRecords * bufferRecords)1478 status_t AidlCamera3Device::AidlRequestThread::switchToOffline(
1479 const std::vector<int32_t>& streamsToKeep,
1480 /*out*/camera::device::CameraOfflineSessionInfo* offlineSessionInfo,
1481 /*out*/std::shared_ptr<camera::device::ICameraOfflineSession>* offlineSession,
1482 /*out*/camera3::BufferRecords* bufferRecords) {
1483 Mutex::Autolock l(mRequestLock);
1484 clearRepeatingRequestsLocked(/*lastFrameNumber*/nullptr);
1485
1486 // Wait until request thread is fully stopped
1487 // TBD: check if request thread is being paused by other APIs (shouldn't be)
1488
1489 // We could also check for mRepeatingRequests.empty(), but the API interface
1490 // is serialized by Camera3Device::mInterfaceLock so no one should be able to submit any
1491 // new requests during the call; hence skip that check.
1492 bool queueEmpty = mNextRequests.empty() && mRequestQueue.empty();
1493 while (!queueEmpty) {
1494 status_t res = mRequestSubmittedSignal.waitRelative(mRequestLock, kRequestSubmitTimeout);
1495 if (res == TIMED_OUT) {
1496 ALOGE("%s: request thread failed to submit one request within timeout!", __FUNCTION__);
1497 return res;
1498 } else if (res != OK) {
1499 ALOGE("%s: request thread failed to submit a request: %s (%d)!",
1500 __FUNCTION__, strerror(-res), res);
1501 return res;
1502 }
1503 queueEmpty = mNextRequests.empty() && mRequestQueue.empty();
1504 }
1505 return (static_cast<AidlHalInterface *>(mInterface.get()))->switchToOffline(
1506 streamsToKeep, offlineSessionInfo, offlineSession, bufferRecords);
1507 }
1508
injectionInitialize(const std::string & injectedCamId,sp<CameraProviderManager> manager,const std::shared_ptr<camera::device::ICameraDeviceCallback> & callback)1509 status_t AidlCamera3Device::AidlCamera3DeviceInjectionMethods::injectionInitialize(
1510 const std::string& injectedCamId, sp<CameraProviderManager> manager,
1511 const std::shared_ptr<camera::device::ICameraDeviceCallback>&callback) {
1512 ATRACE_CALL();
1513 Mutex::Autolock lock(mInjectionLock);
1514
1515 if (manager == nullptr) {
1516 ALOGE("%s: manager does not exist!", __FUNCTION__);
1517 return INVALID_OPERATION;
1518 }
1519
1520 sp<Camera3Device> parent = mParent.promote();
1521 if (parent == nullptr) {
1522 ALOGE("%s: parent does not exist!", __FUNCTION__);
1523 return INVALID_OPERATION;
1524 }
1525
1526 if (parent->getTransportType() != IPCTransport::AIDL) {
1527 ALOGE("%s Parent transport not AIDL for injected camera id %s, aborting", __FUNCTION__,
1528 injectedCamId.c_str());
1529 return INVALID_OPERATION;
1530 }
1531 mInjectedCamId = injectedCamId;
1532 std::shared_ptr<camera::device::ICameraInjectionSession> injectionSession;
1533 ATRACE_BEGIN("Injection CameraHal::openSession");
1534 status_t res = manager->openAidlInjectionSession(injectedCamId, callback,
1535 /*out*/ &injectionSession);
1536 ATRACE_END();
1537 if (res != OK) {
1538 ALOGE("Injection camera could not open camera session: %s (%d)",
1539 strerror(-res), res);
1540 return res;
1541 }
1542 std::shared_ptr<camera::device::ICameraDeviceSession> deviceSession = nullptr;
1543 auto ret = injectionSession->getCameraDeviceSession(&deviceSession);
1544 if (!ret.isOk() || deviceSession == nullptr) {
1545 ALOGE("%s Camera injection session couldn't return ICameraDeviceSession", __FUNCTION__);
1546 return AidlProviderInfo::mapToStatusT(ret);
1547 }
1548
1549 std::shared_ptr<AidlRequestMetadataQueue> queue;
1550 ::aidl::android::hardware::common::fmq::MQDescriptor<
1551 int8_t, ::aidl::android::hardware::common::fmq::SynchronizedReadWrite> desc;
1552
1553 ::ndk::ScopedAStatus requestQueueRet = deviceSession->getCaptureRequestMetadataQueue(&desc);
1554 if (!requestQueueRet.isOk()) {
1555 ALOGE("Injection camera transaction error when getting result metadata queue from camera"
1556 " session: %s", requestQueueRet.getMessage());
1557 return AidlProviderInfo::mapToStatusT(requestQueueRet);
1558 }
1559 queue = std::make_unique<AidlRequestMetadataQueue>(desc);
1560 if (!queue->isValid() || queue->availableToWrite() <= 0) {
1561 ALOGE("HAL returns empty result metadata fmq, not use it");
1562 queue = nullptr;
1563 // Don't use resQueue onwards.
1564 }
1565
1566 std::unique_ptr<AidlResultMetadataQueue>& resQueue = mInjectionResultMetadataQueue;
1567 ::aidl::android::hardware::common::fmq::MQDescriptor<
1568 int8_t, ::aidl::android::hardware::common::fmq::SynchronizedReadWrite> resDesc;
1569 ::ndk::ScopedAStatus resultQueueRet = deviceSession->getCaptureResultMetadataQueue(&resDesc);
1570 if (!resultQueueRet.isOk()) {
1571 ALOGE("Transaction error when getting result metadata queue from camera session: %s",
1572 resultQueueRet.getMessage());
1573 return AidlProviderInfo::mapToStatusT(resultQueueRet);
1574 }
1575 resQueue = std::make_unique<AidlResultMetadataQueue>(resDesc);
1576 if (!resQueue->isValid() || resQueue->availableToWrite() <= 0) {
1577 ALOGE("HAL returns empty result metadata fmq, not use it");
1578 resQueue = nullptr;
1579 // Don't use resQueue onwards.
1580 }
1581
1582 ALOGV("%s: Injection camera interface = new HalInterface()", __FUNCTION__);
1583
1584 mInjectedCamHalInterface =
1585 new AidlHalInterface(deviceSession, injectionSession, queue, parent->mUseHalBufManager,
1586 parent->mSupportOfflineProcessing, parent->mSessionHalBufManager);
1587 if (mInjectedCamHalInterface == nullptr) {
1588 ALOGE("%s: mInjectedCamHalInterface does not exist!", __FUNCTION__);
1589 return DEAD_OBJECT;
1590 }
1591
1592 return OK;
1593 }
1594
replaceHalInterface(sp<HalInterface> newHalInterface,bool keepBackup)1595 status_t AidlCamera3Device::AidlCamera3DeviceInjectionMethods::replaceHalInterface(
1596 sp<HalInterface> newHalInterface, bool keepBackup) {
1597 Mutex::Autolock lock(mInjectionLock);
1598 if (newHalInterface.get() == nullptr) {
1599 ALOGE("%s: The newHalInterface does not exist, to stop replacing.",
1600 __FUNCTION__);
1601 return DEAD_OBJECT;
1602 }
1603
1604 sp<Camera3Device> parent = mParent.promote();
1605 if (parent == nullptr) {
1606 ALOGE("%s: parent does not exist!", __FUNCTION__);
1607 return INVALID_OPERATION;
1608 }
1609 if (parent->getTransportType() != IPCTransport::AIDL ||
1610 newHalInterface->getTransportType() != IPCTransport::AIDL) {
1611 ALOGE("%s Parent transport not AIDL for replacing hal interface", __FUNCTION__);
1612 return INVALID_OPERATION;
1613 }
1614
1615 AidlCamera3Device *aidlParent = static_cast<AidlCamera3Device *>(parent.get());
1616 if (keepBackup) {
1617 if (mBackupHalInterface == nullptr) {
1618 mBackupHalInterface = parent->mInterface;
1619 }
1620 if (mBackupResultMetadataQueue == nullptr) {
1621 mBackupResultMetadataQueue = std::move(aidlParent->mResultMetadataQueue);
1622 aidlParent->mResultMetadataQueue = std::move(mInjectionResultMetadataQueue);
1623 }
1624 } else {
1625 mBackupHalInterface = nullptr;
1626 aidlParent->mResultMetadataQueue = std::move(mBackupResultMetadataQueue);
1627 mBackupResultMetadataQueue = nullptr;
1628 }
1629 parent->mInterface = newHalInterface;
1630 return OK;
1631 }
1632
applyMaxBatchSizeLocked(RequestList * requestList,const sp<camera3::Camera3OutputStreamInterface> & stream)1633 void AidlCamera3Device::applyMaxBatchSizeLocked(
1634 RequestList* requestList, const sp<camera3::Camera3OutputStreamInterface>& stream) {
1635 int batchSize = requestList->size();
1636
1637 if (!mBatchSizeLimitEnabled) {
1638 (*requestList->begin())->mBatchSize = batchSize;
1639 stream->setBatchSize(batchSize);
1640 return;
1641 }
1642
1643 const auto& metadata = (*requestList->begin())->mSettingsList.begin()->metadata;
1644
1645 uint32_t tag = ANDROID_CONTROL_AVAILABLE_HIGH_SPEED_VIDEO_CONFIGURATIONS;
1646 auto sensorPixelModeEntry = metadata.find(ANDROID_SENSOR_PIXEL_MODE);
1647 if (sensorPixelModeEntry.count != 0) {
1648 if (ANDROID_SENSOR_PIXEL_MODE_MAXIMUM_RESOLUTION == sensorPixelModeEntry.data.u8[0]) {
1649 tag = ANDROID_CONTROL_AVAILABLE_HIGH_SPEED_VIDEO_CONFIGURATIONS_MAXIMUM_RESOLUTION;
1650 }
1651 }
1652
1653 const auto fpsRange = metadata.find(ANDROID_CONTROL_AE_TARGET_FPS_RANGE);
1654 if (fpsRange.count > 1) {
1655 auto configEntry = mDeviceInfo.find(tag);
1656 for (size_t index = 4; index < configEntry.count; index += 5) {
1657 if (stream->getWidth() == static_cast<uint32_t>(configEntry.data.i32[index - 4]) &&
1658 stream->getHeight() == static_cast<uint32_t>(configEntry.data.i32[index - 3]) &&
1659 fpsRange.data.i32[0] == configEntry.data.i32[index - 2] &&
1660 fpsRange.data.i32[1] == configEntry.data.i32[index - 1]) {
1661 const int maxBatchSize = configEntry.data.i32[index - 1] / 30;
1662 const int reportedSize = configEntry.data.i32[index];
1663
1664 if (maxBatchSize % reportedSize == 0 && requestList->size() % reportedSize == 0) {
1665 batchSize = reportedSize;
1666 ALOGVV("Matching high speed configuration found. Limit batch size to %d",
1667 batchSize);
1668 } else if (maxBatchSize % reportedSize == 0 &&
1669 reportedSize % requestList->size() == 0) {
1670 ALOGVV("Matching high speed configuration found, but requested batch size is "
1671 "divisor of batch_size_max. No need to limit batch size.");
1672 } else {
1673 ALOGW("Matching high speed configuration found, but batch_size_max is not a "
1674 "divisor of corresponding fps_max/30 or requested batch size is not a "
1675 "divisor of batch_size_max, (fps_max %d, batch_size_max %d, requested "
1676 "batch size %zu)",
1677 configEntry.data.i32[index - 1], reportedSize, requestList->size());
1678 }
1679 break;
1680 }
1681 }
1682 }
1683
1684 for (auto request = requestList->begin(); request != requestList->end(); request++) {
1685 if (requestList->distance(requestList->begin(), request) % batchSize == 0) {
1686 (*request)->mBatchSize = batchSize;
1687 }
1688 }
1689
1690 stream->setBatchSize(batchSize);
1691 }
1692
injectionCameraInitialize(const std::string & injectedCamId,sp<CameraProviderManager> manager)1693 status_t AidlCamera3Device::injectionCameraInitialize(const std::string &injectedCamId,
1694 sp<CameraProviderManager> manager) {
1695 return (static_cast<AidlCamera3DeviceInjectionMethods *>
1696 (mInjectionMethods.get()))->injectionInitialize(injectedCamId, manager,
1697 std::shared_ptr<camera::device::ICameraDeviceCallback>(mCallbacks));
1698 };
1699
createNewRequestThread(wp<Camera3Device> parent,sp<camera3::StatusTracker> statusTracker,sp<Camera3Device::HalInterface> interface,const Vector<int32_t> & sessionParamKeys,bool useHalBufManager,bool supportCameraMute,int rotationOverride,bool supportSettingsOverride)1700 sp<Camera3Device::RequestThread> AidlCamera3Device::createNewRequestThread(
1701 wp<Camera3Device> parent, sp<camera3::StatusTracker> statusTracker,
1702 sp<Camera3Device::HalInterface> interface,
1703 const Vector<int32_t>& sessionParamKeys,
1704 bool useHalBufManager,
1705 bool supportCameraMute,
1706 int rotationOverride,
1707 bool supportSettingsOverride) {
1708 return new AidlRequestThread(parent, statusTracker, interface, sessionParamKeys,
1709 useHalBufManager, supportCameraMute, rotationOverride,
1710 supportSettingsOverride);
1711 };
1712
1713 sp<Camera3Device::Camera3DeviceInjectionMethods>
createCamera3DeviceInjectionMethods(wp<Camera3Device> parent)1714 AidlCamera3Device::createCamera3DeviceInjectionMethods(wp<Camera3Device> parent) {
1715 return new AidlCamera3DeviceInjectionMethods(parent);
1716 }
1717
1718 }; // namespace android
1719