-
-
Notifications
You must be signed in to change notification settings - Fork 225
Add foldable device constraints using Sensor API #1853
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 4 commits
de8ad46
e1a315a
7248549
17cf309
faa66c9
cea95d4
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -15,4 +15,5 @@ enum class ConstraintDependency { | |
| LOCK_SCREEN_SHOWING, | ||
| PHONE_STATE, | ||
| CHARGING_STATE, | ||
| HINGE_STATE, | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -49,5 +49,8 @@ enum class ConstraintId { | |
| CHARGING, | ||
| DISCHARGING, | ||
|
|
||
| HINGE_CLOSED, | ||
| HINGE_OPEN, | ||
|
|
||
| TIME, | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,70 @@ | ||
| package io.github.sds100.keymapper.system.hinge | ||
|
|
||
| import android.content.Context | ||
| import android.hardware.Sensor | ||
| import android.hardware.SensorEvent | ||
| import android.hardware.SensorEventListener | ||
| import android.hardware.SensorManager | ||
| import androidx.core.content.getSystemService | ||
| import dagger.hilt.android.qualifiers.ApplicationContext | ||
| import kotlinx.coroutines.flow.MutableStateFlow | ||
| import kotlinx.coroutines.flow.StateFlow | ||
| import kotlinx.coroutines.flow.asStateFlow | ||
| import timber.log.Timber | ||
| import javax.inject.Inject | ||
| import javax.inject.Singleton | ||
|
|
||
| @Singleton | ||
| class AndroidFoldableAdapter @Inject constructor( | ||
| @ApplicationContext private val context: Context, | ||
| ) : FoldableAdapter { | ||
|
|
||
| private val _hingeState = MutableStateFlow(HingeState(isAvailable = false, angle = null)) | ||
| override val hingeState: StateFlow<HingeState> = _hingeState.asStateFlow() | ||
|
|
||
| private val sensorManager: SensorManager? = context.getSystemService() | ||
| private val hingeSensor: Sensor? = sensorManager?.getDefaultSensor(Sensor.TYPE_HINGE_ANGLE) | ||
|
|
||
| private val sensorEventListener = object : SensorEventListener { | ||
| override fun onSensorChanged(event: SensorEvent?) { | ||
| event?.let { | ||
| if (it.sensor.type == Sensor.TYPE_HINGE_ANGLE && it.values.isNotEmpty()) { | ||
| val angle = it.values[0] | ||
| _hingeState.value = HingeState( | ||
| isAvailable = true, | ||
| angle = angle, | ||
| ) | ||
| } | ||
| } | ||
| } | ||
|
|
||
| override fun onAccuracyChanged(sensor: Sensor?, accuracy: Int) { | ||
| // Not needed for hinge angle sensor | ||
| } | ||
| } | ||
|
|
||
| init { | ||
| startMonitoring() | ||
| } | ||
|
|
||
| private fun startMonitoring() { | ||
| if (hingeSensor != null) { | ||
| try { | ||
| sensorManager?.registerListener( | ||
| sensorEventListener, | ||
| hingeSensor, | ||
| SensorManager.SENSOR_DELAY_NORMAL, | ||
| ) | ||
| Timber.d("Hinge angle sensor monitoring started") | ||
| } catch (e: Exception) { | ||
| Timber.e(e, "Failed to start hinge angle sensor monitoring") | ||
| _hingeState.value = HingeState(isAvailable = false, angle = null) | ||
| } | ||
| } else { | ||
| Timber.d("Hinge angle sensor not available on this device") | ||
| _hingeState.value = HingeState(isAvailable = false, angle = null) | ||
| } | ||
| } | ||
|
|
||
| override fun getCachedHingeState(): HingeState = _hingeState.value | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,31 @@ | ||
| package io.github.sds100.keymapper.system.hinge | ||
|
|
||
| import kotlinx.coroutines.flow.Flow | ||
|
|
||
| /** | ||
| * Represents the state of a foldable device hinge. | ||
| */ | ||
| data class HingeState( | ||
| /** | ||
| * True if the device has a hinge and it is currently available. | ||
| */ | ||
| val isAvailable: Boolean, | ||
|
||
| /** | ||
| * The angle in degrees of the hinge. Null if hinge is not available. | ||
| * 0 degrees means the device is closed/flat. | ||
| * 180 degrees means the device is fully open. | ||
| */ | ||
| val angle: Float?, | ||
| ) | ||
|
|
||
| interface FoldableAdapter { | ||
| /** | ||
| * Flow that emits the current hinge state. | ||
| */ | ||
| val hingeState: Flow<HingeState> | ||
|
||
|
|
||
| /** | ||
| * Get the current cached hinge state. | ||
| */ | ||
| fun getCachedHingeState(): HingeState | ||
| } | ||
Uh oh!
There was an error while loading. Please reload this page.