Skip to content

fix(android): align device orientation degrees#3993

Open
ludwig-pro wants to merge 1 commit into
mrousavy:mainfrom
ludwig-pro:fix/android-device-orientation-degrees
Open

fix(android): align device orientation degrees#3993
ludwig-pro wants to merge 1 commit into
mrousavy:mainfrom
ludwig-pro:fix/android-device-orientation-degrees

Conversation

@ludwig-pro

@ludwig-pro ludwig-pro commented Jun 3, 2026

Copy link
Copy Markdown

What

Align Android device-orientation degree mapping with the physical CameraOrientation semantics used by iOS.

0 -90° 90° 180
Portrait Left Right Down

OrientationEventListener reports physical device rotation degrees, but HybridDeviceOrientationManager previously reused CameraOrientation.fromDegrees(...), which maps 90°/270° for buffer/image orientation semantics.

This caused Android createOrientationManager('device') to report left/right mirrored compared to iOS for the same physical device pose.

This PR now applies the existing image/frame orientation mapper and counter-rotates it directly at the Android device-orientation callsite with fromDegrees(degrees).counterRotated(), leaving the existing fromDegrees(...) behavior unchanged for image/frame paths.

Test plan

  • Installed and launched the example app on a physical Pixel 9a; confirmed useOrientation('device') reports the right orientation
  • Temporarily validated the mapping with the local JUnit guard before removing JUnit from the final PR per review feedback
  • Verified no JUnit leftovers with rg -n "junit|CameraOrientationDeviceRotationDegreesTest" packages/react-native-vision-camera/android
  • cd apps/simple-camera/android && ./gradlew :react-native-vision-camera:compileDebugKotlin --console=plain

Record

Before

android-before-small

After

android-after-small

@vercel

vercel Bot commented Jun 3, 2026

Copy link
Copy Markdown

@ludwig-pro is attempting to deploy a commit to the Margelo Team on Vercel.

A member of the Team first needs to authorize it.

@mrousavy mrousavy left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - thanks for your PR!

This is much appreciated if it works, but we do testing differently. We don't test with JUnit (and adding the dependency here is not the way to go) - we test via full E2E testing on a real device via react-native-harness.

Please tell your agent to remove the JUnit tests.
Then, please add react-native-harness tests (vitest syntax). We can probably not add tests for device orientation changes as the device orientation is fixed in AWS, so if that cannot be tested with Harness then I guess there's no point in adding tests for that - then just the code is fine too.

Comment thread packages/react-native-vision-camera/android/build.gradle Outdated
@ludwig-pro ludwig-pro force-pushed the fix/android-device-orientation-degrees branch from 8d40536 to f11f303 Compare June 4, 2026 12:08
@ludwig-pro ludwig-pro requested a review from mrousavy June 4, 2026 12:11
}

fun CameraOrientation.Companion.fromDeviceRotationDegrees(degrees: Int): CameraOrientation {
return CameraOrientation.fromDegrees(degrees).counterRotated()

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But is it even correct for interface orientation then? Do we also counterRotate that or no

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, device and interface are a bit counter-intuitive because they don’t describe the same thing:

  • device describes how the phone is physically rotated, based on OrientationEventListener.
  • interface describes how the UI/display is rotated, based on Display.rotation / Surface.ROTATION_*.

So when the phone is physically rotated -90°, device reports left, but the UI needs to rotate +90° to stay readable, so interface reports right.

That’s why I think we should only apply counterRotated() on the device-orientation path, and leave interface orientation as-is.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you think it’s worth adding a small note to the docs?

Basically: device is the physical rotation from OrientationEventListener, while interface is the UI/display rotation from Display.rotation / Surface.ROTATION_*, so they can be opposite when the UI counter-rotates to stay readable ?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

screen-20260604-144429-1780577057012-under-10mb

@ludwig-pro ludwig-pro force-pushed the fix/android-device-orientation-degrees branch from f11f303 to bf5c0ae Compare June 4, 2026 12:13
@ludwig-pro ludwig-pro requested a review from mrousavy June 4, 2026 12:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants