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