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();
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 // For stream configurations with multi res streams, hal buffer manager has to be used.
922 if (!flags::session_hal_buf_manager() && cam3stream->getHalStreamGroupId() != -1 &&
923 src->stream_type != CAMERA_STREAM_INPUT) {
924 mUseHalBufManager = true;
925 config->use_hal_buf_manager = true;
926 }
927 cam3stream->setBufferFreedListener(this);
928 int streamId = cam3stream->getId();
929 StreamType streamType;
930 switch (src->stream_type) {
931 case CAMERA_STREAM_OUTPUT:
932 streamType = StreamType::OUTPUT;
933 break;
934 case CAMERA_STREAM_INPUT:
935 streamType = StreamType::INPUT;
936 break;
937 default:
938 ALOGE("%s: Stream %d: Unsupported stream type %d",
939 __FUNCTION__, streamId, config->streams[i]->stream_type);
940 return BAD_VALUE;
941 }
942 dst.id = streamId;
943 dst.streamType = streamType;
944 dst.width = src->width;
945 dst.height = src->height;
946 dst.usage = mapToAidlConsumerUsage(cam3stream->getUsage());
947 dst.rotation = mapToAidlStreamRotation((camera_stream_rotation_t) src->rotation);
948 dst.format = mapToAidlPixelFormat(cam3stream->isFormatOverridden() ?
949 cam3stream->getOriginalFormat() : src->format);
950 dst.dataSpace = mapToAidlDataspace(cam3stream->isDataSpaceOverridden() ?
951 cam3stream->getOriginalDataSpace() : src->data_space);
952 dst.colorSpace = src->color_space;
953
954 dst.bufferSize = bufferSizes[i];
955 if (!src->physical_camera_id.empty()) {
956 dst.physicalCameraId = src->physical_camera_id;
957 }
958 dst.groupId = cam3stream->getHalStreamGroupId();
959 dst.sensorPixelModesUsed.resize(src->sensor_pixel_modes_used.size());
960 size_t j = 0;
961 for (int mode : src->sensor_pixel_modes_used) {
962 dst.sensorPixelModesUsed[j++] = static_cast<SensorPixelMode>(mode);
963 }
964 dst.dynamicRangeProfile = mapToAidlDynamicProfile(src->dynamic_range_profile);
965 dst.useCase = static_cast<ScalerAvailableStreamUseCases>(src->use_case);
966 activeStreams.insert(streamId);
967 // Create Buffer ID map if necessary
968 mBufferRecords.tryCreateBufferCache(streamId);
969 }
970 // remove BufferIdMap for deleted streams
971 mBufferRecords.removeInactiveBufferCaches(activeStreams);
972
973 StreamConfigurationMode operationMode;
974 res = mapToAidlStreamConfigurationMode(
975 (camera_stream_configuration_mode_t) config->operation_mode,
976 /*out*/ &operationMode);
977 if (res != OK) {
978 return res;
979 }
980 requestedConfiguration.operationMode = operationMode;
981 size_t sessionParamSize = get_camera_metadata_size(sessionParams);
982 uint8_t *sessionParamP =
983 reinterpret_cast<uint8_t*>(const_cast<camera_metadata_t*>(sessionParams));
984
985 // std::vector has no setToExternal, so we have to copy
986 requestedConfiguration.sessionParams.metadata.assign(
987 sessionParamP, sessionParamP + sessionParamSize);
988 requestedConfiguration.operationMode = operationMode;
989
990 // Invoke configureStreams
991 std::vector<camera::device::HalStream> finalConfiguration;
992
993 requestedConfiguration.streamConfigCounter = mNextStreamConfigCounter++;
994 requestedConfiguration.multiResolutionInputImage = config->input_is_multi_resolution;
995 requestedConfiguration.logId = logId;
996 ndk::ScopedAStatus err = ndk::ScopedAStatus::ok();
997 int32_t interfaceVersion = 0;
998 camera::device::ConfigureStreamsRet configureStreamsRet;
999 err = mAidlSession->getInterfaceVersion(&interfaceVersion);
1000 if (!err.isOk()) {
1001 ALOGE("%s: Transaction error getting interface version: %s", __FUNCTION__,
1002 err.getMessage());
1003 return AidlProviderInfo::mapToStatusT(err);
1004 }
1005 if (flags::session_hal_buf_manager() && interfaceVersion >= AIDL_DEVICE_SESSION_V3
1006 && mSupportSessionHalBufManager) {
1007 err = mAidlSession->configureStreamsV2(requestedConfiguration, &configureStreamsRet);
1008 finalConfiguration = std::move(configureStreamsRet.halStreams);
1009 } else {
1010 err = mAidlSession->configureStreams(requestedConfiguration, &finalConfiguration);
1011 }
1012
1013 if (!err.isOk()) {
1014 ALOGE("%s: Transaction error: %s", __FUNCTION__, err.getMessage());
1015 return AidlProviderInfo::mapToStatusT(err);
1016 }
1017
1018 if (flags::session_hal_buf_manager()) {
1019 std::set<int32_t> halBufferManagedStreamIds;
1020 for (const auto &halStream: finalConfiguration) {
1021 if ((interfaceVersion >= AIDL_DEVICE_SESSION_V3 &&
1022 mSupportSessionHalBufManager && halStream.enableHalBufferManager)
1023 || mUseHalBufManager) {
1024 halBufferManagedStreamIds.insert(halStream.id);
1025 }
1026 }
1027 mHalBufManagedStreamIds = std::move(halBufferManagedStreamIds);
1028 config->hal_buffer_managed_streams = mHalBufManagedStreamIds;
1029 }
1030 // And convert output stream configuration from AIDL
1031 for (size_t i = 0; i < config->num_streams; i++) {
1032 camera3::camera_stream_t *dst = config->streams[i];
1033 int streamId = Camera3Stream::cast(dst)->getId();
1034
1035 // Start scan at i, with the assumption that the stream order matches
1036 size_t realIdx = i;
1037 bool found = false;
1038 size_t halStreamCount = finalConfiguration.size();
1039 for (size_t idx = 0; idx < halStreamCount; idx++) {
1040 if (finalConfiguration[realIdx].id == streamId) {
1041 found = true;
1042 break;
1043 }
1044 realIdx = (realIdx >= halStreamCount - 1) ? 0 : realIdx + 1;
1045 }
1046 if (!found) {
1047 ALOGE("%s: Stream %d not found in stream configuration response from HAL",
1048 __FUNCTION__, streamId);
1049 return INVALID_OPERATION;
1050 }
1051 camera::device::HalStream &src = finalConfiguration[realIdx];
1052
1053 Camera3Stream* dstStream = Camera3Stream::cast(dst);
1054 int overrideFormat = mapToFrameworkFormat(src.overrideFormat);
1055 android_dataspace overrideDataSpace = mapToFrameworkDataspace(src.overrideDataSpace);
1056
1057 dstStream->setOfflineProcessingSupport(src.supportOffline);
1058
1059 if (dstStream->getOriginalFormat() != HAL_PIXEL_FORMAT_IMPLEMENTATION_DEFINED) {
1060 dstStream->setFormatOverride(false);
1061 dstStream->setDataSpaceOverride(false);
1062 if (dst->format != overrideFormat) {
1063 ALOGE("%s: Stream %d: Format override not allowed for format 0x%x", __FUNCTION__,
1064 streamId, dst->format);
1065 }
1066 if (dst->data_space != overrideDataSpace) {
1067 ALOGE("%s: Stream %d: DataSpace override not allowed for format 0x%x", __FUNCTION__,
1068 streamId, dst->format);
1069 }
1070 } else {
1071 bool needFormatOverride =
1072 requestedConfiguration.streams[i].format != src.overrideFormat;
1073 bool needDataspaceOverride =
1074 requestedConfiguration.streams[i].dataSpace != src.overrideDataSpace;
1075 // Override allowed with IMPLEMENTATION_DEFINED
1076 dstStream->setFormatOverride(needFormatOverride);
1077 dstStream->setDataSpaceOverride(needDataspaceOverride);
1078 dst->format = overrideFormat;
1079 dst->data_space = overrideDataSpace;
1080 }
1081
1082 if (dst->stream_type == CAMERA_STREAM_INPUT) {
1083 if (static_cast<int64_t>(src.producerUsage) != 0) {
1084 ALOGE("%s: Stream %d: INPUT streams must have 0 for producer usage",
1085 __FUNCTION__, streamId);
1086 return INVALID_OPERATION;
1087 }
1088 dstStream->setUsage(
1089 mapConsumerToFrameworkUsage(src.consumerUsage));
1090 } else {
1091 // OUTPUT
1092 if (static_cast<int64_t>(src.consumerUsage) != 0) {
1093 ALOGE("%s: Stream %d: OUTPUT streams must have 0 for consumer usage",
1094 __FUNCTION__, streamId);
1095 return INVALID_OPERATION;
1096 }
1097 dstStream->setUsage(
1098 mapProducerToFrameworkUsage(src.producerUsage));
1099 if (flags::session_hal_buf_manager()) {
1100 dstStream->setHalBufferManager(
1101 contains(config->hal_buffer_managed_streams, streamId));
1102 }
1103 }
1104 dst->max_buffers = src.maxBuffers;
1105 }
1106
1107 return res;
1108 }
1109
configureInjectedStreams(const camera_metadata_t * sessionParams,camera_stream_configuration * config,const std::vector<uint32_t> & bufferSizes,const CameraMetadata & cameraCharacteristics)1110 status_t AidlCamera3Device::AidlHalInterface::configureInjectedStreams(
1111 const camera_metadata_t* sessionParams, camera_stream_configuration* config,
1112 const std::vector<uint32_t>& bufferSizes,
1113 const CameraMetadata& cameraCharacteristics) {
1114 using camera::device::StreamType;
1115 using camera::device::StreamConfigurationMode;
1116
1117 ATRACE_NAME("InjectionCameraHal::configureStreams");
1118 if (!valid()) return INVALID_OPERATION;
1119 status_t res = OK;
1120
1121 if (config->input_is_multi_resolution) {
1122 ALOGE("%s: Injection camera device doesn't support multi-resolution input "
1123 "stream", __FUNCTION__);
1124 return BAD_VALUE;
1125 }
1126
1127 // Convert stream config to AIDL
1128 std::set<int> activeStreams;
1129 camera::device::StreamConfiguration requestedConfiguration;
1130 requestedConfiguration.streams.resize(config->num_streams);
1131 for (size_t i = 0; i < config->num_streams; i++) {
1132 camera::device::Stream& dst = requestedConfiguration.streams[i];
1133 camera3::camera_stream_t* src = config->streams[i];
1134
1135 Camera3Stream* cam3stream = Camera3Stream::cast(src);
1136 cam3stream->setBufferFreedListener(this);
1137 int streamId = cam3stream->getId();
1138 StreamType streamType;
1139 switch (src->stream_type) {
1140 case CAMERA_STREAM_OUTPUT:
1141 streamType = StreamType::OUTPUT;
1142 break;
1143 case CAMERA_STREAM_INPUT:
1144 streamType = StreamType::INPUT;
1145 break;
1146 default:
1147 ALOGE("%s: Stream %d: Unsupported stream type %d", __FUNCTION__,
1148 streamId, config->streams[i]->stream_type);
1149 return BAD_VALUE;
1150 }
1151 dst.id = streamId;
1152 dst.streamType = streamType;
1153 dst.width = src->width;
1154 dst.height = src->height;
1155 dst.usage = mapToAidlConsumerUsage(cam3stream->getUsage());
1156 dst.rotation = mapToAidlStreamRotation((camera_stream_rotation_t)src->rotation);
1157 dst.format =
1158 mapToAidlPixelFormat(cam3stream->isFormatOverridden() ? cam3stream->getOriginalFormat()
1159 : src->format);
1160 dst.dataSpace =
1161 mapToAidlDataspace(cam3stream->isDataSpaceOverridden() ?
1162 cam3stream->getOriginalDataSpace() : src->data_space);
1163 dst.bufferSize = bufferSizes[i];
1164 if (!src->physical_camera_id.empty()) {
1165 dst.physicalCameraId = src->physical_camera_id;
1166 }
1167 dst.groupId = cam3stream->getHalStreamGroupId();
1168 dst.sensorPixelModesUsed.resize(src->sensor_pixel_modes_used.size());
1169 size_t j = 0;
1170 for (int mode : src->sensor_pixel_modes_used) {
1171 dst.sensorPixelModesUsed[j++] = static_cast<SensorPixelMode>(mode);
1172 }
1173 activeStreams.insert(streamId);
1174 // Create Buffer ID map if necessary
1175 mBufferRecords.tryCreateBufferCache(streamId);
1176 }
1177 // remove BufferIdMap for deleted streams
1178 mBufferRecords.removeInactiveBufferCaches(activeStreams);
1179
1180 StreamConfigurationMode operationMode;
1181 res = mapToAidlStreamConfigurationMode(
1182 (camera_stream_configuration_mode_t)config->operation_mode,
1183 /*out*/ &operationMode);
1184 if (res != OK) {
1185 return res;
1186 }
1187 requestedConfiguration.operationMode = operationMode;
1188 size_t sessionParamSize = get_camera_metadata_size(sessionParams);
1189 uint8_t *sessionParamP =
1190 reinterpret_cast<uint8_t*>(const_cast<camera_metadata_t*>(sessionParams));
1191 requestedConfiguration.operationMode = operationMode;
1192 requestedConfiguration.sessionParams.metadata.assign(
1193 sessionParamP, sessionParamP + sessionParamSize);
1194
1195 // See which version of HAL we have
1196 if (mAidlInjectionSession != nullptr) {
1197 requestedConfiguration.streamConfigCounter = mNextStreamConfigCounter++;
1198 requestedConfiguration.multiResolutionInputImage = config->input_is_multi_resolution;
1199
1200 const camera_metadata_t* rawMetadata = cameraCharacteristics.getAndLock();
1201 uint8_t *aidlCharsP =
1202 reinterpret_cast<uint8_t*>(const_cast<camera_metadata_t*>(rawMetadata));
1203 aidl::android::hardware::camera::device::CameraMetadata aidlChars;
1204 aidlChars.metadata.assign(aidlCharsP, aidlCharsP + get_camera_metadata_size(rawMetadata));
1205 cameraCharacteristics.unlock(rawMetadata);
1206
1207 auto err = mAidlInjectionSession->configureInjectionStreams(requestedConfiguration,
1208 aidlChars);
1209 if (!err.isOk()) {
1210 ALOGE("%s: Transaction error: %s", __FUNCTION__, err.getMessage());
1211 return AidlProviderInfo::mapToStatusT(err);
1212 }
1213 } else {
1214 ALOGE("%s: mAidlInjectionSession == nullptr, the injection not supported ", __FUNCTION__);
1215 return INVALID_OPERATION;
1216 }
1217
1218 return res;
1219 }
1220
processBatchCaptureRequests(std::vector<camera_capture_request_t * > & requests,uint32_t * numRequestProcessed)1221 status_t AidlCamera3Device::AidlHalInterface::processBatchCaptureRequests(
1222 std::vector<camera_capture_request_t*>& requests,/*out*/uint32_t* numRequestProcessed) {
1223 ATRACE_NAME("CameraHal::processBatchCaptureRequests");
1224 if (!valid()) return INVALID_OPERATION;
1225
1226 std::vector<camera::device::CaptureRequest> captureRequests;
1227 size_t batchSize = requests.size();
1228 if (batchSize > INT_MAX) {
1229 ALOGE("%s batchSize %zu > INT_MAX, aidl interface cannot handle batch size", __FUNCTION__,
1230 batchSize);
1231 return BAD_VALUE;
1232 }
1233 captureRequests.resize(batchSize);
1234 std::vector<native_handle_t*> handlesCreated;
1235 std::vector<std::pair<int32_t, int32_t>> inflightBuffers;
1236
1237 status_t res = OK;
1238 for (size_t i = 0; i < batchSize; i++) {
1239 res = wrapAsAidlRequest(requests[i], /*out*/&captureRequests[i],
1240 /*out*/&handlesCreated, /*out*/&inflightBuffers);
1241
1242 if (res != OK) {
1243 mBufferRecords.popInflightBuffers(inflightBuffers);
1244 cleanupNativeHandles(&handlesCreated);
1245 return res;
1246 }
1247 }
1248
1249 std::vector<camera::device::BufferCache> cachesToRemove;
1250 {
1251 std::lock_guard<std::mutex> lock(mFreedBuffersLock);
1252 for (auto& pair : mFreedBuffers) {
1253 // The stream might have been removed since onBufferFreed
1254 if (mBufferRecords.isStreamCached(pair.first)) {
1255 cachesToRemove.push_back({pair.first, static_cast<int64_t>(pair.second)});
1256 }
1257 }
1258 mFreedBuffers.clear();
1259 }
1260
1261 *numRequestProcessed = 0;
1262
1263 // Write metadata to FMQ.
1264 for (size_t i = 0; i < batchSize; i++) {
1265 camera_capture_request_t* request = requests[i];
1266 camera::device::CaptureRequest* captureRequest;
1267 captureRequest = &captureRequests[i];
1268
1269 if (request->settings != nullptr) {
1270 size_t settingsSize = get_camera_metadata_size(request->settings);
1271 if (mRequestMetadataQueue != nullptr && mRequestMetadataQueue->write(
1272 reinterpret_cast<const int8_t*>(request->settings), settingsSize)) {
1273 captureRequest->settings.metadata.resize(0);
1274 captureRequest->fmqSettingsSize = settingsSize;
1275 } else {
1276 if (mRequestMetadataQueue != nullptr) {
1277 ALOGW("%s: couldn't utilize fmq, fallback to hwbinder", __FUNCTION__);
1278 }
1279 uint8_t *settingsP =
1280 reinterpret_cast<uint8_t*>(
1281 const_cast<camera_metadata_t*>(request->settings));
1282 size_t settingsSize = get_camera_metadata_size(request->settings);
1283 captureRequest->settings.metadata.assign(settingsP, settingsP + settingsSize);
1284 captureRequest->fmqSettingsSize = 0u;
1285 }
1286 } else {
1287 // A null request settings maps to a size-0 CameraMetadata
1288 captureRequest->settings.metadata.resize(0);
1289 captureRequest->fmqSettingsSize = 0u;
1290 }
1291
1292 captureRequest ->inputWidth = request->input_width;
1293 captureRequest->inputHeight = request->input_height;
1294
1295 std::vector<camera::device::PhysicalCameraSetting>& physicalCameraSettings =
1296 captureRequest->physicalCameraSettings;
1297 physicalCameraSettings.resize(request->num_physcam_settings);
1298 for (size_t j = 0; j < request->num_physcam_settings; j++) {
1299 if (request->physcam_settings != nullptr) {
1300 size_t settingsSize = get_camera_metadata_size(request->physcam_settings[j]);
1301 if (mRequestMetadataQueue != nullptr && mRequestMetadataQueue->write(
1302 reinterpret_cast<const int8_t*>(request->physcam_settings[j]),
1303 settingsSize)) {
1304 physicalCameraSettings[j].settings.metadata.resize(0);
1305 physicalCameraSettings[j].fmqSettingsSize = settingsSize;
1306 } else {
1307 if (mRequestMetadataQueue != nullptr) {
1308 ALOGW("%s: couldn't utilize fmq, fallback to hwbinder", __FUNCTION__);
1309 }
1310 uint8_t *physicalSettingsP =
1311 reinterpret_cast<uint8_t*>(const_cast<camera_metadata_t*>(
1312 request->physcam_settings[j]));
1313 physicalCameraSettings[j].settings.metadata.assign(physicalSettingsP,
1314 physicalSettingsP + settingsSize);
1315 physicalCameraSettings[j].fmqSettingsSize = 0u;
1316 }
1317 } else {
1318 physicalCameraSettings[j].fmqSettingsSize = 0u;
1319 physicalCameraSettings[j].settings.metadata.resize(0);
1320 }
1321 physicalCameraSettings[j].physicalCameraId = request->physcam_id[j];
1322 }
1323 }
1324
1325 int32_t numRequests = 0;
1326 auto retS = mAidlSession->processCaptureRequest(captureRequests, cachesToRemove,
1327 &numRequests);
1328 if (!retS.isOk()) {
1329 res = AidlProviderInfo::mapToStatusT(retS);
1330 }
1331 if (res == OK) {
1332 if (numRequests < 0) {
1333 res = INVALID_OPERATION;
1334 } else {
1335 *numRequestProcessed = static_cast<uint32_t>(numRequests);
1336 }
1337
1338 }
1339 if (res == OK && *numRequestProcessed == batchSize) {
1340 if (mAidlSession->isRemote()) {
1341 // Only close acquire fence FDs when the AIDL transaction succeeds (so the FDs have been
1342 // sent to camera HAL processes)
1343 cleanupNativeHandles(&handlesCreated, /*closeFd*/true);
1344 } else {
1345 // In passthrough mode the FDs are now owned by HAL
1346 cleanupNativeHandles(&handlesCreated);
1347 }
1348 } else {
1349 ALOGE("%s Error with processCaptureRequest %s ", __FUNCTION__, retS.getMessage());
1350 mBufferRecords.popInflightBuffers(inflightBuffers);
1351 cleanupNativeHandles(&handlesCreated);
1352 }
1353 return res;
1354 }
1355
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)1356 status_t AidlCamera3Device::AidlHalInterface::wrapAsAidlRequest(camera_capture_request_t* request,
1357 /*out*/camera::device::CaptureRequest* captureRequest,
1358 /*out*/std::vector<native_handle_t*>* handlesCreated,
1359 /*out*/std::vector<std::pair<int32_t, int32_t>>* inflightBuffers) {
1360 using camera::device::BufferStatus;
1361 using camera::device::StreamBuffer;
1362 ATRACE_CALL();
1363 if (captureRequest == nullptr || handlesCreated == nullptr || inflightBuffers == nullptr) {
1364 ALOGE("%s: captureRequest (%p), handlesCreated (%p), and inflightBuffers(%p) "
1365 "must not be null", __FUNCTION__, captureRequest, handlesCreated, inflightBuffers);
1366 return BAD_VALUE;
1367 }
1368
1369 captureRequest->frameNumber = request->frame_number;
1370
1371 captureRequest->fmqSettingsSize = 0;
1372
1373 {
1374 if (request->input_buffer != nullptr) {
1375 int32_t streamId = Camera3Stream::cast(request->input_buffer->stream)->getId();
1376 buffer_handle_t buf = *(request->input_buffer->buffer);
1377 auto pair = getBufferId(buf, streamId);
1378 bool isNewBuffer = pair.first;
1379 uint64_t bufferId = pair.second;
1380 captureRequest->inputBuffer.streamId = streamId;
1381 captureRequest->inputBuffer.bufferId = bufferId;
1382 captureRequest->inputBuffer.buffer =
1383 (isNewBuffer) ? camera3::dupToAidlIfNotNull(buf) :
1384 aidl::android::hardware::common::NativeHandle();
1385 captureRequest->inputBuffer.status = BufferStatus::OK;
1386 native_handle_t *acquireFence = nullptr;
1387 if (request->input_buffer->acquire_fence != -1) {
1388 acquireFence = native_handle_create(1,0);
1389 acquireFence->data[0] = request->input_buffer->acquire_fence;
1390 handlesCreated->push_back(acquireFence);
1391 }
1392 // duping here is okay, in aidl ownership is not given to aidl_handle
1393 captureRequest->inputBuffer.acquireFence = camera3::dupToAidlIfNotNull(acquireFence);
1394 captureRequest->inputBuffer.releaseFence =
1395 aidl::android::hardware::common::NativeHandle();
1396
1397 mBufferRecords.pushInflightBuffer(captureRequest->frameNumber, streamId,
1398 request->input_buffer->buffer);
1399 inflightBuffers->push_back(std::make_pair(captureRequest->frameNumber, streamId));
1400 } else {
1401 captureRequest->inputBuffer.streamId = -1;
1402 captureRequest->inputBuffer.bufferId = BUFFER_ID_NO_BUFFER;
1403 }
1404
1405 captureRequest->outputBuffers.resize(request->num_output_buffers);
1406 for (size_t i = 0; i < request->num_output_buffers; i++) {
1407 const camera_stream_buffer_t *src = request->output_buffers + i;
1408 StreamBuffer &dst = captureRequest->outputBuffers[i];
1409 int32_t streamId = Camera3Stream::cast(src->stream)->getId();
1410 if (src->buffer != nullptr) {
1411 buffer_handle_t buf = *(src->buffer);
1412 auto pair = getBufferId(buf, streamId);
1413 bool isNewBuffer = pair.first;
1414 dst.bufferId = pair.second;
1415 dst.buffer = isNewBuffer ?
1416 camera3::dupToAidlIfNotNull(buf) :
1417 aidl::android::hardware::common::NativeHandle();
1418 native_handle_t *acquireFence = nullptr;
1419 if (src->acquire_fence != -1) {
1420 acquireFence = native_handle_create(1,0);
1421 acquireFence->data[0] = src->acquire_fence;
1422 handlesCreated->push_back(acquireFence);
1423 }
1424 dst.acquireFence = camera3::dupToAidlIfNotNull(acquireFence);
1425 } else if (isHalBufferManagedStream(streamId)) {
1426 // HAL buffer management path
1427 dst.bufferId = BUFFER_ID_NO_BUFFER;
1428 dst.buffer = aidl::android::hardware::common::NativeHandle();
1429 dst.acquireFence = aidl::android::hardware::common::NativeHandle();
1430 } else {
1431 ALOGE("%s: cannot send a null buffer in capture request!", __FUNCTION__);
1432 return BAD_VALUE;
1433 }
1434 dst.streamId = streamId;
1435 dst.status = BufferStatus::OK;
1436 dst.releaseFence = aidl::android::hardware::common::NativeHandle();
1437
1438 // Output buffers are empty when using HAL buffer manager
1439 if (!isHalBufferManagedStream(streamId)) {
1440 mBufferRecords.pushInflightBuffer(
1441 captureRequest->frameNumber, streamId, src->buffer);
1442 inflightBuffers->push_back(std::make_pair(captureRequest->frameNumber, streamId));
1443 }
1444 }
1445 }
1446 return OK;
1447 }
1448
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)1449 status_t AidlCamera3Device::AidlHalInterface::switchToOffline(
1450 const std::vector<int32_t>& streamsToKeep,
1451 /*out*/aidl::android::hardware::camera::device::CameraOfflineSessionInfo*
1452 offlineSessionInfo,
1453 /*out*/std::shared_ptr<aidl::android::hardware::camera::device::ICameraOfflineSession>*
1454 offlineSession,
1455 /*out*/camera3::BufferRecords* bufferRecords) {
1456 ATRACE_NAME("CameraHal::switchToOffline");
1457 if (!valid()) {
1458 ALOGE("%s called on invalid camera!", __FUNCTION__);
1459 return INVALID_OPERATION;
1460 }
1461
1462 if (offlineSessionInfo == nullptr || offlineSession == nullptr || bufferRecords == nullptr) {
1463 ALOGE("%s: output arguments must not be null!", __FUNCTION__);
1464 return INVALID_OPERATION;
1465 }
1466
1467 auto err = mAidlSession->switchToOffline(streamsToKeep, offlineSessionInfo, offlineSession);
1468
1469 if (!err.isOk()) {
1470 ALOGE("%s: Transaction error: %s", __FUNCTION__, err.getMessage());
1471 return AidlProviderInfo::mapToStatusT(err);
1472 }
1473
1474 return verifyBufferCaches(offlineSessionInfo, bufferRecords);
1475 }
1476
AidlRequestThread(wp<Camera3Device> parent,sp<camera3::StatusTracker> statusTracker,sp<HalInterface> interface,const Vector<int32_t> & sessionParamKeys,bool useHalBufManager,bool supportCameraMute,int rotationOverride,bool supportSettingsOverride)1477 AidlCamera3Device::AidlRequestThread::AidlRequestThread(wp<Camera3Device> parent,
1478 sp<camera3::StatusTracker> statusTracker,
1479 sp<HalInterface> interface,
1480 const Vector<int32_t>& sessionParamKeys,
1481 bool useHalBufManager,
1482 bool supportCameraMute,
1483 int rotationOverride,
1484 bool supportSettingsOverride) :
1485 RequestThread(parent, statusTracker, interface, sessionParamKeys,
1486 useHalBufManager, supportCameraMute, rotationOverride,
1487 supportSettingsOverride) {}
1488
switchToOffline(const std::vector<int32_t> & streamsToKeep,camera::device::CameraOfflineSessionInfo * offlineSessionInfo,std::shared_ptr<camera::device::ICameraOfflineSession> * offlineSession,camera3::BufferRecords * bufferRecords)1489 status_t AidlCamera3Device::AidlRequestThread::switchToOffline(
1490 const std::vector<int32_t>& streamsToKeep,
1491 /*out*/camera::device::CameraOfflineSessionInfo* offlineSessionInfo,
1492 /*out*/std::shared_ptr<camera::device::ICameraOfflineSession>* offlineSession,
1493 /*out*/camera3::BufferRecords* bufferRecords) {
1494 Mutex::Autolock l(mRequestLock);
1495 clearRepeatingRequestsLocked(/*lastFrameNumber*/nullptr);
1496
1497 // Wait until request thread is fully stopped
1498 // TBD: check if request thread is being paused by other APIs (shouldn't be)
1499
1500 // We could also check for mRepeatingRequests.empty(), but the API interface
1501 // is serialized by Camera3Device::mInterfaceLock so no one should be able to submit any
1502 // new requests during the call; hence skip that check.
1503 bool queueEmpty = mNextRequests.empty() && mRequestQueue.empty();
1504 while (!queueEmpty) {
1505 status_t res = mRequestSubmittedSignal.waitRelative(mRequestLock, kRequestSubmitTimeout);
1506 if (res == TIMED_OUT) {
1507 ALOGE("%s: request thread failed to submit one request within timeout!", __FUNCTION__);
1508 return res;
1509 } else if (res != OK) {
1510 ALOGE("%s: request thread failed to submit a request: %s (%d)!",
1511 __FUNCTION__, strerror(-res), res);
1512 return res;
1513 }
1514 queueEmpty = mNextRequests.empty() && mRequestQueue.empty();
1515 }
1516 return (static_cast<AidlHalInterface *>(mInterface.get()))->switchToOffline(
1517 streamsToKeep, offlineSessionInfo, offlineSession, bufferRecords);
1518 }
1519
injectionInitialize(const std::string & injectedCamId,sp<CameraProviderManager> manager,const std::shared_ptr<camera::device::ICameraDeviceCallback> & callback)1520 status_t AidlCamera3Device::AidlCamera3DeviceInjectionMethods::injectionInitialize(
1521 const std::string& injectedCamId, sp<CameraProviderManager> manager,
1522 const std::shared_ptr<camera::device::ICameraDeviceCallback>&callback) {
1523 ATRACE_CALL();
1524 Mutex::Autolock lock(mInjectionLock);
1525
1526 if (manager == nullptr) {
1527 ALOGE("%s: manager does not exist!", __FUNCTION__);
1528 return INVALID_OPERATION;
1529 }
1530
1531 sp<Camera3Device> parent = mParent.promote();
1532 if (parent == nullptr) {
1533 ALOGE("%s: parent does not exist!", __FUNCTION__);
1534 return INVALID_OPERATION;
1535 }
1536
1537 if (parent->getTransportType() != IPCTransport::AIDL) {
1538 ALOGE("%s Parent transport not AIDL for injected camera id %s, aborting", __FUNCTION__,
1539 injectedCamId.c_str());
1540 return INVALID_OPERATION;
1541 }
1542 mInjectedCamId = injectedCamId;
1543 std::shared_ptr<camera::device::ICameraInjectionSession> injectionSession;
1544 ATRACE_BEGIN("Injection CameraHal::openSession");
1545 status_t res = manager->openAidlInjectionSession(injectedCamId, callback,
1546 /*out*/ &injectionSession);
1547 ATRACE_END();
1548 if (res != OK) {
1549 ALOGE("Injection camera could not open camera session: %s (%d)",
1550 strerror(-res), res);
1551 return res;
1552 }
1553 std::shared_ptr<camera::device::ICameraDeviceSession> deviceSession = nullptr;
1554 auto ret = injectionSession->getCameraDeviceSession(&deviceSession);
1555 if (!ret.isOk() || deviceSession == nullptr) {
1556 ALOGE("%s Camera injection session couldn't return ICameraDeviceSession", __FUNCTION__);
1557 return AidlProviderInfo::mapToStatusT(ret);
1558 }
1559
1560 std::shared_ptr<AidlRequestMetadataQueue> queue;
1561 ::aidl::android::hardware::common::fmq::MQDescriptor<
1562 int8_t, ::aidl::android::hardware::common::fmq::SynchronizedReadWrite> desc;
1563
1564 ::ndk::ScopedAStatus requestQueueRet = deviceSession->getCaptureRequestMetadataQueue(&desc);
1565 if (!requestQueueRet.isOk()) {
1566 ALOGE("Injection camera transaction error when getting result metadata queue from camera"
1567 " session: %s", requestQueueRet.getMessage());
1568 return AidlProviderInfo::mapToStatusT(requestQueueRet);
1569 }
1570 queue = std::make_unique<AidlRequestMetadataQueue>(desc);
1571 if (!queue->isValid() || queue->availableToWrite() <= 0) {
1572 ALOGE("HAL returns empty result metadata fmq, not use it");
1573 queue = nullptr;
1574 // Don't use resQueue onwards.
1575 }
1576
1577 std::unique_ptr<AidlResultMetadataQueue>& resQueue = mInjectionResultMetadataQueue;
1578 ::aidl::android::hardware::common::fmq::MQDescriptor<
1579 int8_t, ::aidl::android::hardware::common::fmq::SynchronizedReadWrite> resDesc;
1580 ::ndk::ScopedAStatus resultQueueRet = deviceSession->getCaptureResultMetadataQueue(&resDesc);
1581 if (!resultQueueRet.isOk()) {
1582 ALOGE("Transaction error when getting result metadata queue from camera session: %s",
1583 resultQueueRet.getMessage());
1584 return AidlProviderInfo::mapToStatusT(resultQueueRet);
1585 }
1586 resQueue = std::make_unique<AidlResultMetadataQueue>(resDesc);
1587 if (!resQueue->isValid() || resQueue->availableToWrite() <= 0) {
1588 ALOGE("HAL returns empty result metadata fmq, not use it");
1589 resQueue = nullptr;
1590 // Don't use resQueue onwards.
1591 }
1592
1593 ALOGV("%s: Injection camera interface = new HalInterface()", __FUNCTION__);
1594
1595 mInjectedCamHalInterface =
1596 new AidlHalInterface(deviceSession, injectionSession, queue, parent->mUseHalBufManager,
1597 parent->mSupportOfflineProcessing, parent->mSessionHalBufManager);
1598 if (mInjectedCamHalInterface == nullptr) {
1599 ALOGE("%s: mInjectedCamHalInterface does not exist!", __FUNCTION__);
1600 return DEAD_OBJECT;
1601 }
1602
1603 return OK;
1604 }
1605
replaceHalInterface(sp<HalInterface> newHalInterface,bool keepBackup)1606 status_t AidlCamera3Device::AidlCamera3DeviceInjectionMethods::replaceHalInterface(
1607 sp<HalInterface> newHalInterface, bool keepBackup) {
1608 Mutex::Autolock lock(mInjectionLock);
1609 if (newHalInterface.get() == nullptr) {
1610 ALOGE("%s: The newHalInterface does not exist, to stop replacing.",
1611 __FUNCTION__);
1612 return DEAD_OBJECT;
1613 }
1614
1615 sp<Camera3Device> parent = mParent.promote();
1616 if (parent == nullptr) {
1617 ALOGE("%s: parent does not exist!", __FUNCTION__);
1618 return INVALID_OPERATION;
1619 }
1620 if (parent->getTransportType() != IPCTransport::AIDL ||
1621 newHalInterface->getTransportType() != IPCTransport::AIDL) {
1622 ALOGE("%s Parent transport not AIDL for replacing hal interface", __FUNCTION__);
1623 return INVALID_OPERATION;
1624 }
1625
1626 AidlCamera3Device *aidlParent = static_cast<AidlCamera3Device *>(parent.get());
1627 if (keepBackup) {
1628 if (mBackupHalInterface == nullptr) {
1629 mBackupHalInterface = parent->mInterface;
1630 }
1631 if (mBackupResultMetadataQueue == nullptr) {
1632 mBackupResultMetadataQueue = std::move(aidlParent->mResultMetadataQueue);
1633 aidlParent->mResultMetadataQueue = std::move(mInjectionResultMetadataQueue);
1634 }
1635 } else {
1636 mBackupHalInterface = nullptr;
1637 aidlParent->mResultMetadataQueue = std::move(mBackupResultMetadataQueue);
1638 mBackupResultMetadataQueue = nullptr;
1639 }
1640 parent->mInterface = newHalInterface;
1641 return OK;
1642 }
1643
applyMaxBatchSizeLocked(RequestList * requestList,const sp<camera3::Camera3OutputStreamInterface> & stream)1644 void AidlCamera3Device::applyMaxBatchSizeLocked(
1645 RequestList* requestList, const sp<camera3::Camera3OutputStreamInterface>& stream) {
1646 int batchSize = requestList->size();
1647
1648 if (!mBatchSizeLimitEnabled) {
1649 (*requestList->begin())->mBatchSize = batchSize;
1650 stream->setBatchSize(batchSize);
1651 return;
1652 }
1653
1654 const auto& metadata = (*requestList->begin())->mSettingsList.begin()->metadata;
1655
1656 uint32_t tag = ANDROID_CONTROL_AVAILABLE_HIGH_SPEED_VIDEO_CONFIGURATIONS;
1657 auto sensorPixelModeEntry = metadata.find(ANDROID_SENSOR_PIXEL_MODE);
1658 if (sensorPixelModeEntry.count != 0) {
1659 if (ANDROID_SENSOR_PIXEL_MODE_MAXIMUM_RESOLUTION == sensorPixelModeEntry.data.u8[0]) {
1660 tag = ANDROID_CONTROL_AVAILABLE_HIGH_SPEED_VIDEO_CONFIGURATIONS_MAXIMUM_RESOLUTION;
1661 }
1662 }
1663
1664 const auto fpsRange = metadata.find(ANDROID_CONTROL_AE_TARGET_FPS_RANGE);
1665 if (fpsRange.count > 1) {
1666 auto configEntry = mDeviceInfo.find(tag);
1667 for (size_t index = 4; index < configEntry.count; index += 5) {
1668 if (stream->getWidth() == static_cast<uint32_t>(configEntry.data.i32[index - 4]) &&
1669 stream->getHeight() == static_cast<uint32_t>(configEntry.data.i32[index - 3]) &&
1670 fpsRange.data.i32[0] == configEntry.data.i32[index - 2] &&
1671 fpsRange.data.i32[1] == configEntry.data.i32[index - 1]) {
1672 const int maxBatchSize = configEntry.data.i32[index - 1] / 30;
1673 const int reportedSize = configEntry.data.i32[index];
1674
1675 if (maxBatchSize % reportedSize == 0 && requestList->size() % reportedSize == 0) {
1676 batchSize = reportedSize;
1677 ALOGVV("Matching high speed configuration found. Limit batch size to %d",
1678 batchSize);
1679 } else if (maxBatchSize % reportedSize == 0 &&
1680 reportedSize % requestList->size() == 0) {
1681 ALOGVV("Matching high speed configuration found, but requested batch size is "
1682 "divisor of batch_size_max. No need to limit batch size.");
1683 } else {
1684 ALOGW("Matching high speed configuration found, but batch_size_max is not a "
1685 "divisor of corresponding fps_max/30 or requested batch size is not a "
1686 "divisor of batch_size_max, (fps_max %d, batch_size_max %d, requested "
1687 "batch size %zu)",
1688 configEntry.data.i32[index - 1], reportedSize, requestList->size());
1689 }
1690 break;
1691 }
1692 }
1693 }
1694
1695 for (auto request = requestList->begin(); request != requestList->end(); request++) {
1696 if (requestList->distance(requestList->begin(), request) % batchSize == 0) {
1697 (*request)->mBatchSize = batchSize;
1698 }
1699 }
1700
1701 stream->setBatchSize(batchSize);
1702 }
1703
injectionCameraInitialize(const std::string & injectedCamId,sp<CameraProviderManager> manager)1704 status_t AidlCamera3Device::injectionCameraInitialize(const std::string &injectedCamId,
1705 sp<CameraProviderManager> manager) {
1706 return (static_cast<AidlCamera3DeviceInjectionMethods *>
1707 (mInjectionMethods.get()))->injectionInitialize(injectedCamId, manager,
1708 std::shared_ptr<camera::device::ICameraDeviceCallback>(mCallbacks));
1709 };
1710
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)1711 sp<Camera3Device::RequestThread> AidlCamera3Device::createNewRequestThread(
1712 wp<Camera3Device> parent, sp<camera3::StatusTracker> statusTracker,
1713 sp<Camera3Device::HalInterface> interface,
1714 const Vector<int32_t>& sessionParamKeys,
1715 bool useHalBufManager,
1716 bool supportCameraMute,
1717 int rotationOverride,
1718 bool supportSettingsOverride) {
1719 return new AidlRequestThread(parent, statusTracker, interface, sessionParamKeys,
1720 useHalBufManager, supportCameraMute, rotationOverride,
1721 supportSettingsOverride);
1722 };
1723
1724 sp<Camera3Device::Camera3DeviceInjectionMethods>
createCamera3DeviceInjectionMethods(wp<Camera3Device> parent)1725 AidlCamera3Device::createCamera3DeviceInjectionMethods(wp<Camera3Device> parent) {
1726 return new AidlCamera3DeviceInjectionMethods(parent);
1727 }
1728
1729 }; // namespace android
1730