Merge "[tp] Changes GlobalScope to CoroutineScope(Dispatchers.Main) (2/2)." into udc-dev
diff --git a/src/com/android/customization/picker/clock/ui/binder/ClockCarouselViewBinder.kt b/src/com/android/customization/picker/clock/ui/binder/ClockCarouselViewBinder.kt
index 7d19dc1..7bdd4fc 100644
--- a/src/com/android/customization/picker/clock/ui/binder/ClockCarouselViewBinder.kt
+++ b/src/com/android/customization/picker/clock/ui/binder/ClockCarouselViewBinder.kt
@@ -53,20 +53,18 @@
                             onGetClockController = { clockId ->
                                 clockViewFactory.getController(clockId)
                             },
-                            onClockSelected = { clockId -> viewModel.setSelectedClock(clockId) },
-                            getPreviewRatio = { clockViewFactory.getRatio() },
-                            onClockTransitionCompleted = { startId, endId ->
-                                if (startId != endId ) {
-                                    val hasCustomWeatherDataDisplay =
-                                            clockViewFactory
-                                                    .getController(endId)
-                                                    .largeClock
-                                                    .config
-                                                    .hasCustomWeatherDataDisplay
+                            onClockSelected = { clockId ->
+                                viewModel.setSelectedClock(clockId)
+                                val hasCustomWeatherDataDisplay =
+                                    clockViewFactory
+                                        .getController(clockId)
+                                        .largeClock
+                                        .config
+                                        .hasCustomWeatherDataDisplay
 
-                                    hideSmartspace(hasCustomWeatherDataDisplay)
-                                }
+                                hideSmartspace(hasCustomWeatherDataDisplay)
                             },
+                            previewRatio = clockViewFactory.getRatio(),
                         )
                     }
                 }
diff --git a/src/com/android/customization/picker/clock/ui/view/ClockCarouselView.kt b/src/com/android/customization/picker/clock/ui/view/ClockCarouselView.kt
index a084a54..059e498 100644
--- a/src/com/android/customization/picker/clock/ui/view/ClockCarouselView.kt
+++ b/src/com/android/customization/picker/clock/ui/view/ClockCarouselView.kt
@@ -41,8 +41,8 @@
     val carousel: Carousel
     private val motionLayout: MotionLayout
     private lateinit var adapter: ClockCarouselAdapter
-    private lateinit var scalingUpClockController: ClockController
-    private lateinit var scalingDownClockController: ClockController
+    private var scalingUpClockController: ClockController? = null
+    private var scalingDownClockController: ClockController? = null
     private var scalingUpClockView: View? = null
     private var scalingDownClockView: View? = null
     private var showingCardView: View? = null
@@ -58,17 +58,14 @@
         clockIds: List<String>,
         onGetClockController: (clockId: String) -> ClockController,
         onClockSelected: (clockId: String) -> Unit,
-        getPreviewRatio: () -> Float,
-        onClockTransitionCompleted: (startId: String, endId: String) -> Unit,
+        previewRatio: Float,
     ) {
         adapter =
-            ClockCarouselAdapter(clockIds, onGetClockController, onClockSelected, getPreviewRatio)
+            ClockCarouselAdapter(clockIds, onGetClockController, onClockSelected, previewRatio)
         carousel.setAdapter(adapter)
         carousel.refresh()
         motionLayout.setTransitionListener(
             object : MotionLayout.TransitionListener {
-                var scalingDownClockId = ""
-                var scalingUpClockId = ""
 
                 override fun onTransitionStarted(
                     motionLayout: MotionLayout?,
@@ -76,11 +73,11 @@
                     endId: Int
                 ) {
                     isCarouselInTransition = true
-                    scalingDownClockId = adapter.clockIds[carousel.currentIndex]
+                    val scalingDownClockId = adapter.clockIds[carousel.currentIndex]
                     val scalingUpIdx =
                         if (endId == R.id.next) (carousel.currentIndex + 1) % adapter.count()
                         else (carousel.currentIndex - 1 + adapter.count()) % adapter.count()
-                    scalingUpClockId = adapter.clockIds[scalingUpIdx]
+                    val scalingUpClockId = adapter.clockIds[scalingUpIdx]
                     scalingDownClockController = adapter.onGetClockController(scalingDownClockId)
                     scalingUpClockController = adapter.onGetClockController(scalingUpClockId)
                     scalingDownClockView = motionLayout?.findViewById(R.id.clock_scale_view_2)
@@ -94,6 +91,7 @@
                         motionLayout?.findViewById(
                             if (endId == R.id.next) R.id.item_card_3 else R.id.item_card_1
                         )
+                    setCardAnimationState(true)
                 }
 
                 override fun onTransitionChange(
@@ -102,14 +100,20 @@
                     endId: Int,
                     progress: Float
                 ) {
-                    scalingDownClockController.largeClock.animations.onPickerCarouselSwiping(
-                        1 - progress,
-                        getPreviewRatio()
-                    )
-                    scalingUpClockController.largeClock.animations.onPickerCarouselSwiping(
-                        progress,
-                        getPreviewRatio()
-                    )
+                    scalingDownClockController
+                        ?.largeClock
+                        ?.animations
+                        ?.onPickerCarouselSwiping(
+                            1 - progress,
+                            previewRatio,
+                        )
+                    scalingUpClockController
+                        ?.largeClock
+                        ?.animations
+                        ?.onPickerCarouselSwiping(
+                            progress,
+                            previewRatio,
+                        )
                     val scalingUpScale = getScalingUpScale(progress)
                     val scalingDownScale = getScalingDownScale(progress)
                     scalingUpClockView?.scaleX = scalingUpScale
@@ -122,7 +126,30 @@
 
                 override fun onTransitionCompleted(motionLayout: MotionLayout?, currentId: Int) {
                     isCarouselInTransition = false
-                    onClockTransitionCompleted(scalingDownClockId, scalingUpClockId)
+                    setCardAnimationState(currentId == R.id.start)
+                }
+
+                private fun setCardAnimationState(isStart: Boolean) {
+                    scalingDownClockView?.scaleX = if (isStart) 1f else CLOCK_CAROUSEL_VIEW_SCALE
+                    scalingDownClockView?.scaleY = if (isStart) 1f else CLOCK_CAROUSEL_VIEW_SCALE
+                    scalingUpClockView?.scaleX = if (isStart) CLOCK_CAROUSEL_VIEW_SCALE else 1f
+                    scalingUpClockView?.scaleY = if (isStart) CLOCK_CAROUSEL_VIEW_SCALE else 1f
+                    scalingDownClockController
+                        ?.largeClock
+                        ?.animations
+                        ?.onPickerCarouselSwiping(
+                            if (isStart) 1f else 0f,
+                            previewRatio,
+                        )
+                    scalingUpClockController
+                        ?.largeClock
+                        ?.animations
+                        ?.onPickerCarouselSwiping(
+                            if (isStart) 0f else 1f,
+                            previewRatio,
+                        )
+                    showingCardView?.alpha = if (isStart) 0f else 1f
+                    hidingCardView?.alpha = if (isStart) 1f else 0f
                 }
 
                 override fun onTransitionTrigger(
@@ -138,14 +165,18 @@
     fun setSelectedClockIndex(
         index: Int,
     ) {
-        carousel.jumpToIndex(index)
+        // jumpToIndex to the same position can cause the views unnecessarily populate again.
+        // Only call jumpToIndex when the jump-to index is different from the current carousel.
+        if (index != carousel.currentIndex) {
+            carousel.jumpToIndex(index)
+        }
     }
 
     class ClockCarouselAdapter(
         val clockIds: List<String>,
         val onGetClockController: (clockId: String) -> ClockController,
         private val onClockSelected: (clockId: String) -> Unit,
-        val getPreviewRatio: () -> Float,
+        private val previewRatio: Float,
     ) : Carousel.Adapter {
 
         override fun count(): Int {
@@ -180,7 +211,7 @@
                 onGetClockController(clockIds[index])
                     .largeClock
                     .animations
-                    .onPickerCarouselSwiping(0F, getPreviewRatio())
+                    .onPickerCarouselSwiping(0F, previewRatio)
             } else {
                 cardView.alpha = 0f
                 clockScaleView.scaleX = 1f
@@ -188,7 +219,7 @@
                 onGetClockController(clockIds[index])
                     .largeClock
                     .animations
-                    .onPickerCarouselSwiping(1F, getPreviewRatio())
+                    .onPickerCarouselSwiping(1F, previewRatio)
             }
         }