Merge "Make haptics during unfold animation configurable" into 24D1-dev
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 6f605e9..784b371 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -764,6 +764,9 @@
     <!-- Indicates whether to enable hinge angle sensor when using unfold animation -->
     <bool name="config_unfoldTransitionHingeAngle">false</bool>
 
+    <!-- Indicates whether to enable haptics during unfold animation -->
+    <bool name="config_unfoldTransitionHapticsEnabled">false</bool>
+
     <!-- Indicates the time needed to time out the fold animation if the device stops in half folded
          mode. -->
     <integer name="config_unfoldTransitionHalfFoldedTimeout">1000</integer>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index f23cf98..dadb7e4 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -4198,6 +4198,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="bool" name="config_unfoldTransitionHapticsEnabled" />
   <java-symbol type="integer" name="config_unfoldTransitionHalfFoldedTimeout" />
   <java-symbol type="array" name="config_perDeviceStateRotationLockDefaults" />
 
diff --git a/packages/SystemUI/src/com/android/systemui/unfold/UnfoldHapticsPlayer.kt b/packages/SystemUI/src/com/android/systemui/unfold/UnfoldHapticsPlayer.kt
index 1e65566..b3ea9dc 100644
--- a/packages/SystemUI/src/com/android/systemui/unfold/UnfoldHapticsPlayer.kt
+++ b/packages/SystemUI/src/com/android/systemui/unfold/UnfoldHapticsPlayer.kt
@@ -6,8 +6,8 @@
 import android.os.Vibrator
 import com.android.systemui.dagger.qualifiers.Main
 import com.android.systemui.unfold.UnfoldTransitionProgressProvider.TransitionProgressListener
+import com.android.systemui.unfold.config.UnfoldTransitionConfig
 import com.android.systemui.unfold.updates.FoldProvider
-import com.android.systemui.unfold.updates.FoldProvider.FoldCallback
 import java.util.concurrent.Executor
 import javax.inject.Inject
 
@@ -18,6 +18,7 @@
 constructor(
     unfoldTransitionProgressProvider: UnfoldTransitionProgressProvider,
     foldProvider: FoldProvider,
+    transitionConfig: UnfoldTransitionConfig,
     @Main private val mainExecutor: Executor,
     private val vibrator: Vibrator?
 ) : TransitionProgressListener {
@@ -27,22 +28,17 @@
             VibrationAttributes.createForUsage(VibrationAttributes.USAGE_HARDWARE_FEEDBACK)
 
     init {
-        if (vibrator != null) {
+        if (vibrator != null && transitionConfig.isHapticsEnabled) {
             // We don't need to remove the callback because we should listen to it
             // the whole time when SystemUI process is alive
             unfoldTransitionProgressProvider.addCallback(this)
-        }
 
-        foldProvider.registerCallback(
-            object : FoldCallback {
-                override fun onFoldUpdated(isFolded: Boolean) {
-                    if (isFolded) {
-                        isFirstAnimationAfterUnfold = true
-                    }
+            foldProvider.registerCallback({ isFolded ->
+                if (isFolded) {
+                    isFirstAnimationAfterUnfold = true
                 }
-            },
-            mainExecutor
-        )
+            }, mainExecutor)
+        }
     }
 
     private var lastTransitionProgress = TRANSITION_PROGRESS_FULL_OPEN
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewControllerTest.kt
index 443dd6a..47441c2 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewControllerTest.kt
@@ -313,6 +313,7 @@
     private class UnfoldConfig : UnfoldTransitionConfig {
         override var isEnabled: Boolean = false
         override var isHingeAngleEnabled: Boolean = false
+        override val isHapticsEnabled: Boolean = false
         override val halfFoldedTimeoutMillis: Int = 0
     }
 
diff --git a/packages/SystemUI/tests/src/com/android/systemui/unfold/UnfoldHapticsPlayerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/unfold/UnfoldHapticsPlayerTest.kt
index b9c7e61..fab9594 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/unfold/UnfoldHapticsPlayerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/unfold/UnfoldHapticsPlayerTest.kt
@@ -17,13 +17,12 @@
 
 import android.os.VibrationAttributes
 import android.os.VibrationEffect
-import android.os.Vibrator
+import android.os.vibrator
 import android.testing.AndroidTestingRunner
 import androidx.test.filters.SmallTest
 import com.android.systemui.SysuiTestCase
-import com.android.systemui.unfold.util.TestFoldProvider
+import com.android.systemui.testKosmos
 import com.android.systemui.util.mockito.any
-import com.android.systemui.util.mockito.mock
 import org.junit.Before
 import org.junit.Test
 import org.junit.runner.RunWith
@@ -35,15 +34,20 @@
 @SmallTest
 class UnfoldHapticsPlayerTest : SysuiTestCase() {
 
+    private val kosmos = testKosmos()
+
     private val progressProvider = TestUnfoldTransitionProvider()
-    private val vibrator: Vibrator = mock()
-    private val testFoldProvider = TestFoldProvider()
+    private val vibrator = kosmos.vibrator
+    private val transitionConfig = kosmos.unfoldTransitionConfig
+    private val testFoldProvider = kosmos.foldProvider
 
     private lateinit var player: UnfoldHapticsPlayer
 
     @Before
     fun before() {
-        player = UnfoldHapticsPlayer(progressProvider, testFoldProvider, Runnable::run, vibrator)
+        transitionConfig.isHapticsEnabled = true
+        player = UnfoldHapticsPlayer(progressProvider, testFoldProvider, transitionConfig,
+            Runnable::run, vibrator)
     }
 
     @Test
@@ -58,6 +62,21 @@
     }
 
     @Test
+    fun testHapticsDisabled_unfoldingTransitionFinishing_doesNotPlayHaptics() {
+        transitionConfig.isHapticsEnabled = false
+        player = UnfoldHapticsPlayer(progressProvider, testFoldProvider, transitionConfig,
+                Runnable::run, vibrator)
+
+        testFoldProvider.onFoldUpdate(isFolded = true)
+        testFoldProvider.onFoldUpdate(isFolded = false)
+        progressProvider.onTransitionStarted()
+        progressProvider.onTransitionProgress(0.5f)
+        progressProvider.onTransitionFinishing()
+
+        verify(vibrator).vibrate(any<VibrationEffect>(), any<VibrationAttributes>())
+    }
+
+    @Test
     fun testUnfoldingTransitionFinishingLate_doesNotPlayHaptics() {
         testFoldProvider.onFoldUpdate(isFolded = true)
         testFoldProvider.onFoldUpdate(isFolded = false)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/unfold/UnfoldTestUtilsKosmos.kt b/packages/SystemUI/tests/src/com/android/systemui/unfold/UnfoldTestUtilsKosmos.kt
new file mode 100644
index 0000000..c073903
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/unfold/UnfoldTestUtilsKosmos.kt
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.unfold
+
+import com.android.systemui.unfold.util.TestFoldProvider
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.unfold.config.TestUnfoldTransitionConfig
+
+var Kosmos.foldProvider: TestFoldProvider by Kosmos.Fixture { TestFoldProvider() }
+
+var Kosmos.unfoldTransitionConfig: TestUnfoldTransitionConfig
+    by Kosmos.Fixture { TestUnfoldTransitionConfig() }
diff --git a/packages/SystemUI/tests/src/com/android/systemui/unfold/config/ResourceUnfoldTransitionConfigTest.kt b/packages/SystemUI/tests/src/com/android/systemui/unfold/config/ResourceUnfoldTransitionConfigTest.kt
index ab450e2..3c53997 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/unfold/config/ResourceUnfoldTransitionConfigTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/unfold/config/ResourceUnfoldTransitionConfigTest.kt
@@ -47,6 +47,12 @@
     }
 
     @Test
+    fun testHapticsEnabled() {
+        assertThat(config.isHapticsEnabled).isEqualTo(mContext.resources
+            .getBoolean(com.android.internal.R.bool.config_unfoldTransitionHapticsEnabled))
+    }
+
+    @Test
     fun testHalfFoldedTimeout() {
         assertThat(config.halfFoldedTimeoutMillis).isEqualTo(mContext.resources
             .getInteger(com.android.internal.R.integer.config_unfoldTransitionHalfFoldedTimeout))
diff --git a/packages/SystemUI/tests/src/com/android/systemui/unfold/config/TestUnfoldTransitionConfig.kt b/packages/SystemUI/tests/src/com/android/systemui/unfold/config/TestUnfoldTransitionConfig.kt
new file mode 100644
index 0000000..0586115
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/unfold/config/TestUnfoldTransitionConfig.kt
@@ -0,0 +1,24 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.unfold.config
+
+class TestUnfoldTransitionConfig(
+    override var isEnabled: Boolean = false,
+    override var isHingeAngleEnabled: Boolean = false,
+    override var isHapticsEnabled: Boolean = false,
+    override var halfFoldedTimeoutMillis: Int = 1000
+) : UnfoldTransitionConfig
diff --git a/packages/SystemUI/tests/utils/src/android/os/VibratorKosmos.kt b/packages/SystemUI/tests/utils/src/android/os/VibratorKosmos.kt
new file mode 100644
index 0000000..872b25c
--- /dev/null
+++ b/packages/SystemUI/tests/utils/src/android/os/VibratorKosmos.kt
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.os
+
+import com.android.systemui.kosmos.Kosmos
+import com.android.systemui.util.mockito.mock
+
+var Kosmos.vibrator by Kosmos.Fixture { mock<Vibrator>() }
diff --git a/packages/SystemUI/unfold/src/com/android/systemui/unfold/config/ResourceUnfoldTransitionConfig.kt b/packages/SystemUI/unfold/src/com/android/systemui/unfold/config/ResourceUnfoldTransitionConfig.kt
index c513729..ca1daf6 100644
--- a/packages/SystemUI/unfold/src/com/android/systemui/unfold/config/ResourceUnfoldTransitionConfig.kt
+++ b/packages/SystemUI/unfold/src/com/android/systemui/unfold/config/ResourceUnfoldTransitionConfig.kt
@@ -33,6 +33,12 @@
         Resources.getSystem().getBoolean(id)
     }
 
+    override val isHapticsEnabled: Boolean by lazy {
+        val id = Resources.getSystem()
+            .getIdentifier("config_unfoldTransitionHapticsEnabled", "bool", "android")
+        Resources.getSystem().getBoolean(id)
+    }
+
     override val halfFoldedTimeoutMillis: Int by lazy {
         val id = Resources.getSystem()
             .getIdentifier("config_unfoldTransitionHalfFoldedTimeout", "integer", "android")
diff --git a/packages/SystemUI/unfold/src/com/android/systemui/unfold/config/UnfoldTransitionConfig.kt b/packages/SystemUI/unfold/src/com/android/systemui/unfold/config/UnfoldTransitionConfig.kt
index 765e862..1084cb3 100644
--- a/packages/SystemUI/unfold/src/com/android/systemui/unfold/config/UnfoldTransitionConfig.kt
+++ b/packages/SystemUI/unfold/src/com/android/systemui/unfold/config/UnfoldTransitionConfig.kt
@@ -18,5 +18,6 @@
 interface UnfoldTransitionConfig {
     val isEnabled: Boolean
     val isHingeAngleEnabled: Boolean
+    val isHapticsEnabled: Boolean
     val halfFoldedTimeoutMillis: Int
 }