summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--packages/SystemUI/shared/src/com/android/systemui/unfold/UnfoldTransitionFactory.kt8
-rw-r--r--packages/SystemUI/shared/src/com/android/systemui/unfold/progress/PhysicsBasedUnfoldTransitionProgressProvider.kt27
-rw-r--r--packages/SystemUI/shared/src/com/android/systemui/unfold/updates/DeviceFoldStateProvider.kt116
-rw-r--r--packages/SystemUI/shared/src/com/android/systemui/unfold/updates/FoldStateProvider.kt10
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/unfold/updates/DeviceFoldStateProviderTest.kt126
5 files changed, 229 insertions, 58 deletions
diff --git a/packages/SystemUI/shared/src/com/android/systemui/unfold/UnfoldTransitionFactory.kt b/packages/SystemUI/shared/src/com/android/systemui/unfold/UnfoldTransitionFactory.kt
index e46b6f12e4a3..ea93a3b9375e 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/unfold/UnfoldTransitionFactory.kt
+++ b/packages/SystemUI/shared/src/com/android/systemui/unfold/UnfoldTransitionFactory.kt
@@ -60,14 +60,12 @@ fun createUnfoldTransitionProgressProvider(
hingeAngleProvider,
screenStatusProvider,
deviceStateManager,
- mainExecutor
+ mainExecutor,
+ mainHandler
)
val unfoldTransitionProgressProvider = if (config.isHingeAngleEnabled) {
- PhysicsBasedUnfoldTransitionProgressProvider(
- mainHandler,
- foldStateProvider
- )
+ PhysicsBasedUnfoldTransitionProgressProvider(foldStateProvider)
} else {
FixedTimingTransitionProgressProvider(foldStateProvider)
}
diff --git a/packages/SystemUI/shared/src/com/android/systemui/unfold/progress/PhysicsBasedUnfoldTransitionProgressProvider.kt b/packages/SystemUI/shared/src/com/android/systemui/unfold/progress/PhysicsBasedUnfoldTransitionProgressProvider.kt
index 90f5998053b8..51eae573f040 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/unfold/progress/PhysicsBasedUnfoldTransitionProgressProvider.kt
+++ b/packages/SystemUI/shared/src/com/android/systemui/unfold/progress/PhysicsBasedUnfoldTransitionProgressProvider.kt
@@ -15,7 +15,6 @@
*/
package com.android.systemui.unfold.progress
-import android.os.Handler
import android.util.Log
import android.util.MathUtils.saturate
import androidx.dynamicanimation.animation.DynamicAnimation
@@ -24,9 +23,10 @@ import androidx.dynamicanimation.animation.SpringAnimation
import androidx.dynamicanimation.animation.SpringForce
import com.android.systemui.unfold.UnfoldTransitionProgressProvider
import com.android.systemui.unfold.UnfoldTransitionProgressProvider.TransitionProgressListener
+import com.android.systemui.unfold.updates.FOLD_UPDATE_ABORTED
import com.android.systemui.unfold.updates.FOLD_UPDATE_FINISH_CLOSED
-import com.android.systemui.unfold.updates.FOLD_UPDATE_FINISH_FULL_OPEN
import com.android.systemui.unfold.updates.FOLD_UPDATE_START_CLOSING
+import com.android.systemui.unfold.updates.FOLD_UPDATE_FINISH_FULL_OPEN
import com.android.systemui.unfold.updates.FOLD_UPDATE_UNFOLDED_SCREEN_AVAILABLE
import com.android.systemui.unfold.updates.FoldStateProvider
import com.android.systemui.unfold.updates.FoldStateProvider.FoldUpdate
@@ -39,7 +39,6 @@ import com.android.systemui.unfold.updates.FoldStateProvider.FoldUpdatesListener
* - doesn't handle postures
*/
internal class PhysicsBasedUnfoldTransitionProgressProvider(
- private val handler: Handler,
private val foldStateProvider: FoldStateProvider
) :
UnfoldTransitionProgressProvider,
@@ -51,8 +50,6 @@ internal class PhysicsBasedUnfoldTransitionProgressProvider(
addEndListener(this@PhysicsBasedUnfoldTransitionProgressProvider)
}
- private val timeoutRunnable = TimeoutRunnable()
-
private var isTransitionRunning = false
private var isAnimatedCancelRunning = false
@@ -92,7 +89,7 @@ internal class PhysicsBasedUnfoldTransitionProgressProvider(
cancelTransition(endValue = 1f, animate = true)
}
}
- FOLD_UPDATE_FINISH_FULL_OPEN -> {
+ FOLD_UPDATE_FINISH_FULL_OPEN, FOLD_UPDATE_ABORTED -> {
// Do not cancel if we haven't started the transition yet.
// This could happen when we fully unfolded the device before the screen
// became available. In this case we start and immediately cancel the animation
@@ -106,7 +103,11 @@ internal class PhysicsBasedUnfoldTransitionProgressProvider(
cancelTransition(endValue = 0f, animate = false)
}
FOLD_UPDATE_START_CLOSING -> {
- startTransition(startValue = 1f)
+ // The transition might be already running as the device might start closing several
+ // times before reaching an end state.
+ if (!isTransitionRunning) {
+ startTransition(startValue = 1f)
+ }
}
}
@@ -116,8 +117,6 @@ internal class PhysicsBasedUnfoldTransitionProgressProvider(
}
private fun cancelTransition(endValue: Float, animate: Boolean) {
- handler.removeCallbacks(timeoutRunnable)
-
if (isTransitionRunning && animate) {
isAnimatedCancelRunning = true
springAnimation.animateToFinalPosition(endValue)
@@ -175,8 +174,6 @@ internal class PhysicsBasedUnfoldTransitionProgressProvider(
}
springAnimation.start()
-
- handler.postDelayed(timeoutRunnable, TRANSITION_TIMEOUT_MILLIS)
}
override fun addCallback(listener: TransitionProgressListener) {
@@ -187,13 +184,6 @@ internal class PhysicsBasedUnfoldTransitionProgressProvider(
listeners.remove(listener)
}
- private inner class TimeoutRunnable : Runnable {
-
- override fun run() {
- cancelTransition(endValue = 1f, animate = true)
- }
- }
-
private object AnimationProgressProperty :
FloatPropertyCompat<PhysicsBasedUnfoldTransitionProgressProvider>("animation_progress") {
@@ -212,7 +202,6 @@ internal class PhysicsBasedUnfoldTransitionProgressProvider(
private const val TAG = "PhysicsBasedUnfoldTransitionProgressProvider"
private const val DEBUG = true
-private const val TRANSITION_TIMEOUT_MILLIS = 2000L
private const val SPRING_STIFFNESS = 200.0f
private const val MINIMAL_VISIBLE_CHANGE = 0.001f
private const val FINAL_HINGE_ANGLE_POSITION = 165f
diff --git a/packages/SystemUI/shared/src/com/android/systemui/unfold/updates/DeviceFoldStateProvider.kt b/packages/SystemUI/shared/src/com/android/systemui/unfold/updates/DeviceFoldStateProvider.kt
index 35e2b30d0a39..6d9631c12430 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/unfold/updates/DeviceFoldStateProvider.kt
+++ b/packages/SystemUI/shared/src/com/android/systemui/unfold/updates/DeviceFoldStateProvider.kt
@@ -15,14 +15,19 @@
*/
package com.android.systemui.unfold.updates
+import android.annotation.FloatRange
import android.content.Context
import android.hardware.devicestate.DeviceStateManager
+import android.os.Handler
+import android.util.Log
+import androidx.annotation.VisibleForTesting
import androidx.core.util.Consumer
-import com.android.systemui.unfold.updates.screen.ScreenStatusProvider
import com.android.systemui.unfold.updates.FoldStateProvider.FoldUpdate
import com.android.systemui.unfold.updates.FoldStateProvider.FoldUpdatesListener
+import com.android.systemui.unfold.updates.hinge.FULLY_CLOSED_DEGREES
import com.android.systemui.unfold.updates.hinge.FULLY_OPEN_DEGREES
import com.android.systemui.unfold.updates.hinge.HingeAngleProvider
+import com.android.systemui.unfold.updates.screen.ScreenStatusProvider
import java.util.concurrent.Executor
class DeviceFoldStateProvider(
@@ -30,7 +35,8 @@ class DeviceFoldStateProvider(
private val hingeAngleProvider: HingeAngleProvider,
private val screenStatusProvider: ScreenStatusProvider,
private val deviceStateManager: DeviceStateManager,
- private val mainExecutor: Executor
+ private val mainExecutor: Executor,
+ private val handler: Handler
) : FoldStateProvider {
private val outputListeners: MutableList<FoldUpdatesListener> = mutableListOf()
@@ -38,9 +44,13 @@ class DeviceFoldStateProvider(
@FoldUpdate
private var lastFoldUpdate: Int? = null
+ @FloatRange(from = 0.0, to = 180.0)
+ private var lastHingeAngle: Float = 0f
+
private val hingeAngleListener = HingeAngleListener()
private val screenListener = ScreenStatusListener()
private val foldStateListener = FoldStateListener(context)
+ private val timeoutRunnable = TimeoutRunnable()
private var isFolded = false
private var isUnfoldHandled = true
@@ -72,47 +82,69 @@ class DeviceFoldStateProvider(
override val isFullyOpened: Boolean
get() = !isFolded && lastFoldUpdate == FOLD_UPDATE_FINISH_FULL_OPEN
+ private val isTransitionInProgess: Boolean
+ get() = lastFoldUpdate == FOLD_UPDATE_START_OPENING ||
+ lastFoldUpdate == FOLD_UPDATE_START_CLOSING
+
private fun onHingeAngle(angle: Float) {
- when (lastFoldUpdate) {
- FOLD_UPDATE_FINISH_FULL_OPEN -> {
- if (FULLY_OPEN_DEGREES - angle > START_CLOSING_THRESHOLD_DEGREES) {
- lastFoldUpdate = FOLD_UPDATE_START_CLOSING
- outputListeners.forEach { it.onFoldUpdate(FOLD_UPDATE_START_CLOSING) }
- }
- }
- FOLD_UPDATE_START_OPENING -> {
- if (FULLY_OPEN_DEGREES - angle < FULLY_OPEN_THRESHOLD_DEGREES) {
- lastFoldUpdate = FOLD_UPDATE_FINISH_FULL_OPEN
- outputListeners.forEach { it.onFoldUpdate(FOLD_UPDATE_FINISH_FULL_OPEN) }
- }
- }
- FOLD_UPDATE_START_CLOSING -> {
- if (FULLY_OPEN_DEGREES - angle < START_CLOSING_THRESHOLD_DEGREES) {
- lastFoldUpdate = FOLD_UPDATE_FINISH_FULL_OPEN
- outputListeners.forEach { it.onFoldUpdate(FOLD_UPDATE_FINISH_FULL_OPEN) }
- }
+ if (DEBUG) { Log.d(TAG, "Hinge angle: $angle, lastHingeAngle: $lastHingeAngle") }
+
+ val isClosing = angle < lastHingeAngle
+ val isFullyOpened = FULLY_OPEN_DEGREES - angle < FULLY_OPEN_THRESHOLD_DEGREES
+ val closingEventDispatched = lastFoldUpdate == FOLD_UPDATE_START_CLOSING
+
+ if (isClosing && !closingEventDispatched && !isFullyOpened) {
+ notifyFoldUpdate(FOLD_UPDATE_START_CLOSING)
+ }
+
+ if (isTransitionInProgess) {
+ if (isFullyOpened) {
+ notifyFoldUpdate(FOLD_UPDATE_FINISH_FULL_OPEN)
+ cancelTimeout()
+ } else {
+ // The timeout will trigger some constant time after the last angle update.
+ rescheduleAbortAnimationTimeout()
}
}
+ lastHingeAngle = angle
outputListeners.forEach { it.onHingeAngleUpdate(angle) }
}
private inner class FoldStateListener(context: Context) :
DeviceStateManager.FoldStateListener(context, { folded: Boolean ->
isFolded = folded
+ lastHingeAngle = FULLY_CLOSED_DEGREES
if (folded) {
- lastFoldUpdate = FOLD_UPDATE_FINISH_CLOSED
- outputListeners.forEach { it.onFoldUpdate(FOLD_UPDATE_FINISH_CLOSED) }
hingeAngleProvider.stop()
+ notifyFoldUpdate(FOLD_UPDATE_FINISH_CLOSED)
+ cancelTimeout()
isUnfoldHandled = false
} else {
- lastFoldUpdate = FOLD_UPDATE_START_OPENING
- outputListeners.forEach { it.onFoldUpdate(FOLD_UPDATE_START_OPENING) }
+ notifyFoldUpdate(FOLD_UPDATE_START_OPENING)
+ rescheduleAbortAnimationTimeout()
hingeAngleProvider.start()
}
})
+ private fun notifyFoldUpdate(@FoldUpdate update: Int) {
+ if (DEBUG) { Log.d(TAG, stateToString(update)) }
+ outputListeners.forEach { it.onFoldUpdate(update) }
+ lastFoldUpdate = update
+ }
+
+ private fun rescheduleAbortAnimationTimeout() {
+ if (isTransitionInProgess) {
+ cancelTimeout()
+ }
+ handler.postDelayed(timeoutRunnable, ABORT_CLOSING_MILLIS)
+ }
+
+ private fun cancelTimeout() {
+ handler.removeCallbacks(timeoutRunnable)
+ }
+
private inner class ScreenStatusListener :
ScreenStatusProvider.ScreenListener {
@@ -136,7 +168,39 @@ class DeviceFoldStateProvider(
onHingeAngle(angle)
}
}
+
+ private inner class TimeoutRunnable : Runnable {
+
+ override fun run() {
+ notifyFoldUpdate(FOLD_UPDATE_ABORTED)
+ }
+ }
+}
+
+private fun stateToString(@FoldUpdate update: Int): String {
+ return when (update) {
+ FOLD_UPDATE_START_OPENING -> "START_OPENING"
+ FOLD_UPDATE_HALF_OPEN -> "HALF_OPEN"
+ FOLD_UPDATE_START_CLOSING -> "START_CLOSING"
+ FOLD_UPDATE_ABORTED -> "ABORTED"
+ FOLD_UPDATE_UNFOLDED_SCREEN_AVAILABLE -> "UNFOLDED_SCREEN_AVAILABLE"
+ FOLD_UPDATE_FINISH_HALF_OPEN -> "FINISH_HALF_OPEN"
+ FOLD_UPDATE_FINISH_FULL_OPEN -> "FINISH_FULL_OPEN"
+ FOLD_UPDATE_FINISH_CLOSED -> "FINISH_CLOSED"
+ else -> "UNKNOWN"
+ }
}
-private const val START_CLOSING_THRESHOLD_DEGREES = 95f
-private const val FULLY_OPEN_THRESHOLD_DEGREES = 15f \ No newline at end of file
+private const val TAG = "DeviceFoldProvider"
+private const val DEBUG = false
+
+/**
+ * Time after which [FOLD_UPDATE_ABORTED] is emitted following a [FOLD_UPDATE_START_CLOSING] or
+ * [FOLD_UPDATE_START_OPENING] event, if an end state is not reached.
+ */
+@VisibleForTesting
+const val ABORT_CLOSING_MILLIS = 1000L
+
+/** Threshold after which we consider the device fully unfolded. */
+@VisibleForTesting
+const val FULLY_OPEN_THRESHOLD_DEGREES = 15f \ No newline at end of file
diff --git a/packages/SystemUI/shared/src/com/android/systemui/unfold/updates/FoldStateProvider.kt b/packages/SystemUI/shared/src/com/android/systemui/unfold/updates/FoldStateProvider.kt
index 643ece353522..bffebcd4512b 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/unfold/updates/FoldStateProvider.kt
+++ b/packages/SystemUI/shared/src/com/android/systemui/unfold/updates/FoldStateProvider.kt
@@ -39,6 +39,7 @@ interface FoldStateProvider : CallbackController<FoldUpdatesListener> {
FOLD_UPDATE_START_OPENING,
FOLD_UPDATE_HALF_OPEN,
FOLD_UPDATE_START_CLOSING,
+ FOLD_UPDATE_ABORTED,
FOLD_UPDATE_UNFOLDED_SCREEN_AVAILABLE,
FOLD_UPDATE_FINISH_HALF_OPEN,
FOLD_UPDATE_FINISH_FULL_OPEN,
@@ -51,7 +52,8 @@ interface FoldStateProvider : CallbackController<FoldUpdatesListener> {
const val FOLD_UPDATE_START_OPENING = 0
const val FOLD_UPDATE_HALF_OPEN = 1
const val FOLD_UPDATE_START_CLOSING = 2
-const val FOLD_UPDATE_UNFOLDED_SCREEN_AVAILABLE = 3
-const val FOLD_UPDATE_FINISH_HALF_OPEN = 4
-const val FOLD_UPDATE_FINISH_FULL_OPEN = 5
-const val FOLD_UPDATE_FINISH_CLOSED = 6
+const val FOLD_UPDATE_ABORTED = 3
+const val FOLD_UPDATE_UNFOLDED_SCREEN_AVAILABLE = 4
+const val FOLD_UPDATE_FINISH_HALF_OPEN = 5
+const val FOLD_UPDATE_FINISH_FULL_OPEN = 6
+const val FOLD_UPDATE_FINISH_CLOSED = 7
diff --git a/packages/SystemUI/tests/src/com/android/systemui/unfold/updates/DeviceFoldStateProviderTest.kt b/packages/SystemUI/tests/src/com/android/systemui/unfold/updates/DeviceFoldStateProviderTest.kt
index a1d9a7b50d81..be1720d07d11 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/unfold/updates/DeviceFoldStateProviderTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/unfold/updates/DeviceFoldStateProviderTest.kt
@@ -18,7 +18,9 @@ package com.android.systemui.unfold.updates
import android.hardware.devicestate.DeviceStateManager
import android.hardware.devicestate.DeviceStateManager.FoldStateListener
+import android.os.Handler
import android.testing.AndroidTestingRunner
+import androidx.core.util.Consumer
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.unfold.updates.hinge.HingeAngleProvider
@@ -31,9 +33,12 @@ import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.ArgumentCaptor
+import org.mockito.Captor
import org.mockito.Mock
import org.mockito.Mockito.verify
+import org.mockito.Mockito.`when` as whenever
import org.mockito.MockitoAnnotations
+import java.lang.Exception
@RunWith(AndroidTestingRunner::class)
@SmallTest
@@ -48,16 +53,28 @@ class DeviceFoldStateProviderTest : SysuiTestCase() {
@Mock
private lateinit var deviceStateManager: DeviceStateManager
- private lateinit var foldStateProvider: FoldStateProvider
+ @Mock
+ private lateinit var handler: Handler
+
+ @Captor
+ private lateinit var foldStateListenerCaptor: ArgumentCaptor<FoldStateListener>
+
+ @Captor
+ private lateinit var screenOnListenerCaptor: ArgumentCaptor<ScreenListener>
+
+ @Captor
+ private lateinit var hingeAngleCaptor: ArgumentCaptor<Consumer<Float>>
+
+ private lateinit var foldStateProvider: DeviceFoldStateProvider
private val foldUpdates: MutableList<Int> = arrayListOf()
private val hingeAngleUpdates: MutableList<Float> = arrayListOf()
- private val foldStateListenerCaptor = ArgumentCaptor.forClass(FoldStateListener::class.java)
private var foldedDeviceState: Int = 0
private var unfoldedDeviceState: Int = 0
- private val screenOnListenerCaptor = ArgumentCaptor.forClass(ScreenListener::class.java)
+ private var scheduledRunnable: Runnable? = null
+ private var scheduledRunnableDelay: Long? = null
@Before
fun setUp() {
@@ -75,7 +92,8 @@ class DeviceFoldStateProviderTest : SysuiTestCase() {
hingeAngleProvider,
screenStatusProvider,
deviceStateManager,
- context.mainExecutor
+ context.mainExecutor,
+ handler
)
foldStateProvider.addCallback(object : FoldStateProvider.FoldUpdatesListener {
@@ -91,6 +109,22 @@ class DeviceFoldStateProviderTest : SysuiTestCase() {
verify(deviceStateManager).registerCallback(any(), foldStateListenerCaptor.capture())
verify(screenStatusProvider).addCallback(screenOnListenerCaptor.capture())
+ verify(hingeAngleProvider).addCallback(hingeAngleCaptor.capture())
+
+ whenever(handler.postDelayed(any<Runnable>(), any())).then { invocationOnMock ->
+ scheduledRunnable = invocationOnMock.getArgument<Runnable>(0)
+ scheduledRunnableDelay = invocationOnMock.getArgument<Long>(1)
+ null
+ }
+
+ whenever(handler.removeCallbacks(any<Runnable>())).then { invocationOnMock ->
+ val removedRunnable = invocationOnMock.getArgument<Runnable>(0)
+ if (removedRunnable == scheduledRunnable) {
+ scheduledRunnableDelay = null
+ scheduledRunnable = null
+ }
+ null
+ }
}
@Test
@@ -167,6 +201,86 @@ class DeviceFoldStateProviderTest : SysuiTestCase() {
assertThat(foldUpdates).isEmpty()
}
+ @Test
+ fun startClosingEvent_afterTimeout_abortEmitted() {
+ sendHingeAngleEvent(90)
+ sendHingeAngleEvent(80)
+
+ simulateTimeout(ABORT_CLOSING_MILLIS)
+
+ assertThat(foldUpdates).containsExactly(FOLD_UPDATE_START_CLOSING, FOLD_UPDATE_ABORTED)
+ }
+
+ @Test
+ fun startClosingEvent_beforeTimeout_abortNotEmitted() {
+ sendHingeAngleEvent(90)
+ sendHingeAngleEvent(80)
+
+ simulateTimeout(ABORT_CLOSING_MILLIS - 1)
+
+ assertThat(foldUpdates).containsExactly(FOLD_UPDATE_START_CLOSING)
+ }
+
+ @Test
+ fun startClosingEvent_eventBeforeTimeout_oneEventEmitted() {
+ sendHingeAngleEvent(180)
+ sendHingeAngleEvent(90)
+
+ simulateTimeout(ABORT_CLOSING_MILLIS - 1)
+ sendHingeAngleEvent(80)
+
+ assertThat(foldUpdates).containsExactly(FOLD_UPDATE_START_CLOSING)
+ }
+
+ @Test
+ fun startClosingEvent_timeoutAfterTimeoutRescheduled_abortEmitted() {
+ sendHingeAngleEvent(180)
+ sendHingeAngleEvent(90)
+
+ simulateTimeout(ABORT_CLOSING_MILLIS - 1) // The timeout should not trigger here.
+ sendHingeAngleEvent(80)
+ simulateTimeout(ABORT_CLOSING_MILLIS) // The timeout should trigger here.
+
+ assertThat(foldUpdates).containsExactly(FOLD_UPDATE_START_CLOSING, FOLD_UPDATE_ABORTED)
+ }
+
+ @Test
+ fun startClosingEvent_shortTimeBetween_emitsOnlyOneEvents() {
+ sendHingeAngleEvent(180)
+
+ sendHingeAngleEvent(90)
+ sendHingeAngleEvent(80)
+
+ assertThat(foldUpdates).containsExactly(FOLD_UPDATE_START_CLOSING)
+ }
+
+ @Test
+ fun startClosingEvent_whileClosing_emittedDespiteInitialAngle() {
+ val maxAngle = 180 - FULLY_OPEN_THRESHOLD_DEGREES.toInt()
+ for (i in 1..maxAngle) {
+ foldUpdates.clear()
+
+ simulateFolding(startAngle = i)
+
+ assertThat(foldUpdates).containsExactly(FOLD_UPDATE_START_CLOSING)
+ simulateTimeout() // Timeout to set the state to aborted.
+ }
+ }
+
+ private fun simulateTimeout(waitTime: Long = ABORT_CLOSING_MILLIS) {
+ val runnableDelay = scheduledRunnableDelay ?: throw Exception("No runnable scheduled.")
+ if (waitTime >= runnableDelay) {
+ scheduledRunnable?.run()
+ scheduledRunnable = null
+ scheduledRunnableDelay = null
+ }
+ }
+
+ private fun simulateFolding(startAngle: Int) {
+ sendHingeAngleEvent(startAngle)
+ sendHingeAngleEvent(startAngle - 1)
+ }
+
private fun setFoldState(folded: Boolean) {
val state = if (folded) foldedDeviceState else unfoldedDeviceState
foldStateListenerCaptor.value.onStateChanged(state)
@@ -175,4 +289,8 @@ class DeviceFoldStateProviderTest : SysuiTestCase() {
private fun fireScreenOnEvent() {
screenOnListenerCaptor.value.onScreenTurnedOn()
}
+
+ private fun sendHingeAngleEvent(angle: Int) {
+ hingeAngleCaptor.value.accept(angle.toFloat())
+ }
}