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/common/Camera2ClientBase.cpp b/services/camera/libcameraservice/common/Camera2ClientBase.cpp
index 95b4050..4555838 100644
--- a/services/camera/libcameraservice/common/Camera2ClientBase.cpp
+++ b/services/camera/libcameraservice/common/Camera2ClientBase.cpp
@@ -60,10 +60,11 @@
uid_t clientUid,
int servicePid,
bool overrideForPerfClass,
+ bool overrideToPortrait,
bool legacyClient):
TClientBase(cameraService, remoteCallback, clientPackageName, systemNativeClient,
clientFeatureId, cameraId, api1CameraId, cameraFacing, sensorOrientation, clientPid,
- clientUid, servicePid),
+ clientUid, servicePid, overrideToPortrait),
mSharedCameraCallbacks(remoteCallback),
mCameraServiceProxyWrapper(cameraServiceProxyWrapper),
mDeviceActive(false), mApi1CameraId(api1CameraId)
@@ -113,12 +114,14 @@
case IPCTransport::HIDL:
mDevice =
new HidlCamera3Device(mCameraServiceProxyWrapper,
- TClientBase::mCameraIdStr, mOverrideForPerfClass, mLegacyClient);
+ TClientBase::mCameraIdStr, mOverrideForPerfClass,
+ TClientBase::mOverrideToPortrait, mLegacyClient);
break;
case IPCTransport::AIDL:
mDevice =
new AidlCamera3Device(mCameraServiceProxyWrapper,
- TClientBase::mCameraIdStr, mOverrideForPerfClass, mLegacyClient);
+ TClientBase::mCameraIdStr, mOverrideForPerfClass,
+ TClientBase::mOverrideToPortrait, mLegacyClient);
break;
default:
ALOGE("%s Invalid transport for camera id %s", __FUNCTION__,
diff --git a/services/camera/libcameraservice/common/Camera2ClientBase.h b/services/camera/libcameraservice/common/Camera2ClientBase.h
index 37a7200..89347eb 100644
--- a/services/camera/libcameraservice/common/Camera2ClientBase.h
+++ b/services/camera/libcameraservice/common/Camera2ClientBase.h
@@ -61,6 +61,7 @@
uid_t clientUid,
int servicePid,
bool overrideForPerfClass,
+ bool overrideToPortrait,
bool legacyClient = false);
virtual ~Camera2ClientBase();
diff --git a/services/camera/libcameraservice/common/CameraProviderManager.cpp b/services/camera/libcameraservice/common/CameraProviderManager.cpp
index dc37c59..89c7459 100644
--- a/services/camera/libcameraservice/common/CameraProviderManager.cpp
+++ b/services/camera/libcameraservice/common/CameraProviderManager.cpp
@@ -323,13 +323,13 @@
}
status_t CameraProviderManager::getCameraInfo(const std::string &id,
- hardware::CameraInfo* info) const {
+ bool overrideToPortrait, int *portraitRotation, hardware::CameraInfo* info) const {
std::lock_guard<std::mutex> lock(mInterfaceMutex);
auto deviceInfo = findDeviceInfoLocked(id);
if (deviceInfo == nullptr) return NAME_NOT_FOUND;
- return deviceInfo->getCameraInfo(info);
+ return deviceInfo->getCameraInfo(overrideToPortrait, portraitRotation, info);
}
status_t CameraProviderManager::isSessionConfigurationSupported(const std::string& id,
@@ -361,9 +361,11 @@
}
status_t CameraProviderManager::getCameraCharacteristics(const std::string &id,
- bool overrideForPerfClass, CameraMetadata* characteristics) const {
+ bool overrideForPerfClass, CameraMetadata* characteristics,
+ bool overrideToPortrait) const {
std::lock_guard<std::mutex> lock(mInterfaceMutex);
- return getCameraCharacteristicsLocked(id, overrideForPerfClass, characteristics);
+ return getCameraCharacteristicsLocked(id, overrideForPerfClass, characteristics,
+ overrideToPortrait);
}
status_t CameraProviderManager::getHighestSupportedVersion(const std::string &id,
@@ -2031,7 +2033,9 @@
dprintf(fd, " Has a flash unit: %s\n",
device->hasFlashUnit() ? "true" : "false");
hardware::CameraInfo info;
- status_t res = device->getCameraInfo(&info);
+ int portraitRotation;
+ status_t res = device->getCameraInfo(/*overrideToPortrait*/false, &portraitRotation,
+ &info);
if (res != OK) {
dprintf(fd, " <Error reading camera info: %s (%d)>\n",
strerror(-res), res);
@@ -2041,7 +2045,8 @@
dprintf(fd, " Orientation: %d\n", info.orientation);
}
CameraMetadata info2;
- res = device->getCameraCharacteristics(true /*overrideForPerfClass*/, &info2);
+ res = device->getCameraCharacteristics(true /*overrideForPerfClass*/, &info2,
+ /*overrideToPortrait*/true);
if (res == INVALID_OPERATION) {
dprintf(fd, " API2 not directly supported\n");
} else if (res != OK) {
@@ -2313,6 +2318,7 @@
}
status_t CameraProviderManager::ProviderInfo::DeviceInfo3::getCameraInfo(
+ bool overrideToPortrait, int *portraitRotation,
hardware::CameraInfo *info) const {
if (info == nullptr) return BAD_VALUE;
@@ -2343,6 +2349,17 @@
return NAME_NOT_FOUND;
}
+ if (overrideToPortrait && (info->orientation == 0 || info->orientation == 180)) {
+ *portraitRotation = 90;
+ if (info->facing == hardware::CAMERA_FACING_FRONT) {
+ info->orientation = (360 + info->orientation - 90) % 360;
+ } else {
+ info->orientation = (360 + info->orientation + 90) % 360;
+ }
+ } else {
+ *portraitRotation = 0;
+ }
+
return OK;
}
bool CameraProviderManager::ProviderInfo::DeviceInfo3::isAPI1Compatible() const {
@@ -2368,7 +2385,7 @@
}
status_t CameraProviderManager::ProviderInfo::DeviceInfo3::getCameraCharacteristics(
- bool overrideForPerfClass, CameraMetadata *characteristics) const {
+ bool overrideForPerfClass, CameraMetadata *characteristics, bool overrideToPortrait) {
if (characteristics == nullptr) return BAD_VALUE;
if (!overrideForPerfClass && mCameraCharNoPCOverride != nullptr) {
@@ -2377,6 +2394,35 @@
*characteristics = mCameraCharacteristics;
}
+ if (overrideToPortrait) {
+ const auto &lensFacingEntry = characteristics->find(ANDROID_LENS_FACING);
+ const auto &sensorOrientationEntry = characteristics->find(ANDROID_SENSOR_ORIENTATION);
+ if (lensFacingEntry.count > 0 && sensorOrientationEntry.count > 0) {
+ uint8_t lensFacing = lensFacingEntry.data.u8[0];
+ int32_t sensorOrientation = sensorOrientationEntry.data.i32[0];
+ int32_t newSensorOrientation = sensorOrientation;
+
+ if (sensorOrientation == 0 || sensorOrientation == 180) {
+ if (lensFacing == ANDROID_LENS_FACING_FRONT) {
+ newSensorOrientation = (360 + sensorOrientation - 90) % 360;
+ } else if (lensFacing == ANDROID_LENS_FACING_BACK) {
+ newSensorOrientation = (360 + sensorOrientation + 90) % 360;
+ }
+ }
+
+ if (newSensorOrientation != sensorOrientation) {
+ ALOGV("%s: Update ANDROID_SENSOR_ORIENTATION for lens facing %d "
+ "from %d to %d", __FUNCTION__, lensFacing, sensorOrientation,
+ newSensorOrientation);
+ characteristics->update(ANDROID_SENSOR_ORIENTATION, &newSensorOrientation, 1);
+ }
+ }
+
+ if (characteristics->exists(ANDROID_INFO_DEVICE_STATE_ORIENTATIONS)) {
+ characteristics->erase(ANDROID_INFO_DEVICE_STATE_ORIENTATIONS);
+ }
+ }
+
return OK;
}
@@ -2706,10 +2752,12 @@
}
status_t CameraProviderManager::getCameraCharacteristicsLocked(const std::string &id,
- bool overrideForPerfClass, CameraMetadata* characteristics) const {
+ bool overrideForPerfClass, CameraMetadata* characteristics,
+ bool overrideToPortrait) const {
auto deviceInfo = findDeviceInfoLocked(id);
if (deviceInfo != nullptr) {
- return deviceInfo->getCameraCharacteristics(overrideForPerfClass, characteristics);
+ return deviceInfo->getCameraCharacteristics(overrideForPerfClass, characteristics,
+ overrideToPortrait);
}
// Find hidden physical camera characteristics
@@ -2744,7 +2792,9 @@
combo.push_back(deviceId);
hardware::CameraInfo info;
- status_t res = deviceInfo->getCameraInfo(&info);
+ int portraitRotation;
+ status_t res = deviceInfo->getCameraInfo(/*overrideToPortrait*/false, &portraitRotation,
+ &info);
if (res != OK) {
ALOGE("%s: Error reading camera info: %s (%d)", __FUNCTION__, strerror(-res), res);
continue;
diff --git a/services/camera/libcameraservice/common/CameraProviderManager.h b/services/camera/libcameraservice/common/CameraProviderManager.h
index 73a8b9c..ab1b389 100644
--- a/services/camera/libcameraservice/common/CameraProviderManager.h
+++ b/services/camera/libcameraservice/common/CameraProviderManager.h
@@ -257,14 +257,15 @@
* Return the old camera API camera info
*/
status_t getCameraInfo(const std::string &id,
- hardware::CameraInfo* info) const;
+ bool overrideToPortrait, int *portraitRotation, hardware::CameraInfo* info) const;
/**
* Return API2 camera characteristics - returns NAME_NOT_FOUND if a device ID does
* not have a v3 or newer HAL version.
*/
status_t getCameraCharacteristics(const std::string &id,
- bool overrideForPerfClass, CameraMetadata* characteristics) const;
+ bool overrideForPerfClass, CameraMetadata* characteristics,
+ bool overrideToPortrait) const;
status_t isConcurrentSessionConfigurationSupported(
const std::vector<hardware::camera2::utils::CameraIdAndSessionConfiguration>
@@ -566,13 +567,16 @@
virtual status_t setTorchMode(bool enabled) = 0;
virtual status_t turnOnTorchWithStrengthLevel(int32_t torchStrength) = 0;
virtual status_t getTorchStrengthLevel(int32_t *torchStrength) = 0;
- virtual status_t getCameraInfo(hardware::CameraInfo *info) const = 0;
+ virtual status_t getCameraInfo(bool overrideToPortrait,
+ int *portraitRotation,
+ hardware::CameraInfo *info) const = 0;
virtual bool isAPI1Compatible() const = 0;
virtual status_t dumpState(int fd) = 0;
virtual status_t getCameraCharacteristics(bool overrideForPerfClass,
- CameraMetadata *characteristics) const {
+ CameraMetadata *characteristics, bool overrideToPortrait) {
(void) overrideForPerfClass;
(void) characteristics;
+ (void) overrideToPortrait;
return INVALID_OPERATION;
}
virtual status_t getPhysicalCameraCharacteristics(const std::string& physicalCameraId,
@@ -629,12 +633,15 @@
virtual status_t setTorchMode(bool enabled) = 0;
virtual status_t turnOnTorchWithStrengthLevel(int32_t torchStrength) = 0;
virtual status_t getTorchStrengthLevel(int32_t *torchStrength) = 0;
- virtual status_t getCameraInfo(hardware::CameraInfo *info) const override;
+ virtual status_t getCameraInfo(bool overrideToPortrait,
+ int *portraitRotation,
+ hardware::CameraInfo *info) const override;
virtual bool isAPI1Compatible() const override;
virtual status_t dumpState(int fd) = 0;
virtual status_t getCameraCharacteristics(
bool overrideForPerfClass,
- CameraMetadata *characteristics) const override;
+ CameraMetadata *characteristics,
+ bool overrideToPortrait) override;
virtual status_t getPhysicalCameraCharacteristics(const std::string& physicalCameraId,
CameraMetadata *characteristics) const override;
virtual status_t isSessionConfigurationSupported(
@@ -833,7 +840,7 @@
const hardware::camera::common::V1_0::TorchModeStatus&);
status_t getCameraCharacteristicsLocked(const std::string &id, bool overrideForPerfClass,
- CameraMetadata* characteristics) const;
+ CameraMetadata* characteristics, bool overrideToPortrait) const;
void filterLogicalCameraIdsLocked(std::vector<std::string>& deviceIds) const;
status_t getSystemCameraKindLocked(const std::string& id, SystemCameraKind *kind) const;
diff --git a/services/camera/libcameraservice/common/aidl/AidlProviderInfo.cpp b/services/camera/libcameraservice/common/aidl/AidlProviderInfo.cpp
index c034bbf..5a449b6 100644
--- a/services/camera/libcameraservice/common/aidl/AidlProviderInfo.cpp
+++ b/services/camera/libcameraservice/common/aidl/AidlProviderInfo.cpp
@@ -769,7 +769,8 @@
bool overrideForPerfClass =
SessionConfigurationUtils::targetPerfClassPrimaryCamera(
perfClassPrimaryCameraIds, cameraId, targetSdkVersion);
- res = mManager->getCameraCharacteristicsLocked(cameraId, overrideForPerfClass, &deviceInfo);
+ res = mManager->getCameraCharacteristicsLocked(cameraId, overrideForPerfClass, &deviceInfo,
+ /*overrideToPortrait*/true);
if (res != OK) {
return res;
}
@@ -777,7 +778,7 @@
[this](const String8 &id, bool overrideForPerfClass) {
CameraMetadata physicalDeviceInfo;
mManager->getCameraCharacteristicsLocked(id.string(), overrideForPerfClass,
- &physicalDeviceInfo);
+ &physicalDeviceInfo, /*overrideToPortrait*/true);
return physicalDeviceInfo;
};
std::vector<std::string> physicalCameraIds;
diff --git a/services/camera/libcameraservice/common/hidl/HidlProviderInfo.cpp b/services/camera/libcameraservice/common/hidl/HidlProviderInfo.cpp
index cc55c6c..258d5fd 100644
--- a/services/camera/libcameraservice/common/hidl/HidlProviderInfo.cpp
+++ b/services/camera/libcameraservice/common/hidl/HidlProviderInfo.cpp
@@ -924,7 +924,8 @@
bool overrideForPerfClass =
SessionConfigurationUtils::targetPerfClassPrimaryCamera(
perfClassPrimaryCameraIds, cameraId, targetSdkVersion);
- res = mManager->getCameraCharacteristicsLocked(cameraId, overrideForPerfClass, &deviceInfo);
+ res = mManager->getCameraCharacteristicsLocked(cameraId, overrideForPerfClass, &deviceInfo,
+ /*overrideToPortrait*/true);
if (res != OK) {
return res;
}
@@ -932,7 +933,7 @@
[this](const String8 &id, bool overrideForPerfClass) {
CameraMetadata physicalDeviceInfo;
mManager->getCameraCharacteristicsLocked(id.string(), overrideForPerfClass,
- &physicalDeviceInfo);
+ &physicalDeviceInfo, /*overrideToPortrait*/true);
return physicalDeviceInfo;
};
std::vector<std::string> physicalCameraIds;