Skip to content

Conversation

Copy link
Contributor

Copilot AI commented Oct 25, 2025

Adds constraint support for detecting hinge state on foldable devices (Galaxy Fold, Pixel Fold, etc.), enabling key mappings that trigger based on device fold position.

Implementation

New Constraints

  • HINGE_CLOSED - angle < 30°
  • HINGE_OPEN - angle ≥ 150°

Architecture

  • FoldableAdapter interface with AndroidFoldableAdapter implementation using Android Sensor API
  • Uses Sensor.TYPE_HINGE_ANGLE for precise, real-time angle detection
  • Sealed class HingeState with Unavailable and Available(angle) states for type-safe state representation
  • Integrated into existing constraint system: ConstraintData, ConstraintEntity, DetectConstraintsUseCase, ConstraintSnapshot
  • Full serialization support for database persistence
  • UI components: strings, icons, selection handlers
  • Requires Android R (API 30) or higher with @RequiresApi annotations

Detection Logic
Uses hardware sensor for precise angle measurements:

  • Automatically registers SensorEventListener for TYPE_HINGE_ANGLE
  • Works seamlessly in background without Activity context
  • Real-time angle updates via sensor events
  • StateFlow-based state management

Constraint evaluation:

is ConstraintData.HingeClosed -> {
    when (val state = foldableAdapter.hingeState.value) {
        is HingeState.Available -> state.angle < 30f
        is HingeState.Unavailable -> false
    }
}

Benefits

  • ✅ Works in background without Activity context (uses Sensor API)
  • ✅ Precise angle measurements from hardware sensor
  • ✅ Automatic monitoring - no manual initialization needed
  • ✅ Type-safe sealed class pattern for state representation
  • ✅ Graceful degradation on non-foldable devices or older Android versions
  • ✅ API level validation (requires Android R / API 30+)

Files Changed

16 files: 2 new adapter files (FoldableAdapter with sealed class, AndroidFoldableAdapter), constraint system updates (Constraint.kt, ConstraintEntity.kt, CreateConstraintUseCase.kt with API validation, etc.), detection logic (DetectConstraintsUseCase.kt, ConstraintSnapshot.kt with pattern matching), UI layer (strings, icons, viewmodels), build dependencies

Original prompt

This section details on the original issue you should resolve

<issue_title>Hinge closed/open constraint for foldables</issue_title>
<issue_description>Developer TODO (don't remove)

  • create new branch. put issue number at start of name
  • update documentation
  • squash and merge
  • delete branch

Or the user could specify an angle degree.
Not that i have a foldable, but i noticed other applications do support for hinge detection.
</issue_description>

Comments on the Issue (you are @copilot in this section)

@sds100 Can they do this while running in the background though? @sds100 > Yeah, im pretty sure.

Do you have any examples of apps or documentation in Android developers?</comment_new>


✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.

Copilot AI changed the title [WIP] Add hinge closed/open constraint support for foldables Add hinge angle constraints for foldable devices Oct 25, 2025
Copilot AI requested a review from sds100 October 25, 2025 11:02
Copy link
Collaborator

@sds100 sds100 left a comment

Choose a reason for hiding this comment

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

@copilot Please implement my comments

* APIs work best with an active Activity context. Apps running in the background
* may not receive real-time hinge state updates.
*/
fun startMonitoring(activity: Activity) {
Copy link
Collaborator

Choose a reason for hiding this comment

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

@copilot

Is there no API to monitor this in the background? Can you not use the sensors API?

https://developer.android.com/reference/android/hardware/Sensor#STRING_TYPE_HINGE_ANGLE

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Switched to using Sensor.TYPE_HINGE_ANGLE from the SensorManager API. This provides real-time angle detection and works in the background without requiring an Activity context. The sensor automatically starts monitoring on initialization. (17cf309)

import javax.inject.Singleton

@Singleton
class AndroidHingeAdapter @Inject constructor(
Copy link
Collaborator

Choose a reason for hiding this comment

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

Rename this and the interface FoldableAdapter

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Renamed to FoldableAdapter and AndroidFoldableAdapter. (17cf309)


ConstraintEntity.HINGE_CLOSED -> ConstraintData.HingeClosed
ConstraintEntity.HINGE_OPEN -> ConstraintData.HingeOpen
ConstraintEntity.HINGE_ANGLE -> {
Copy link
Collaborator

Choose a reason for hiding this comment

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

@copilot

Do not do the hinge angle constraint.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Removed the HingeAngle constraint. Only HingeClosed and HingeOpen constraints remain. (17cf309)

… HingeAngle constraint

- Switch from WindowManager to SensorManager for background support
- Use Sensor.TYPE_HINGE_ANGLE for real-time angle detection
- Rename AndroidHingeAdapter to AndroidFoldableAdapter
- Rename HingeAdapter interface to FoldableAdapter
- Remove HingeAngle constraint (keep only HingeClosed and HingeOpen)
- Remove androidx.window dependency
- Update all references throughout codebase

Co-authored-by: sds100 <[email protected]>
Copilot AI changed the title Add hinge angle constraints for foldable devices Add foldable device constraints using Sensor API Oct 25, 2025
Copilot AI requested a review from sds100 October 25, 2025 11:23
Copy link
Collaborator

@sds100 sds100 left a comment

Choose a reason for hiding this comment

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

@copilot

Please review my comments.

/**
* Flow that emits the current hinge state.
*/
val hingeState: Flow<HingeState>
Copy link
Collaborator

Choose a reason for hiding this comment

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

@copilot Just make one StateFlow instead of a separate cached method.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Removed getCachedHingeState() method. Now using hingeState.value directly from the StateFlow. (faa66c9)

/**
* True if the device has a hinge and it is currently available.
*/
val isAvailable: Boolean,
Copy link
Collaborator

Choose a reason for hiding this comment

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

Create separate sealed class for Unavailable.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Created sealed class for HingeState with Unavailable and Available(angle: Float) states. Updated ConstraintSnapshot to use pattern matching with the sealed class. (faa66c9)

- Convert HingeState to sealed class with Unavailable and Available(angle) states
- Remove getCachedHingeState() method, use StateFlow.value directly
- Add @RequiresApi(Build.VERSION_CODES.R) annotations
- Add API level 30 minimum requirement check in CreateConstraintUseCase
- Update ConstraintSnapshot to use sealed class pattern matching

Co-authored-by: sds100 <[email protected]>
Copilot AI requested a review from sds100 October 25, 2025 11:55
@sds100 sds100 added this to the 4.0 milestone Oct 25, 2025
@sds100 sds100 merged commit cecbb02 into develop Oct 26, 2025
0 of 3 checks passed
@sds100 sds100 deleted the copilot/hinge-closed-open-constraint branch October 26, 2025 17:29
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.

Hinge closed/open constraint for foldables

2 participants