Make unfold timeout configurable in resources

This allows to have a different timeout for the emulator, and to write better e2e integration tests for the unfold transition.
For now, the timeout is pretty low and the emulator is not able do dump all the views in time.

Test: atest DeviceFoldStateProviderTest
Bug: 220087235
Change-Id: Icd45a312c878f0a9d9f33f35cbaf4bac37cc5dd1
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index e6d4bab..0cabca1 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -674,6 +674,10 @@
     <!-- Indicates whether to enable hinge angle sensor when using unfold animation -->
     <bool name="config_unfoldTransitionHingeAngle">false</bool>
 
+    <!-- Indicates the time needed to time out the fold animation if the device stops in half folded
+         mode. -->
+    <integer name="config_unfoldTransitionHalfFoldedTimeout">600</integer>
+
     <!-- Indicates that the device supports having more than one internal display on at the same
          time. Only applicable to devices with more than one internal display. If this option is
          set to false, DisplayManager will make additional effort to ensure no more than 1 internal
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 7f891ea..67d4c2b 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -3959,6 +3959,7 @@
   <java-symbol type="bool" name="config_supportsConcurrentInternalDisplays" />
   <java-symbol type="bool" name="config_unfoldTransitionEnabled" />
   <java-symbol type="bool" name="config_unfoldTransitionHingeAngle" />
+  <java-symbol type="integer" name="config_unfoldTransitionHalfFoldedTimeout" />
   <java-symbol type="array" name="config_perDeviceStateRotationLockDefaults" />
 
 
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 ed973d6..83b72e8 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
@@ -57,6 +57,15 @@
     private val foldStateListener = FoldStateListener(context)
     private val timeoutRunnable = TimeoutRunnable()
 
+    /**
+     * Time after which [FOLD_UPDATE_FINISH_HALF_OPEN] is emitted following a
+     * [FOLD_UPDATE_START_CLOSING] or [FOLD_UPDATE_START_OPENING] event, if an end state is not
+     * reached.
+     */
+    private val halfOpenedTimeoutMillis: Int =
+        context.resources.getInteger(
+            com.android.internal.R.integer.config_unfoldTransitionHalfFoldedTimeout)
+
     private var isFolded = false
     private var isUnfoldHandled = true
 
@@ -171,7 +180,7 @@
         if (isTransitionInProgess) {
             cancelTimeout()
         }
-        handler.postDelayed(timeoutRunnable, HALF_OPENED_TIMEOUT_MILLIS)
+        handler.postDelayed(timeoutRunnable, halfOpenedTimeoutMillis.toLong())
     }
 
     private fun cancelTimeout() {
@@ -222,12 +231,6 @@
 private const val TAG = "DeviceFoldProvider"
 private const val DEBUG = false
 
-/**
- * Time after which [FOLD_UPDATE_FINISH_HALF_OPEN] is emitted following a
- * [FOLD_UPDATE_START_CLOSING] or [FOLD_UPDATE_START_OPENING] event, if an end state is not reached.
- */
-@VisibleForTesting const val HALF_OPENED_TIMEOUT_MILLIS = 600L
-
 /** Threshold after which we consider the device fully unfolded. */
 @VisibleForTesting const val FULLY_OPEN_THRESHOLD_DEGREES = 15f
 
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 7ac2434..05a8f0a 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
@@ -78,6 +78,9 @@
     @Before
     fun setUp() {
         MockitoAnnotations.initMocks(this)
+        overrideResource(
+            com.android.internal.R.integer.config_unfoldTransitionHalfFoldedTimeout,
+            HALF_OPENED_TIMEOUT_MILLIS.toInt())
         deviceStates = FoldableTestUtils.findDeviceStates(context)
 
         foldStateProvider =
@@ -319,4 +322,8 @@
     private fun sendHingeAngleEvent(angle: Int) {
         hingeAngleCaptor.value.accept(angle.toFloat())
     }
+
+    companion object {
+        private const val HALF_OPENED_TIMEOUT_MILLIS = 300L
+    }
 }