Skip to content

feat(android): rewrite sensor logic to improve reliability#103

Merged
gladiuscode merged 7 commits intomainfrom
feature/rework-android-orientation-logic
Mar 19, 2026
Merged

feat(android): rewrite sensor logic to improve reliability#103
gladiuscode merged 7 commits intomainfrom
feature/rework-android-orientation-logic

Conversation

@gladiuscode
Copy link
Owner

@gladiuscode gladiuscode commented Mar 18, 2026

Summary by CodeRabbit

  • New Features

    • More reliable device orientation detection via OS orientation events and rotation-vector sensor.
    • Face-up / face-down detection added; device and face orientation now use a unified public callback.
  • Bug Fixes

    • Suppressed duplicate or UNKNOWN orientation updates.
    • Ensured correct sensor enable/disable and listener lifecycle ordering.
  • Refactor

    • Consolidated orientation handling and removed legacy conversion helpers.

@gladiuscode gladiuscode self-assigned this Mar 18, 2026
@gladiuscode gladiuscode added enhancement New feature or request Android Android only labels Mar 18, 2026
@coderabbitai
Copy link

coderabbitai bot commented Mar 18, 2026

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Switched Android orientation handling to use Rotation Vector + OrientationEventListener; OrientationSensorsEventListener now reports device and face Orientation enums via a device-orientation callback, OrientationDirectorModuleImpl consumes device-orientation events, and two orientation conversion helpers were removed from Utils.

Changes

Cohort / File(s) Summary
Sensor listener & orientation logic
android/src/main/java/com/orientationdirector/implementation/OrientationSensorsEventListener.kt
Rewrote listener to implement OrientationEventListener, rely on TYPE_ROTATION_VECTOR only, compute rotation matrix to derive face orientation, map orientation angles to Orientation, suppress duplicate notifications, expose setOnDeviceOrientationChangedCallback, and simplify lifecycle registration (enable/disable).
Module callback integration
android/src/main/java/com/orientationdirector/implementation/OrientationDirectorModuleImpl.kt
Replaced angles-based callback with setOnDeviceOrientationChangedCallback, added onDeviceOrientationChanged(Orientation) handler, early-return on UNKNOWN/unchanged, preserved one-time initial-orientation computation and adjusted sensor enable/disable sequencing.
Utility cleanup
android/src/main/java/com/orientationdirector/implementation/Utils.kt
Removed convertToDeviceOrientationFrom(FloatArray) and convertToInterfaceOrientationFrom(Orientation) helpers; remaining conversion helpers unchanged.

Sequence Diagram(s)

sequenceDiagram
    actor RotationVectorSensor
    participant SensorListener as OrientationSensorsEventListener
    participant Module as OrientationDirectorModuleImpl
    participant JS as React/JS

    RotationVectorSensor->>SensorListener: SensorEvent(rotation vector)
    SensorListener->>SensorListener: getRotationMatrixFromVector()\ncompute face Z / map angles -> Device Orientation
    alt face orientation determined
        SensorListener-->>Module: notifyFaceOrientationChanged(Orientation)
    end
    SensorListener-->>Module: notifyDeviceOrientationChanged(Orientation)
    Module->>Module: onDeviceOrientationChanged(Orientation)\nreturn if UNKNOWN or unchanged
    Module-->>JS: emit orientation change event
    Module->>SensorListener: enable()/disable() (manage lifecycle)
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~40 minutes

Possibly related PRs

Poem

🐇 I twitch my whiskers at the spin,
Vectors whirl and new enums grin,
Face and device now sing in tune,
No more angles under the moon,
I hop — orientations begin ✨

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'rewrite sensor logic to improve reliability' accurately reflects the main changes: refactoring sensor event handling, simplifying orientation computation, and improving robustness through duplicate suppression and better control flow.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feature/rework-android-orientation-logic
📝 Coding Plan
  • Generate coding plan for human review comments

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
android/src/main/java/com/orientationdirector/implementation/OrientationDirectorModuleImpl.kt (1)

154-172: ⚠️ Potential issue | 🟠 Major

Don’t finalize initial orientation on flat states (FACE_UP/FACE_DOWN).

Line 168 marks initial orientation as computed for any non-UNKNOWN value. Because OrientationSensorsEventListener emits FACE_UP/FACE_DOWN via the same callback (OrientationSensorsEventListener.kt Line 108-Line 111), the module can disable sensors while still lacking a stable portrait/landscape orientation.

Proposed fix
   private fun onDeviceOrientationChanged(deviceOrientation: Orientation) {
     if (deviceOrientation == Orientation.UNKNOWN) return
-
     if (lastDeviceOrientation == deviceOrientation) return

     mEventManager.sendDeviceOrientationDidChange(deviceOrientation.ordinal)
     lastDeviceOrientation = deviceOrientation

     checkInterfaceOrientation()

     // NOTE(2.init): This is needed to disable sensors if they were needed just for the initial
     //  device computation.
-    if (didComputeInitialDeviceOrientation) return
+    val isFlatOrientation =
+      deviceOrientation == Orientation.FACE_UP || deviceOrientation == Orientation.FACE_DOWN
+    if (didComputeInitialDeviceOrientation || isFlatOrientation) return

     didComputeInitialDeviceOrientation = true

     if (!areOrientationSensorsEnabled) {
       mOrientationSensorsEventListener.disable()
     }
   }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@android/src/main/java/com/orientationdirector/implementation/OrientationDirectorModuleImpl.kt`
around lines 154 - 172, The onDeviceOrientationChanged function currently marks
didComputeInitialDeviceOrientation true for any non-UNKNOWN deviceOrientation,
causing FACE_UP/FACE_DOWN to finalize the initial state and potentially disable
sensors; change the logic in onDeviceOrientationChanged to ignore FACE_UP and
FACE_DOWN (i.e., only set didComputeInitialDeviceOrientation = true and disable
sensors when deviceOrientation is one of the stable orientations like PORTRAIT,
PORTRAIT_UPSIDE_DOWN, LANDSCAPE_LEFT, LANDSCAPE_RIGHT), and keep
lastDeviceOrientation and the early-return behavior intact so sensors aren’t
disabled prematurely.
🧹 Nitpick comments (1)
android/src/main/java/com/orientationdirector/implementation/OrientationSensorsEventListener.kt (1)

113-113: Replace empty override block to satisfy static analysis.

Line 113 is currently an empty function block and is flagged by detekt (EmptyFunctionBlock). Use an expression body instead.

Proposed fix
-  override fun onAccuracyChanged(p0: Sensor?, p1: Int) {}
+  override fun onAccuracyChanged(sensor: Sensor?, accuracy: Int) = Unit
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@android/src/main/java/com/orientationdirector/implementation/OrientationSensorsEventListener.kt`
at line 113, The override onAccuracyChanged in OrientationSensorsEventListener
currently has an empty function block which triggers detekt's
EmptyFunctionBlock; change it to an expression body (returning Unit) instead of
an empty block so the method stays explicit but non-empty — update the
declaration of onAccuracyChanged(p0: Sensor?, p1: Int) to use an expression body
(e.g., = Unit) to satisfy static analysis without changing behavior.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Outside diff comments:
In
`@android/src/main/java/com/orientationdirector/implementation/OrientationDirectorModuleImpl.kt`:
- Around line 154-172: The onDeviceOrientationChanged function currently marks
didComputeInitialDeviceOrientation true for any non-UNKNOWN deviceOrientation,
causing FACE_UP/FACE_DOWN to finalize the initial state and potentially disable
sensors; change the logic in onDeviceOrientationChanged to ignore FACE_UP and
FACE_DOWN (i.e., only set didComputeInitialDeviceOrientation = true and disable
sensors when deviceOrientation is one of the stable orientations like PORTRAIT,
PORTRAIT_UPSIDE_DOWN, LANDSCAPE_LEFT, LANDSCAPE_RIGHT), and keep
lastDeviceOrientation and the early-return behavior intact so sensors aren’t
disabled prematurely.

---

Nitpick comments:
In
`@android/src/main/java/com/orientationdirector/implementation/OrientationSensorsEventListener.kt`:
- Line 113: The override onAccuracyChanged in OrientationSensorsEventListener
currently has an empty function block which triggers detekt's
EmptyFunctionBlock; change it to an expression body (returning Unit) instead of
an empty block so the method stays explicit but non-empty — update the
declaration of onAccuracyChanged(p0: Sensor?, p1: Int) to use an expression body
(e.g., = Unit) to satisfy static analysis without changing behavior.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 54fbfb88-cef8-4a95-aefd-81ac92b2d270

📥 Commits

Reviewing files that changed from the base of the PR and between 32e6a84 and 1eff13e.

📒 Files selected for processing (3)
  • android/src/main/java/com/orientationdirector/implementation/OrientationDirectorModuleImpl.kt
  • android/src/main/java/com/orientationdirector/implementation/OrientationSensorsEventListener.kt
  • android/src/main/java/com/orientationdirector/implementation/Utils.kt
💤 Files with no reviewable changes (1)
  • android/src/main/java/com/orientationdirector/implementation/Utils.kt

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
android/src/main/java/com/orientationdirector/implementation/OrientationSensorsEventListener.kt (2)

34-54: ⚠️ Potential issue | 🟠 Major

Reset the cached orientations when the listener is re-enabled.

lastComputedDeviceOrientation and lastComputedFaceOrientation survive disable(). Re-enabling in the same pose then suppresses the first callback, so a fresh subscriber can stay stale until the next real rotation.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@android/src/main/java/com/orientationdirector/implementation/OrientationSensorsEventListener.kt`
around lines 34 - 54, The cached orientation fields
lastComputedDeviceOrientation and lastComputedFaceOrientation are left intact
across disable()/enable() which can suppress the first callback after
re-enabling; clear/reset these caches when (re)enabling the listener so
subscribers get an immediate fresh callback. In the
OrientationSensorsEventListener.enable() method (before registering the sensor
or right at start of the method) set lastComputedDeviceOrientation and
lastComputedFaceOrientation back to their initial/neutral state (e.g., null or
the same sentinel used on creation) so the first sensor event is treated as new;
you may also clear them in disable() if you prefer to keep state teardown there,
but ensure at least enable() resets them.

38-42: ⚠️ Potential issue | 🟡 Minor

SENSOR_DELAY_UI is in the wrong slot here.

The fourth argument maxReportLatencyUs must be an explicit microsecond value (e.g., 0 or a specific duration), not a sensor delay preset constant. Passing SensorManager.SENSOR_DELAY_UI (which equals 2) means the max report latency is only 2 microseconds, effectively disabling sensor event batching. The sampling rate remains SENSOR_DELAY_NORMAL from the third argument, but the batching configuration is incorrect.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@android/src/main/java/com/orientationdirector/implementation/OrientationSensorsEventListener.kt`
around lines 38 - 42, The registerListener call is passing
SensorManager.SENSOR_DELAY_UI as the fourth argument (maxReportLatencyUs), which
is incorrect; update the mSensorManager.registerListener(this, mRotationSensor,
SensorManager.SENSOR_DELAY_NORMAL, SensorManager.SENSOR_DELAY_UI) invocation to
pass an explicit microsecond latency value (e.g., 0L for no batching or a
specific microsecond duration) instead of SENSOR_DELAY_UI so maxReportLatencyUs
is set correctly; ensure you reference the same mSensorManager.registerListener
call and mRotationSensor and keep the sampling rate as
SensorManager.SENSOR_DELAY_NORMAL.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In
`@android/src/main/java/com/orientationdirector/implementation/OrientationSensorsEventListener.kt`:
- Around line 56-72: The method onOrientationChanged currently uses
lastComputedDeviceOrientation both as the "flat/unknown" flag and the dedupe
key, causing missed transitions; introduce a separate
lastEmittedDeviceOrientation (or similar) and use that for the dedupe check
instead of lastComputedDeviceOrientation. In onOrientationChanged, when
angleDegrees == ORIENTATION_UNKNOWN keep lastComputedDeviceOrientation =
Orientation.UNKNOWN (to represent the computed state) but do not update
lastEmittedDeviceOrientation or call notifyDeviceOrientationChanged; compute
currentDeviceOrientation from angleDegrees, compare it against
lastEmittedDeviceOrientation (not lastComputedDeviceOrientation), and only when
different call notifyDeviceOrientationChanged and then set
lastEmittedDeviceOrientation = currentDeviceOrientation (and optionally update
lastComputedDeviceOrientation too). Ensure you update references in the class to
use lastEmittedDeviceOrientation for all dedupe comparisons.

---

Outside diff comments:
In
`@android/src/main/java/com/orientationdirector/implementation/OrientationSensorsEventListener.kt`:
- Around line 34-54: The cached orientation fields lastComputedDeviceOrientation
and lastComputedFaceOrientation are left intact across disable()/enable() which
can suppress the first callback after re-enabling; clear/reset these caches when
(re)enabling the listener so subscribers get an immediate fresh callback. In the
OrientationSensorsEventListener.enable() method (before registering the sensor
or right at start of the method) set lastComputedDeviceOrientation and
lastComputedFaceOrientation back to their initial/neutral state (e.g., null or
the same sentinel used on creation) so the first sensor event is treated as new;
you may also clear them in disable() if you prefer to keep state teardown there,
but ensure at least enable() resets them.
- Around line 38-42: The registerListener call is passing
SensorManager.SENSOR_DELAY_UI as the fourth argument (maxReportLatencyUs), which
is incorrect; update the mSensorManager.registerListener(this, mRotationSensor,
SensorManager.SENSOR_DELAY_NORMAL, SensorManager.SENSOR_DELAY_UI) invocation to
pass an explicit microsecond latency value (e.g., 0L for no batching or a
specific microsecond duration) instead of SENSOR_DELAY_UI so maxReportLatencyUs
is set correctly; ensure you reference the same mSensorManager.registerListener
call and mRotationSensor and keep the sampling rate as
SensorManager.SENSOR_DELAY_NORMAL.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: c564161c-73d2-4a29-955d-1fe7f3186b19

📥 Commits

Reviewing files that changed from the base of the PR and between 1eff13e and b574664.

📒 Files selected for processing (1)
  • android/src/main/java/com/orientationdirector/implementation/OrientationSensorsEventListener.kt

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (2)
android/src/main/java/com/orientationdirector/implementation/OrientationSensorsEventListener.kt (2)

8-8: Unused import.

android.util.Log is imported but not used in this file.

🧹 Suggested removal
-import android.util.Log
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@android/src/main/java/com/orientationdirector/implementation/OrientationSensorsEventListener.kt`
at line 8, Remove the unused import `android.util.Log` from
OrientationSensorsEventListener.kt; open the file containing the
OrientationSensorsEventListener class (or related top-level functions) and
delete the `import android.util.Log` line, then run a quick build or lint to
confirm no remaining references to Log remain.

82-85: Face orientation transition to UNKNOWN is not emitted.

When lastComputedDeviceOrientation != UNKNOWN (device is no longer flat), lastComputedFaceOrientation is reset to UNKNOWN silently without invoking the callback. If consumers track face orientation state, they won't be notified when the device transitions away from FACE_UP/FACE_DOWN.

If this is intentional (face orientation only meaningful when device is flat), consider documenting this behavior. Otherwise, you may want to emit Orientation.UNKNOWN for face orientation before the early return.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@android/src/main/java/com/orientationdirector/implementation/OrientationSensorsEventListener.kt`
around lines 82 - 85, When lastComputedDeviceOrientation != Orientation.UNKNOWN
the code silently sets lastComputedFaceOrientation = Orientation.UNKNOWN and
returns; update this to also emit the face-orientation change (i.e., call the
face-orientation callback/notification) with Orientation.UNKNOWN before the
early return so consumers are notified, or alternatively add a clear
comment/docstring near lastComputedDeviceOrientation and
lastComputedFaceOrientation explaining that face orientation updates are
suppressed when the device is not flat; locate the logic around
lastComputedDeviceOrientation / lastComputedFaceOrientation in
OrientationSensorsEventListener.kt and either invoke the existing
face-orientation callback with Orientation.UNKNOWN before returning or add the
documentation explaining the intentional behavior.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In
`@android/src/main/java/com/orientationdirector/implementation/OrientationSensorsEventListener.kt`:
- Around line 95-99: The face-down detection logic in
OrientationSensorsEventListener.kt is using absPitch and comparing it to
FACE_DOWN_LIMIT (155°) which can never be exceeded because
SensorManager.getOrientation() returns pitch in [-90, +90], so absPitch >
FACE_DOWN_LIMIT is always false; update the logic that computes
currentFaceOrientation to check the signed pitch (e.g., pitch <
-FACE_DOWN_PITCH_THRESHOLD) instead of absPitch or reduce FACE_DOWN_LIMIT to a
realistic threshold within 0–90 and use absPitch > NEW_LIMIT, and keep the
existing roll check (absRoll) as a secondary condition — update references to
absPitch, FACE_DOWN_LIMIT and currentFaceOrientation accordingly so face-down
states are correctly detected.

---

Nitpick comments:
In
`@android/src/main/java/com/orientationdirector/implementation/OrientationSensorsEventListener.kt`:
- Line 8: Remove the unused import `android.util.Log` from
OrientationSensorsEventListener.kt; open the file containing the
OrientationSensorsEventListener class (or related top-level functions) and
delete the `import android.util.Log` line, then run a quick build or lint to
confirm no remaining references to Log remain.
- Around line 82-85: When lastComputedDeviceOrientation != Orientation.UNKNOWN
the code silently sets lastComputedFaceOrientation = Orientation.UNKNOWN and
returns; update this to also emit the face-orientation change (i.e., call the
face-orientation callback/notification) with Orientation.UNKNOWN before the
early return so consumers are notified, or alternatively add a clear
comment/docstring near lastComputedDeviceOrientation and
lastComputedFaceOrientation explaining that face orientation updates are
suppressed when the device is not flat; locate the logic around
lastComputedDeviceOrientation / lastComputedFaceOrientation in
OrientationSensorsEventListener.kt and either invoke the existing
face-orientation callback with Orientation.UNKNOWN before returning or add the
documentation explaining the intentional behavior.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 74589bf1-aa8e-438b-8694-d3d65b7e3654

📥 Commits

Reviewing files that changed from the base of the PR and between b574664 and fa2a279.

📒 Files selected for processing (1)
  • android/src/main/java/com/orientationdirector/implementation/OrientationSensorsEventListener.kt

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
android/src/main/java/com/orientationdirector/implementation/OrientationSensorsEventListener.kt (1)

17-17: Prune the leftover orientation-angle computation.

currentFaceOrientation only depends on rotationMatrix[8]. The orientationAngles field and the SensorManager.getOrientation(...) call are dead work on every rotation-vector sample now.

🧹 Suggested cleanup
   private val rotationMatrix = FloatArray(9)
-  private val orientationAngles = FloatArray(3)

     SensorManager.getRotationMatrixFromVector(rotationMatrix, event.values)
-    SensorManager.getOrientation(rotationMatrix, orientationAngles)

Also applies to: 87-88

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@android/src/main/java/com/orientationdirector/implementation/OrientationSensorsEventListener.kt`
at line 17, Remove the unused orientationAngles array and the dead call to
SensorManager.getOrientation(...) (and any assignments to orientationAngles)
since currentFaceOrientation only uses rotationMatrix[8]; locate the
orientationAngles declaration and usages in OrientationSensorsEventListener
(including lines around onSensorChanged where SensorManager.getOrientation is
called) and delete them, then replace any logic that relied on orientationAngles
with direct reads from rotationMatrix[8] (e.g., use rotationMatrix[8] when
computing currentFaceOrientation).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In
`@android/src/main/java/com/orientationdirector/implementation/OrientationSensorsEventListener.kt`:
- Around line 104-111: notifyDeviceOrientationChanged and
notifyFaceOrientationChanged overwrite caches after invoking the callback, which
lets a synchronous disable() call in the callback reset the caches only to have
the old value written back; to fix, capture the current cache value (e.g., prev
= lastComputedDeviceOrientation / lastComputedFaceOrientation) before calling
onDeviceOrientationChangedCallback, invoke the callback, then only assign
lastComputedDeviceOrientation = deviceOrientation (or
lastComputedFaceOrientation = faceOrientation) if the cache still equals prev
(meaning the callback did not call disable() or otherwise change it); reference
functions: notifyDeviceOrientationChanged, notifyFaceOrientationChanged,
onDeviceOrientationChangedCallback, lastComputedDeviceOrientation,
lastComputedFaceOrientation, and disable().

---

Nitpick comments:
In
`@android/src/main/java/com/orientationdirector/implementation/OrientationSensorsEventListener.kt`:
- Line 17: Remove the unused orientationAngles array and the dead call to
SensorManager.getOrientation(...) (and any assignments to orientationAngles)
since currentFaceOrientation only uses rotationMatrix[8]; locate the
orientationAngles declaration and usages in OrientationSensorsEventListener
(including lines around onSensorChanged where SensorManager.getOrientation is
called) and delete them, then replace any logic that relied on orientationAngles
with direct reads from rotationMatrix[8] (e.g., use rotationMatrix[8] when
computing currentFaceOrientation).

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 1e799a2d-eb58-4ab7-9e15-a7ae85bb4d2f

📥 Commits

Reviewing files that changed from the base of the PR and between fa2a279 and 44e708b.

📒 Files selected for processing (1)
  • android/src/main/java/com/orientationdirector/implementation/OrientationSensorsEventListener.kt

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
android/src/main/java/com/orientationdirector/implementation/OrientationSensorsEventListener.kt (1)

79-82: Silent reset of face orientation when device orientation becomes known.

When the device transitions from flat to tilted, lastComputedFaceOrientation is reset to UNKNOWN without notifying consumers. This means if a consumer previously received FACE_UP, they won't receive an explicit notification that face orientation is no longer valid.

This is likely acceptable since:

  1. The handler in OrientationDirectorModuleImpl filters out UNKNOWN values
  2. A non-unknown device orientation semantically supersedes face orientation

Just flagging for awareness in case consumers need to track face orientation end events.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@android/src/main/java/com/orientationdirector/implementation/OrientationSensorsEventListener.kt`
around lines 79 - 82, The code silently sets lastComputedFaceOrientation =
Orientation.UNKNOWN when lastComputedDeviceOrientation becomes known; instead
dispatch an explicit face-orientation update so consumers are notified of the
transition. Modify the block that currently sets lastComputedFaceOrientation
(look for lastComputedDeviceOrientation, lastComputedFaceOrientation, and
Orientation.UNKNOWN in OrientationSensorsEventListener.kt) to call the same
notification/emission path used elsewhere (the method or callback used by
OrientationDirectorModuleImpl to receive orientation updates) with
Orientation.UNKNOWN before changing the internal field so consumers receive the
“face orientation ended” event.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In
`@android/src/main/java/com/orientationdirector/implementation/OrientationSensorsEventListener.kt`:
- Around line 79-82: The code silently sets lastComputedFaceOrientation =
Orientation.UNKNOWN when lastComputedDeviceOrientation becomes known; instead
dispatch an explicit face-orientation update so consumers are notified of the
transition. Modify the block that currently sets lastComputedFaceOrientation
(look for lastComputedDeviceOrientation, lastComputedFaceOrientation, and
Orientation.UNKNOWN in OrientationSensorsEventListener.kt) to call the same
notification/emission path used elsewhere (the method or callback used by
OrientationDirectorModuleImpl to receive orientation updates) with
Orientation.UNKNOWN before changing the internal field so consumers receive the
“face orientation ended” event.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: f253b495-ac85-480e-b91c-a140cb2b7ab6

📥 Commits

Reviewing files that changed from the base of the PR and between 44e708b and c4c8a09.

📒 Files selected for processing (1)
  • android/src/main/java/com/orientationdirector/implementation/OrientationSensorsEventListener.kt

@gladiuscode gladiuscode merged commit ba58945 into main Mar 19, 2026
1 check passed
@gladiuscode gladiuscode deleted the feature/rework-android-orientation-logic branch March 19, 2026 20:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Android Android only enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant