Skip to content

Commit faa66c9

Browse files
Copilotsds100
andcommitted
Refine FoldableAdapter: sealed class, StateFlow, API level check
- 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 <16245954+sds100@users.noreply.github.com>
1 parent 17cf309 commit faa66c9

File tree

4 files changed

+36
-27
lines changed

4 files changed

+36
-27
lines changed

base/src/main/java/io/github/sds100/keymapper/base/constraints/ConstraintSnapshot.kt

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import io.github.sds100.keymapper.system.camera.CameraAdapter
99
import io.github.sds100.keymapper.system.devices.DevicesAdapter
1010
import io.github.sds100.keymapper.system.display.DisplayAdapter
1111
import io.github.sds100.keymapper.system.hinge.FoldableAdapter
12+
import io.github.sds100.keymapper.system.hinge.HingeState
1213
import io.github.sds100.keymapper.system.inputmethod.InputMethodAdapter
1314
import io.github.sds100.keymapper.system.lock.LockScreenAdapter
1415
import io.github.sds100.keymapper.system.media.MediaAdapter
@@ -144,13 +145,17 @@ class LazyConstraintSnapshot(
144145
is ConstraintData.Discharging -> !isCharging
145146

146147
is ConstraintData.HingeClosed -> {
147-
val hingeState = foldableAdapter.getCachedHingeState()
148-
hingeState.isAvailable && hingeState.angle != null && hingeState.angle < 30f
148+
when (val state = foldableAdapter.hingeState.value) {
149+
is HingeState.Available -> state.angle < 30f
150+
is HingeState.Unavailable -> false
151+
}
149152
}
150153

151154
is ConstraintData.HingeOpen -> {
152-
val hingeState = foldableAdapter.getCachedHingeState()
153-
hingeState.isAvailable && hingeState.angle != null && hingeState.angle >= 150f
155+
when (val state = foldableAdapter.hingeState.value) {
156+
is HingeState.Available -> state.angle >= 150f
157+
is HingeState.Unavailable -> false
158+
}
154159
}
155160

156161
// The keyguard manager still reports the lock screen as showing if you are in

base/src/main/java/io/github/sds100/keymapper/base/constraints/CreateConstraintUseCase.kt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package io.github.sds100.keymapper.base.constraints
22

33
import android.content.pm.PackageManager
4+
import android.os.Build
45
import io.github.sds100.keymapper.common.utils.KMError
56
import io.github.sds100.keymapper.data.Keys
67
import io.github.sds100.keymapper.data.repositories.PreferenceRepository
@@ -30,6 +31,11 @@ class CreateConstraintUseCaseImpl @Inject constructor(
3031
return KMError.SystemFeatureNotSupported(PackageManager.FEATURE_CAMERA_FLASH)
3132
}
3233
}
34+
ConstraintId.HINGE_CLOSED, ConstraintId.HINGE_OPEN -> {
35+
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.R) {
36+
return KMError.SdkVersionTooLow(Build.VERSION_CODES.R)
37+
}
38+
}
3339
else -> Unit
3440
}
3541

system/src/main/java/io/github/sds100/keymapper/system/hinge/AndroidFoldableAdapter.kt

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ import android.hardware.Sensor
55
import android.hardware.SensorEvent
66
import android.hardware.SensorEventListener
77
import android.hardware.SensorManager
8+
import android.os.Build
9+
import androidx.annotation.RequiresApi
810
import androidx.core.content.getSystemService
911
import dagger.hilt.android.qualifiers.ApplicationContext
1012
import kotlinx.coroutines.flow.MutableStateFlow
@@ -14,12 +16,13 @@ import timber.log.Timber
1416
import javax.inject.Inject
1517
import javax.inject.Singleton
1618

19+
@RequiresApi(Build.VERSION_CODES.R)
1720
@Singleton
1821
class AndroidFoldableAdapter @Inject constructor(
1922
@ApplicationContext private val context: Context,
2023
) : FoldableAdapter {
2124

22-
private val _hingeState = MutableStateFlow(HingeState(isAvailable = false, angle = null))
25+
private val _hingeState = MutableStateFlow<HingeState>(HingeState.Unavailable)
2326
override val hingeState: StateFlow<HingeState> = _hingeState.asStateFlow()
2427

2528
private val sensorManager: SensorManager? = context.getSystemService()
@@ -30,10 +33,7 @@ class AndroidFoldableAdapter @Inject constructor(
3033
event?.let {
3134
if (it.sensor.type == Sensor.TYPE_HINGE_ANGLE && it.values.isNotEmpty()) {
3235
val angle = it.values[0]
33-
_hingeState.value = HingeState(
34-
isAvailable = true,
35-
angle = angle,
36-
)
36+
_hingeState.value = HingeState.Available(angle)
3737
}
3838
}
3939
}
@@ -58,13 +58,11 @@ class AndroidFoldableAdapter @Inject constructor(
5858
Timber.d("Hinge angle sensor monitoring started")
5959
} catch (e: Exception) {
6060
Timber.e(e, "Failed to start hinge angle sensor monitoring")
61-
_hingeState.value = HingeState(isAvailable = false, angle = null)
61+
_hingeState.value = HingeState.Unavailable
6262
}
6363
} else {
6464
Timber.d("Hinge angle sensor not available on this device")
65-
_hingeState.value = HingeState(isAvailable = false, angle = null)
65+
_hingeState.value = HingeState.Unavailable
6666
}
6767
}
68-
69-
override fun getCachedHingeState(): HingeState = _hingeState.value
7068
}
Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,31 +1,31 @@
11
package io.github.sds100.keymapper.system.hinge
22

3-
import kotlinx.coroutines.flow.Flow
3+
import androidx.annotation.RequiresApi
4+
import android.os.Build
5+
import kotlinx.coroutines.flow.StateFlow
46

57
/**
68
* Represents the state of a foldable device hinge.
79
*/
8-
data class HingeState(
10+
sealed class HingeState {
911
/**
10-
* True if the device has a hinge and it is currently available.
12+
* Hinge sensor is not available on this device.
1113
*/
12-
val isAvailable: Boolean,
14+
data object Unavailable : HingeState()
15+
1316
/**
14-
* The angle in degrees of the hinge. Null if hinge is not available.
17+
* Hinge sensor is available and reporting angle.
18+
* @param angle The angle in degrees of the hinge.
1519
* 0 degrees means the device is closed/flat.
1620
* 180 degrees means the device is fully open.
1721
*/
18-
val angle: Float?,
19-
)
22+
data class Available(val angle: Float) : HingeState()
23+
}
2024

25+
@RequiresApi(Build.VERSION_CODES.R)
2126
interface FoldableAdapter {
2227
/**
23-
* Flow that emits the current hinge state.
24-
*/
25-
val hingeState: Flow<HingeState>
26-
27-
/**
28-
* Get the current cached hinge state.
28+
* StateFlow that emits the current hinge state.
2929
*/
30-
fun getCachedHingeState(): HingeState
30+
val hingeState: StateFlow<HingeState>
3131
}

0 commit comments

Comments
 (0)