libcameraservice: Provide flag for overriding camera output to portrait.
Apps commonly do not handle landscape orientation cameras correctly. In
order to prevent stretching and rotation issues in these apps, this
patch adds a flag to override the behavior of these landscape cameras
to produce a portrait image instead by changing the SENSOR_ORIENTATION
reported by CameraCharacteristics and applying a 90 degree rotate and
crop.
Bug: 250678880
Test: Ran on foldable device with several camera apps to verify behavior.
Merged-In: I64ed52812326edc11f1cdb6bfbdbe75fcb8b1fb8
Change-Id: Iea30befecf297cc5c6ab4af2424027e995190fed
diff --git a/services/camera/libcameraservice/device3/Camera3Device.cpp b/services/camera/libcameraservice/device3/Camera3Device.cpp
index 8d85b82..7b5ccc8 100644
--- a/services/camera/libcameraservice/device3/Camera3Device.cpp
+++ b/services/camera/libcameraservice/device3/Camera3Device.cpp
@@ -73,7 +73,7 @@
namespace android {
Camera3Device::Camera3Device(std::shared_ptr<CameraServiceProxyWrapper>& cameraServiceProxyWrapper,
- const String8 &id, bool overrideForPerfClass, bool legacyClient):
+ const String8 &id, bool overrideForPerfClass, bool overrideToPortrait, bool legacyClient):
mCameraServiceProxyWrapper(cameraServiceProxyWrapper),
mId(id),
mLegacyClient(legacyClient),
@@ -95,7 +95,8 @@
mVendorTagId(CAMERA_METADATA_INVALID_VENDOR_ID),
mLastTemplateId(-1),
mNeedFixupMonochromeTags(false),
- mOverrideForPerfClass(overrideForPerfClass)
+ mOverrideForPerfClass(overrideForPerfClass),
+ mOverrideToPortrait(overrideToPortrait)
{
ATRACE_CALL();
ALOGV("%s: Created device for camera %s", __FUNCTION__, mId.string());
@@ -167,7 +168,7 @@
/** Start up request queue thread */
mRequestThread = createNewRequestThread(
this, mStatusTracker, mInterface, sessionParamKeys,
- mUseHalBufManager, mSupportCameraMute);
+ mUseHalBufManager, mSupportCameraMute, mOverrideToPortrait);
res = mRequestThread->run(String8::format("C3Dev-%s-ReqQueue", mId.string()).string());
if (res != OK) {
SET_ERR_L("Unable to start request queue thread: %s (%d)",
@@ -2906,7 +2907,8 @@
sp<StatusTracker> statusTracker,
sp<HalInterface> interface, const Vector<int32_t>& sessionParamKeys,
bool useHalBufManager,
- bool supportCameraMute) :
+ bool supportCameraMute,
+ bool overrideToPortrait) :
Thread(/*canCallJava*/false),
mParent(parent),
mStatusTracker(statusTracker),
@@ -2936,7 +2938,8 @@
mSessionParamKeys(sessionParamKeys),
mLatestSessionParams(sessionParamKeys.size()),
mUseHalBufManager(useHalBufManager),
- mSupportCameraMute(supportCameraMute){
+ mSupportCameraMute(supportCameraMute),
+ mOverrideToPortrait(overrideToPortrait) {
mStatusId = statusTracker->addComponent("RequestThread");
}
@@ -3605,9 +3608,9 @@
mPrevTriggers = triggerCount;
// Do not override rotate&crop for stream configurations that include
- // SurfaceViews(HW_COMPOSER) output. The display rotation there will be
- // compensated by NATIVE_WINDOW_TRANSFORM_INVERSE_DISPLAY
- bool rotateAndCropChanged = mComposerOutput ? false :
+ // SurfaceViews(HW_COMPOSER) output, unless mOverrideToPortrait is set.
+ // The display rotation there will be compensated by NATIVE_WINDOW_TRANSFORM_INVERSE_DISPLAY
+ bool rotateAndCropChanged = (mComposerOutput && !mOverrideToPortrait) ? false :
overrideAutoRotateAndCrop(captureRequest);
bool autoframingChanged = overrideAutoframing(captureRequest);
bool testPatternChanged = overrideTestPattern(captureRequest);
@@ -4666,6 +4669,15 @@
const sp<CaptureRequest> &request) {
ATRACE_CALL();
+ if (mOverrideToPortrait) {
+ Mutex::Autolock l(mTriggerMutex);
+ uint8_t rotateAndCrop_u8 = mRotateAndCropOverride;
+ CameraMetadata &metadata = request->mSettingsList.begin()->metadata;
+ metadata.update(ANDROID_SCALER_ROTATE_AND_CROP,
+ &rotateAndCrop_u8, 1);
+ return true;
+ }
+
if (request->mRotateAndCropAuto) {
Mutex::Autolock l(mTriggerMutex);
CameraMetadata &metadata = request->mSettingsList.begin()->metadata;