xref: /aosp_15_r20/frameworks/av/services/camera/libcameraservice/device3/aidl/AidlCamera3Device.cpp (revision ec779b8e0859a360c3d303172224686826e6e0e1)
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