[TP] Fix digital clocks in clock carousel

1. Modify the view size of the clock carousel to make it same as the
   screen preview
2. Choose a proper ratio for the text size for text view clocks

Test: Manually tested that the text clocks are showing
Bug: 262924055
Change-Id: I06220c4f10dc4b7b475efe5471dcf19a94a4ce82
diff --git a/res/layout/clock_carousel.xml b/res/layout/clock_carousel.xml
index 098586e..cfc7e4e 100644
--- a/res/layout/clock_carousel.xml
+++ b/res/layout/clock_carousel.xml
@@ -19,59 +19,79 @@
     xmlns:app="http://schemas.android.com/apk/res-auto"
     android:id="@+id/motion_container"
     android:layout_width="match_parent"
-    android:layout_height="wrap_content"
+    android:layout_height="match_parent"
     app:layoutDescription="@xml/carousel_scene">
 
-    <FrameLayout
+    <com.android.wallpaper.picker.DisplayAspectRatioFrameLayout
         android:id="@+id/item_view_0"
-        android:layout_width="@dimen/clock_carousel_item_small_size"
-        android:layout_height="@dimen/clock_carousel_item_small_size"
-        android:layout_marginEnd="16dp"
-        android:scaleType="centerCrop"
+        android:layout_width="@dimen/clock_carousel_item_width"
+        android:layout_height="@dimen/clock_carousel_item_height"
+        android:layout_marginEnd="@dimen/clock_carousel_item_margin"
         app:layout_constraintBottom_toBottomOf="parent"
         app:layout_constraintEnd_toStartOf="@+id/item_view_1"
-        app:layout_constraintTop_toTopOf="parent" />
+        app:layout_constraintTop_toTopOf="parent">
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"
+            android:layout_gravity="center" />
+    </com.android.wallpaper.picker.DisplayAspectRatioFrameLayout>
 
-    <FrameLayout
+    <com.android.wallpaper.picker.DisplayAspectRatioFrameLayout
         android:id="@+id/item_view_1"
-        android:layout_width="@dimen/clock_carousel_item_small_size"
-        android:layout_height="@dimen/clock_carousel_item_small_size"
-        android:layout_marginEnd="16dp"
-        android:scaleType="centerCrop"
+        android:layout_width="@dimen/clock_carousel_item_width"
+        android:layout_height="@dimen/clock_carousel_item_height"
+        android:layout_marginEnd="@dimen/clock_carousel_item_margin"
         app:layout_constraintBottom_toBottomOf="parent"
         app:layout_constraintEnd_toStartOf="@+id/item_view_2"
-        app:layout_constraintTop_toTopOf="parent" />
+        app:layout_constraintTop_toTopOf="parent" >
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"
+            android:layout_gravity="center" />
+    </com.android.wallpaper.picker.DisplayAspectRatioFrameLayout>
 
-    <FrameLayout
+    <com.android.wallpaper.picker.DisplayAspectRatioFrameLayout
         android:id="@+id/item_view_2"
-        android:layout_width="@dimen/clock_carousel_item_large_size"
-        android:layout_height="@dimen/clock_carousel_item_large_size"
-        android:scaleType="centerCrop"
+        android:layout_width="@dimen/clock_carousel_item_width"
+        android:layout_height="@dimen/clock_carousel_item_height"
         app:layout_constraintBottom_toBottomOf="parent"
         app:layout_constraintEnd_toEndOf="parent"
         app:layout_constraintHorizontal_bias="0.5"
         app:layout_constraintStart_toStartOf="parent"
-        app:layout_constraintTop_toTopOf="parent" />
+        app:layout_constraintTop_toTopOf="parent">
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"
+            android:layout_gravity="center" />
+    </com.android.wallpaper.picker.DisplayAspectRatioFrameLayout>
 
-    <FrameLayout
+    <com.android.wallpaper.picker.DisplayAspectRatioFrameLayout
         android:id="@+id/item_view_3"
-        android:layout_width="@dimen/clock_carousel_item_small_size"
-        android:layout_height="@dimen/clock_carousel_item_small_size"
-        android:layout_marginStart="16dp"
-        android:scaleType="centerCrop"
+        android:layout_width="@dimen/clock_carousel_item_width"
+        android:layout_height="@dimen/clock_carousel_item_height"
+        android:layout_marginStart="@dimen/clock_carousel_item_margin"
         app:layout_constraintBottom_toBottomOf="parent"
         app:layout_constraintStart_toEndOf="@+id/item_view_2"
-        app:layout_constraintTop_toTopOf="parent" />
+        app:layout_constraintTop_toTopOf="parent" >
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"
+            android:layout_gravity="center" />
+    </com.android.wallpaper.picker.DisplayAspectRatioFrameLayout>
 
-    <FrameLayout
+    <com.android.wallpaper.picker.DisplayAspectRatioFrameLayout
         android:id="@+id/item_view_4"
-        android:layout_width="@dimen/clock_carousel_item_small_size"
-        android:layout_height="@dimen/clock_carousel_item_small_size"
-        android:layout_marginStart="16dp"
-        android:scaleType="centerCrop"
+        android:layout_width="@dimen/clock_carousel_item_width"
+        android:layout_height="@dimen/clock_carousel_item_height"
+        android:layout_marginStart="@dimen/clock_carousel_item_margin"
         app:layout_constraintBottom_toBottomOf="parent"
         app:layout_constraintStart_toEndOf="@+id/item_view_3"
-        app:layout_constraintTop_toTopOf="parent" />
+        app:layout_constraintTop_toTopOf="parent" >
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"
+            android:layout_gravity="center" />
+    </com.android.wallpaper.picker.DisplayAspectRatioFrameLayout>
 
     <androidx.constraintlayout.helper.widget.Carousel
         android:id="@+id/carousel"
diff --git a/res/layout/clock_carousel_view.xml b/res/layout/clock_carousel_view.xml
index 21ff266..f1c959c 100644
--- a/res/layout/clock_carousel_view.xml
+++ b/res/layout/clock_carousel_view.xml
@@ -17,4 +17,4 @@
 <com.android.customization.picker.clock.ui.view.ClockCarouselView
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent"
-    android:layout_height="wrap_content"/>
\ No newline at end of file
+    android:layout_height="@dimen/screen_preview_height" />
\ No newline at end of file
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index febca46..b856c35 100644
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -153,7 +153,7 @@
     <!-- Width of a single selectable item in the lock screen quick affordance picker. -->
     <dimen name="keyguard_quick_affordance_picker_item_width">74dp</dimen>
 
-    <dimen name="clock_carousel_item_small_size">100dp</dimen>
-    <dimen name="clock_carousel_item_large_size">120dp</dimen>
-    <dimen name="clock_carousel_item_margin">32dp</dimen>
+    <dimen name="clock_carousel_item_width">190dp</dimen>
+    <dimen name="clock_carousel_item_height">380dp</dimen>
+    <dimen name="clock_carousel_item_margin">16dp</dimen>
 </resources>
diff --git a/res/xml/carousel_scene.xml b/res/xml/carousel_scene.xml
index 345f690..8c6738b 100644
--- a/res/xml/carousel_scene.xml
+++ b/res/xml/carousel_scene.xml
@@ -40,94 +40,82 @@
     <ConstraintSet android:id="@+id/previous">
         <Constraint
             android:id="@+id/item_view_0"
-            android:layout_width="@dimen/clock_carousel_item_small_size"
-            android:layout_height="@dimen/clock_carousel_item_small_size"
+            android:layout_width="@dimen/clock_carousel_item_width"
+            android:layout_height="@dimen/clock_carousel_item_height"
             motion:layout_constraintEnd_toStartOf="@id/guideline_start"
             motion:layout_constraintTop_toTopOf="parent"
-            motion:layout_constraintBottom_toBottomOf="parent"
-            android:layout_marginEnd="16dp" />
+            motion:layout_constraintBottom_toBottomOf="parent" />
         <Constraint
             android:id="@+id/item_view_1"
-            android:layout_width="0dp"
-            android:layout_height="0dp"
-            motion:layout_constraintDimensionRatio="1:1"
+            android:layout_width="@dimen/clock_carousel_item_width"
+            android:layout_height="@dimen/clock_carousel_item_height"
+            motion:layout_constraintWidth_max="@dimen/clock_carousel_item_width"
             motion:layout_constraintHorizontal_bias="0.5"
-            motion:layout_constraintStart_toStartOf="@id/guideline_start"
-            motion:layout_constraintEnd_toEndOf="@id/guideline_end"
+            motion:layout_constraintStart_toStartOf="parent"
+            motion:layout_constraintEnd_toEndOf="parent"
             motion:layout_constraintTop_toTopOf="parent"
-            motion:layout_constraintBottom_toBottomOf="parent"
-            android:layout_marginStart="@dimen/clock_carousel_item_margin"
-            android:layout_marginEnd="@dimen/clock_carousel_item_margin" />
+            motion:layout_constraintBottom_toBottomOf="parent" />
         <Constraint
             android:id="@+id/item_view_2"
-            android:layout_width="@dimen/clock_carousel_item_small_size"
-            android:layout_height="@dimen/clock_carousel_item_small_size"
+            android:layout_width="@dimen/clock_carousel_item_width"
+            android:layout_height="@dimen/clock_carousel_item_height"
             motion:layout_constraintStart_toStartOf="@id/guideline_end"
             motion:layout_constraintTop_toTopOf="parent"
-            motion:layout_constraintBottom_toBottomOf="parent"
-            android:layout_marginStart="16dp" />
+            motion:layout_constraintBottom_toBottomOf="parent" />
     </ConstraintSet>
 
     <ConstraintSet android:id="@+id/start">
         <Constraint
             android:id="@+id/item_view_1"
-            android:layout_width="@dimen/clock_carousel_item_small_size"
-            android:layout_height="@dimen/clock_carousel_item_small_size"
+            android:layout_width="@dimen/clock_carousel_item_width"
+            android:layout_height="@dimen/clock_carousel_item_height"
             motion:layout_constraintEnd_toStartOf="@id/guideline_start"
             motion:layout_constraintTop_toTopOf="parent"
-            motion:layout_constraintBottom_toBottomOf="parent"
-            android:layout_marginEnd="16dp" />
+            motion:layout_constraintBottom_toBottomOf="parent" />
         <Constraint
             android:id="@+id/item_view_2"
-            android:layout_width="0dp"
-            android:layout_height="0dp"
-            motion:layout_constraintDimensionRatio="1:1"
+            android:layout_width="@dimen/clock_carousel_item_width"
+            android:layout_height="@dimen/clock_carousel_item_height"
+            motion:layout_constraintWidth_max="@dimen/clock_carousel_item_width"
             motion:layout_constraintHorizontal_bias="0.5"
-            motion:layout_constraintStart_toStartOf="@id/guideline_start"
-            motion:layout_constraintEnd_toEndOf="@id/guideline_end"
+            motion:layout_constraintStart_toStartOf="parent"
+            motion:layout_constraintEnd_toEndOf="parent"
             motion:layout_constraintTop_toTopOf="parent"
-            motion:layout_constraintBottom_toBottomOf="parent"
-            android:layout_marginStart="@dimen/clock_carousel_item_margin"
-            android:layout_marginEnd="@dimen/clock_carousel_item_margin" />
+            motion:layout_constraintBottom_toBottomOf="parent" />
         <Constraint
             android:id="@+id/item_view_3"
-            android:layout_width="@dimen/clock_carousel_item_small_size"
-            android:layout_height="@dimen/clock_carousel_item_small_size"
+            android:layout_width="@dimen/clock_carousel_item_width"
+            android:layout_height="@dimen/clock_carousel_item_height"
             motion:layout_constraintStart_toStartOf="@id/guideline_end"
             motion:layout_constraintTop_toTopOf="parent"
-            motion:layout_constraintBottom_toBottomOf="parent"
-            android:layout_marginStart="16dp" />
+            motion:layout_constraintBottom_toBottomOf="parent" />
     </ConstraintSet>
 
     <ConstraintSet android:id="@+id/next">
         <Constraint
             android:id="@+id/item_view_2"
-            android:layout_width="@dimen/clock_carousel_item_small_size"
-            android:layout_height="@dimen/clock_carousel_item_small_size"
+            android:layout_width="@dimen/clock_carousel_item_width"
+            android:layout_height="@dimen/clock_carousel_item_height"
             motion:layout_constraintEnd_toStartOf="@id/guideline_start"
             motion:layout_constraintTop_toTopOf="parent"
-            motion:layout_constraintBottom_toBottomOf="parent"
-            android:layout_marginEnd="16dp" />
+            motion:layout_constraintBottom_toBottomOf="parent" />
         <Constraint
             android:id="@+id/item_view_3"
-            android:layout_width="0dp"
-            android:layout_height="0dp"
-            motion:layout_constraintDimensionRatio="1:1"
+            android:layout_width="@dimen/clock_carousel_item_width"
+            android:layout_height="@dimen/clock_carousel_item_height"
+            motion:layout_constraintWidth_max="@dimen/clock_carousel_item_width"
             motion:layout_constraintHorizontal_bias="0.5"
-            motion:layout_constraintStart_toStartOf="@id/guideline_start"
-            motion:layout_constraintEnd_toEndOf="@id/guideline_end"
+            motion:layout_constraintStart_toStartOf="parent"
+            motion:layout_constraintEnd_toEndOf="parent"
             motion:layout_constraintTop_toTopOf="parent"
-            motion:layout_constraintBottom_toBottomOf="parent"
-            android:layout_marginStart="@dimen/clock_carousel_item_margin"
-            android:layout_marginEnd="@dimen/clock_carousel_item_margin" />
+            motion:layout_constraintBottom_toBottomOf="parent" />
         <Constraint
             android:id="@+id/item_view_4"
-            android:layout_width="@dimen/clock_carousel_item_small_size"
-            android:layout_height="@dimen/clock_carousel_item_small_size"
+            android:layout_width="@dimen/clock_carousel_item_width"
+            android:layout_height="@dimen/clock_carousel_item_height"
             motion:layout_constraintStart_toStartOf="@id/guideline_end"
             motion:layout_constraintTop_toTopOf="parent"
-            motion:layout_constraintBottom_toBottomOf="parent"
-            android:layout_marginStart="16dp" />
+            motion:layout_constraintBottom_toBottomOf="parent" />
     </ConstraintSet>
 
 </MotionScene>
\ No newline at end of file
diff --git a/src/com/android/customization/module/CustomizationInjector.kt b/src/com/android/customization/module/CustomizationInjector.kt
index e5c1424..90a213b 100644
--- a/src/com/android/customization/module/CustomizationInjector.kt
+++ b/src/com/android/customization/module/CustomizationInjector.kt
@@ -15,6 +15,7 @@
  */
 package com.android.customization.module
 
+import android.app.Activity
 import android.content.Context
 import androidx.fragment.app.FragmentActivity
 import com.android.customization.model.theme.OverlayManagerCompat
@@ -75,7 +76,7 @@
     ): ClockCarouselViewModel
 
     fun getClockViewFactory(
-        context: Context,
+        activity: Activity,
         registry: ClockRegistry,
     ): ClockViewFactory
 
diff --git a/src/com/android/customization/module/ThemePickerInjector.kt b/src/com/android/customization/module/ThemePickerInjector.kt
index 4bef78d..2f7b5cb 100644
--- a/src/com/android/customization/module/ThemePickerInjector.kt
+++ b/src/com/android/customization/module/ThemePickerInjector.kt
@@ -15,6 +15,7 @@
  */
 package com.android.customization.module
 
+import android.app.Activity
 import android.app.UiModeManager
 import android.content.Context
 import android.content.Intent
@@ -125,7 +126,7 @@
                     object : ClockViewFactoryProvider {
                         override fun get(registry: ClockRegistry): ClockViewFactory {
                             return getClockViewFactory(
-                                context = activity,
+                                activity = activity,
                                 registry = registry,
                             )
                         }
@@ -333,11 +334,11 @@
     }
 
     override fun getClockViewFactory(
-        context: Context,
+        activity: Activity,
         registry: ClockRegistry,
     ): ClockViewFactory {
         return clockViewFactory
-            ?: ClockViewFactory(context, registry).also { clockViewFactory = it }
+            ?: ClockViewFactory(activity, registry).also { clockViewFactory = it }
     }
 
     protected fun getNotificationsInteractor(
diff --git a/src/com/android/customization/picker/clock/ui/fragment/ClockSettingsFragment.kt b/src/com/android/customization/picker/clock/ui/fragment/ClockSettingsFragment.kt
index ed14889..c25f6e6 100644
--- a/src/com/android/customization/picker/clock/ui/fragment/ClockSettingsFragment.kt
+++ b/src/com/android/customization/picker/clock/ui/fragment/ClockSettingsFragment.kt
@@ -120,7 +120,7 @@
         lifecycleScope.launch {
             val registry =
                 withContext(Dispatchers.IO) { injector.getClockRegistryProvider(context).get() }
-            val clockViewFactory = injector.getClockViewFactory(context, registry)
+            val clockViewFactory = injector.getClockViewFactory(activity, registry)
             ClockCarouselViewBinder.bind(
                     view = carouselView,
                     viewModel = injector.getClockCarouselViewModel(context, registry),
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 2771b12..e16492f 100644
--- a/src/com/android/customization/picker/clock/ui/view/ClockCarouselView.kt
+++ b/src/com/android/customization/picker/clock/ui/view/ClockCarouselView.kt
@@ -22,6 +22,7 @@
 import android.view.ViewGroup
 import android.widget.FrameLayout
 import androidx.constraintlayout.helper.widget.Carousel
+import androidx.core.view.get
 import com.android.wallpaper.R
 
 class ClockCarouselView(
@@ -67,13 +68,14 @@
         }
 
         override fun populate(view: View?, index: Int) {
-            val viewGroup = view as ViewGroup
-            viewGroup.removeAllViews()
+            val viewRoot = view as ViewGroup
+            val clockHostView = viewRoot[0] as ViewGroup
+            clockHostView.removeAllViews()
             val clockView = onGetClockPreview(clockIds[index])
             // The clock view might still be attached to an existing parent. Detach before adding to
             // another parent.
             (clockView.parent as? ViewGroup)?.removeView(clockView)
-            viewGroup.addView(clockView)
+            clockHostView.addView(clockView)
         }
 
         override fun onNewItem(index: Int) {
diff --git a/src/com/android/customization/picker/clock/ui/view/ClockViewFactory.kt b/src/com/android/customization/picker/clock/ui/view/ClockViewFactory.kt
index 8f4fb28..488dd08 100644
--- a/src/com/android/customization/picker/clock/ui/view/ClockViewFactory.kt
+++ b/src/com/android/customization/picker/clock/ui/view/ClockViewFactory.kt
@@ -1,14 +1,32 @@
+/*
+ * Copyright (C) 2023 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.customization.picker.clock.ui.view
 
-import android.content.Context
+import android.app.Activity
 import android.view.View
 import com.android.systemui.plugins.ClockController
 import com.android.systemui.shared.clocks.ClockRegistry
-import java.util.HashMap
+import com.android.wallpaper.R
+import com.android.wallpaper.util.ScreenSizeCalculator
 
-class ClockViewFactory(private val context: Context, private val registry: ClockRegistry) {
-    private val clockControllers: HashMap<String, ClockController> =
-        HashMap<String, ClockController>()
+class ClockViewFactory(
+    private val activity: Activity,
+    private val registry: ClockRegistry,
+) {
+    private val clockControllers: HashMap<String, ClockController> = HashMap()
 
     fun getView(clockId: String): View {
         return (clockControllers[clockId] ?: initClockController(clockId)).largeClock.view
@@ -16,8 +34,17 @@
 
     private fun initClockController(clockId: String): ClockController {
         val controller =
-            registry.createExampleClock(clockId).also { it?.initialize(context.resources, 0f, 0f) }
+            registry.createExampleClock(clockId).also { it?.initialize(activity.resources, 0f, 0f) }
         checkNotNull(controller)
+        val screenSizeCalculator = ScreenSizeCalculator.getInstance()
+        val screenSize = screenSizeCalculator.getScreenSize(activity.windowManager.defaultDisplay)
+        val ratio =
+            activity.resources.getDimensionPixelSize(R.dimen.screen_preview_height).toFloat() /
+                screenSize.y.toFloat()
+        controller.largeClock.events.onFontSettingChanged(
+            activity.resources.getDimensionPixelSize(R.dimen.large_clock_text_size).toFloat() *
+                ratio
+        )
         clockControllers[clockId] = controller
         return controller
     }
diff --git a/src/com/android/customization/picker/preview/ui/section/PreviewWithClockCarouselSectionController.kt b/src/com/android/customization/picker/preview/ui/section/PreviewWithClockCarouselSectionController.kt
index 186611e..9a31ae9 100644
--- a/src/com/android/customization/picker/preview/ui/section/PreviewWithClockCarouselSectionController.kt
+++ b/src/com/android/customization/picker/preview/ui/section/PreviewWithClockCarouselSectionController.kt
@@ -65,7 +65,11 @@
         displayUtils,
         navigator,
     ) {
+
     private var clockCarouselBinding: ClockCarouselViewBinder.Binding? = null
+
+    override val hideLockScreenClockPreview = true
+
     override fun createView(context: Context): ScreenPreviewView {
         val view = super.createView(context)
         val carouselViewStub: ViewStub = view.requireViewById(R.id.clock_carousel_view_stub)
diff --git a/tests/src/com/android/customization/testing/TestCustomizationInjector.kt b/tests/src/com/android/customization/testing/TestCustomizationInjector.kt
index 2627f92..0aac5cc 100644
--- a/tests/src/com/android/customization/testing/TestCustomizationInjector.kt
+++ b/tests/src/com/android/customization/testing/TestCustomizationInjector.kt
@@ -1,5 +1,6 @@
 package com.android.customization.testing
 
+import android.app.Activity
 import android.content.Context
 import androidx.fragment.app.FragmentActivity
 import com.android.customization.model.theme.OverlayManagerCompat
@@ -199,9 +200,12 @@
             }
     }
 
-    override fun getClockViewFactory(context: Context, registry: ClockRegistry): ClockViewFactory {
+    override fun getClockViewFactory(
+        activity: Activity,
+        registry: ClockRegistry
+    ): ClockViewFactory {
         return clockViewFactory
-            ?: ClockViewFactory(context, registry).also { clockViewFactory = it }
+            ?: ClockViewFactory(activity, registry).also { clockViewFactory = it }
     }
 
     override fun getClockSettingsViewModelFactory(