Merge "Import translations. DO NOT MERGE ANYWHERE" into tm-qpr-dev
diff --git a/res/layout/clock_carousel.xml b/res/layout/clock_carousel.xml
new file mode 100644
index 0000000..098586e
--- /dev/null
+++ b/res/layout/clock_carousel.xml
@@ -0,0 +1,102 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+     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.
+-->
+<androidx.constraintlayout.motion.widget.MotionLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    android:id="@+id/motion_container"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    app:layoutDescription="@xml/carousel_scene">
+
+    <FrameLayout
+        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"
+        app:layout_constraintBottom_toBottomOf="parent"
+        app:layout_constraintEnd_toStartOf="@+id/item_view_1"
+        app:layout_constraintTop_toTopOf="parent" />
+
+    <FrameLayout
+        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"
+        app:layout_constraintBottom_toBottomOf="parent"
+        app:layout_constraintEnd_toStartOf="@+id/item_view_2"
+        app:layout_constraintTop_toTopOf="parent" />
+
+    <FrameLayout
+        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"
+        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" />
+
+    <FrameLayout
+        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"
+        app:layout_constraintBottom_toBottomOf="parent"
+        app:layout_constraintStart_toEndOf="@+id/item_view_2"
+        app:layout_constraintTop_toTopOf="parent" />
+
+    <FrameLayout
+        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"
+        app:layout_constraintBottom_toBottomOf="parent"
+        app:layout_constraintStart_toEndOf="@+id/item_view_3"
+        app:layout_constraintTop_toTopOf="parent" />
+
+    <androidx.constraintlayout.helper.widget.Carousel
+        android:id="@+id/carousel"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        app:carousel_backwardTransition="@+id/backward"
+        app:carousel_firstView="@+id/item_view_2"
+        app:carousel_forwardTransition="@+id/forward"
+        app:carousel_infinite="true"
+        app:carousel_nextState="@+id/next"
+        app:carousel_previousState="@+id/previous"
+        app:constraint_referenced_ids="item_view_0,item_view_1,item_view_2,item_view_3,item_view_4" />
+
+    <!-- The guidelines make sure that only the view in the middle show between the lines  -->
+    <androidx.constraintlayout.widget.Guideline
+        android:id="@+id/guideline_start"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:orientation="vertical"
+        app:layout_constraintGuide_begin="100dp" />
+
+    <androidx.constraintlayout.widget.Guideline
+        android:id="@+id/guideline_end"
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:orientation="vertical"
+        app:layout_constraintGuide_end="100dp" />
+</androidx.constraintlayout.motion.widget.MotionLayout>
\ No newline at end of file
diff --git a/res/layout/clock_carousel_view.xml b/res/layout/clock_carousel_view.xml
index 996eaa3..21ff266 100644
--- a/res/layout/clock_carousel_view.xml
+++ b/res/layout/clock_carousel_view.xml
@@ -14,89 +14,7 @@
      See the License for the specific language governing permissions and
      limitations under the License.
 -->
-<androidx.constraintlayout.motion.widget.MotionLayout
+<com.android.customization.picker.clock.ui.view.ClockCarouselView
     xmlns:android="http://schemas.android.com/apk/res/android"
-    xmlns:app="http://schemas.android.com/apk/res-auto"
-    android:id="@+id/motion_container"
     android:layout_width="match_parent"
-    android:layout_height="wrap_content"
-    app:layoutDescription="@xml/carousel_scene">
-
-    <FrameLayout
-        android:id="@+id/item_view_0"
-        android:layout_width="100dp"
-        android:layout_height="100dp"
-        android:layout_marginEnd="16dp"
-        android:scaleType="centerCrop"
-        app:layout_constraintBottom_toBottomOf="parent"
-        app:layout_constraintEnd_toStartOf="@+id/item_view_1"
-        app:layout_constraintTop_toTopOf="parent" />
-
-    <FrameLayout
-        android:id="@+id/item_view_1"
-        android:layout_width="100dp"
-        android:layout_height="100dp"
-        android:layout_marginEnd="16dp"
-        android:scaleType="centerCrop"
-        app:layout_constraintBottom_toBottomOf="parent"
-        app:layout_constraintEnd_toStartOf="@+id/item_view_2"
-        app:layout_constraintTop_toTopOf="parent" />
-
-    <FrameLayout
-        android:id="@+id/item_view_2"
-        android:layout_width="150dp"
-        android:layout_height="150dp"
-        android:scaleType="centerCrop"
-        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" />
-
-    <FrameLayout
-        android:id="@+id/item_view_3"
-        android:layout_width="100dp"
-        android:layout_height="100dp"
-        android:layout_marginStart="16dp"
-        android:scaleType="centerCrop"
-        app:layout_constraintBottom_toBottomOf="parent"
-        app:layout_constraintStart_toEndOf="@+id/item_view_2"
-        app:layout_constraintTop_toTopOf="parent" />
-
-    <FrameLayout
-        android:id="@+id/item_view_4"
-        android:layout_width="100dp"
-        android:layout_height="100dp"
-        android:layout_marginStart="16dp"
-        android:scaleType="centerCrop"
-        app:layout_constraintBottom_toBottomOf="parent"
-        app:layout_constraintStart_toEndOf="@+id/item_view_3"
-        app:layout_constraintTop_toTopOf="parent" />
-
-    <androidx.constraintlayout.helper.widget.Carousel
-        android:id="@+id/carousel"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        app:carousel_backwardTransition="@+id/backward"
-        app:carousel_firstView="@+id/item_view_2"
-        app:carousel_forwardTransition="@+id/forward"
-        app:carousel_infinite="true"
-        app:carousel_nextState="@+id/next"
-        app:carousel_previousState="@+id/previous"
-        app:constraint_referenced_ids="item_view_0,item_view_1,item_view_2,item_view_3,item_view_4" />
-
-    <!-- The guidelines make sure that only the view in the middle show between the lines  -->
-    <androidx.constraintlayout.widget.Guideline
-        android:id="@+id/guideline_start"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:orientation="vertical"
-        app:layout_constraintGuide_begin="100dp" />
-
-    <androidx.constraintlayout.widget.Guideline
-        android:id="@+id/guideline_end"
-        android:layout_width="wrap_content"
-        android:layout_height="wrap_content"
-        android:orientation="vertical"
-        app:layout_constraintGuide_end="100dp" />
-</androidx.constraintlayout.motion.widget.MotionLayout>
\ No newline at end of file
+    android:layout_height="wrap_content"/>
\ No newline at end of file
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index 9099c93..febca46 100644
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -152,4 +152,8 @@
     <dimen name="keyguard_quick_affordance_icon_size">24dp</dimen>
     <!-- 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>
 </resources>
diff --git a/res/xml/carousel_scene.xml b/res/xml/carousel_scene.xml
index 05007f4..345f690 100644
--- a/res/xml/carousel_scene.xml
+++ b/res/xml/carousel_scene.xml
@@ -40,8 +40,8 @@
     <ConstraintSet android:id="@+id/previous">
         <Constraint
             android:id="@+id/item_view_0"
-            android:layout_width="100dp"
-            android:layout_height="100dp"
+            android:layout_width="@dimen/clock_carousel_item_small_size"
+            android:layout_height="@dimen/clock_carousel_item_small_size"
             motion:layout_constraintEnd_toStartOf="@id/guideline_start"
             motion:layout_constraintTop_toTopOf="parent"
             motion:layout_constraintBottom_toBottomOf="parent"
@@ -56,12 +56,12 @@
             motion:layout_constraintEnd_toEndOf="@id/guideline_end"
             motion:layout_constraintTop_toTopOf="parent"
             motion:layout_constraintBottom_toBottomOf="parent"
-            android:layout_marginStart="16dp"
-            android:layout_marginEnd="16dp" />
+            android:layout_marginStart="@dimen/clock_carousel_item_margin"
+            android:layout_marginEnd="@dimen/clock_carousel_item_margin" />
         <Constraint
             android:id="@+id/item_view_2"
-            android:layout_width="100dp"
-            android:layout_height="100dp"
+            android:layout_width="@dimen/clock_carousel_item_small_size"
+            android:layout_height="@dimen/clock_carousel_item_small_size"
             motion:layout_constraintStart_toStartOf="@id/guideline_end"
             motion:layout_constraintTop_toTopOf="parent"
             motion:layout_constraintBottom_toBottomOf="parent"
@@ -71,8 +71,8 @@
     <ConstraintSet android:id="@+id/start">
         <Constraint
             android:id="@+id/item_view_1"
-            android:layout_width="100dp"
-            android:layout_height="100dp"
+            android:layout_width="@dimen/clock_carousel_item_small_size"
+            android:layout_height="@dimen/clock_carousel_item_small_size"
             motion:layout_constraintEnd_toStartOf="@id/guideline_start"
             motion:layout_constraintTop_toTopOf="parent"
             motion:layout_constraintBottom_toBottomOf="parent"
@@ -87,12 +87,12 @@
             motion:layout_constraintEnd_toEndOf="@id/guideline_end"
             motion:layout_constraintTop_toTopOf="parent"
             motion:layout_constraintBottom_toBottomOf="parent"
-            android:layout_marginStart="16dp"
-            android:layout_marginEnd="16dp" />
+            android:layout_marginStart="@dimen/clock_carousel_item_margin"
+            android:layout_marginEnd="@dimen/clock_carousel_item_margin" />
         <Constraint
             android:id="@+id/item_view_3"
-            android:layout_width="100dp"
-            android:layout_height="100dp"
+            android:layout_width="@dimen/clock_carousel_item_small_size"
+            android:layout_height="@dimen/clock_carousel_item_small_size"
             motion:layout_constraintStart_toStartOf="@id/guideline_end"
             motion:layout_constraintTop_toTopOf="parent"
             motion:layout_constraintBottom_toBottomOf="parent"
@@ -102,8 +102,8 @@
     <ConstraintSet android:id="@+id/next">
         <Constraint
             android:id="@+id/item_view_2"
-            android:layout_width="100dp"
-            android:layout_height="100dp"
+            android:layout_width="@dimen/clock_carousel_item_small_size"
+            android:layout_height="@dimen/clock_carousel_item_small_size"
             motion:layout_constraintEnd_toStartOf="@id/guideline_start"
             motion:layout_constraintTop_toTopOf="parent"
             motion:layout_constraintBottom_toBottomOf="parent"
@@ -118,12 +118,12 @@
             motion:layout_constraintEnd_toEndOf="@id/guideline_end"
             motion:layout_constraintTop_toTopOf="parent"
             motion:layout_constraintBottom_toBottomOf="parent"
-            android:layout_marginStart="16dp"
-            android:layout_marginEnd="16dp" />
+            android:layout_marginStart="@dimen/clock_carousel_item_margin"
+            android:layout_marginEnd="@dimen/clock_carousel_item_margin" />
         <Constraint
             android:id="@+id/item_view_4"
-            android:layout_width="100dp"
-            android:layout_height="100dp"
+            android:layout_width="@dimen/clock_carousel_item_small_size"
+            android:layout_height="@dimen/clock_carousel_item_small_size"
             motion:layout_constraintStart_toStartOf="@id/guideline_end"
             motion:layout_constraintTop_toTopOf="parent"
             motion:layout_constraintBottom_toBottomOf="parent"
diff --git a/src/com/android/customization/module/CustomizationInjector.kt b/src/com/android/customization/module/CustomizationInjector.kt
index 1f0507e..26bd925 100644
--- a/src/com/android/customization/module/CustomizationInjector.kt
+++ b/src/com/android/customization/module/CustomizationInjector.kt
@@ -22,6 +22,7 @@
 import com.android.customization.model.theme.ThemeManager
 import com.android.customization.picker.clock.data.repository.ClockRegistryProvider
 import com.android.customization.picker.clock.domain.interactor.ClockPickerInteractor
+import com.android.customization.picker.clock.ui.viewmodel.ClockCarouselViewModel
 import com.android.customization.picker.clock.ui.viewmodel.ClockSectionViewModel
 import com.android.customization.picker.color.domain.interactor.ColorPickerInteractor
 import com.android.customization.picker.color.ui.viewmodel.ColorPickerViewModel
@@ -37,23 +38,23 @@
         provider: ThemeBundleProvider,
         activity: FragmentActivity,
         overlayManagerCompat: OverlayManagerCompat,
-        logger: ThemesUserEventLogger
+        logger: ThemesUserEventLogger,
     ): ThemeManager
 
     fun getKeyguardQuickAffordancePickerInteractor(
-        context: Context
+        context: Context,
     ): KeyguardQuickAffordancePickerInteractor
 
     fun getClockRegistryProvider(context: Context): ClockRegistryProvider
 
     fun getClockPickerInteractor(
         context: Context,
-        clockRegistry: ClockRegistry
+        clockRegistry: ClockRegistry,
     ): ClockPickerInteractor
 
     fun getClockSectionViewModel(
         context: Context,
-        clockRegistry: ClockRegistry
+        clockRegistry: ClockRegistry,
     ): ClockSectionViewModel
 
     fun getColorPickerInteractor(
@@ -65,4 +66,9 @@
         context: Context,
         wallpaperColorsViewModel: WallpaperColorsViewModel,
     ): ColorPickerViewModel.Factory
+
+    fun getClockCarouselViewModel(
+        context: Context,
+        clockRegistry: ClockRegistry,
+    ): ClockCarouselViewModel
 }
diff --git a/src/com/android/customization/module/DefaultCustomizationSections.java b/src/com/android/customization/module/DefaultCustomizationSections.java
index 2b29312..ab894f8 100644
--- a/src/com/android/customization/module/DefaultCustomizationSections.java
+++ b/src/com/android/customization/module/DefaultCustomizationSections.java
@@ -14,12 +14,16 @@
 import com.android.customization.model.mode.DarkModeSectionController;
 import com.android.customization.model.themedicon.ThemedIconSectionController;
 import com.android.customization.model.themedicon.ThemedIconSwitchProvider;
+import com.android.customization.picker.clock.data.repository.ClockRegistryProvider;
 import com.android.customization.picker.notifications.ui.section.NotificationSectionController;
 import com.android.customization.picker.notifications.ui.viewmodel.NotificationSectionViewModel;
+import com.android.customization.picker.preview.ui.section.PreviewWithClockCarouselSectionController;
+import com.android.customization.picker.preview.ui.section.PreviewWithClockCarouselSectionController.ClockCarouselViewModelProvider;
 import com.android.customization.picker.quickaffordance.domain.interactor.KeyguardQuickAffordancePickerInteractor;
 import com.android.customization.picker.quickaffordance.ui.section.KeyguardQuickAffordanceSectionController;
 import com.android.customization.picker.quickaffordance.ui.viewmodel.KeyguardQuickAffordancePickerViewModel;
 import com.android.customization.picker.settings.ui.section.MoreSettingsSectionController;
+import com.android.wallpaper.config.BaseFlags;
 import com.android.wallpaper.model.CustomizationSectionController;
 import com.android.wallpaper.model.CustomizationSectionController.CustomizationSectionNavigationController;
 import com.android.wallpaper.model.PermissionRequester;
@@ -45,16 +49,26 @@
     private final KeyguardQuickAffordancePickerViewModel.Factory
             mKeyguardQuickAffordancePickerViewModelFactory;
     private final NotificationSectionViewModel.Factory mNotificationSectionViewModelFactory;
+    private final BaseFlags mFlags;
+    private final ClockRegistryProvider mClockRegistryProvider;
+    private final PreviewWithClockCarouselSectionController.ClockCarouselViewModelProvider
+            mClockCarouselViewModelProvider;
 
     public DefaultCustomizationSections(
             KeyguardQuickAffordancePickerInteractor keyguardQuickAffordancePickerInteractor,
             KeyguardQuickAffordancePickerViewModel.Factory
                     keyguardQuickAffordancePickerViewModelFactory,
-            NotificationSectionViewModel.Factory notificationSectionViewModelFactory) {
+            NotificationSectionViewModel.Factory notificationSectionViewModelFactory,
+            BaseFlags flags,
+            ClockRegistryProvider clockRegistryProvider,
+            ClockCarouselViewModelProvider clockCarouselViewModelProvider) {
         mKeyguardQuickAffordancePickerInteractor = keyguardQuickAffordancePickerInteractor;
         mKeyguardQuickAffordancePickerViewModelFactory =
                 keyguardQuickAffordancePickerViewModelFactory;
         mNotificationSectionViewModelFactory = notificationSectionViewModelFactory;
+        mFlags = flags;
+        mClockRegistryProvider = clockRegistryProvider;
+        mClockCarouselViewModelProvider = clockCarouselViewModelProvider;
     }
 
     @Override
@@ -75,13 +89,23 @@
 
         // Wallpaper section.
         sectionControllers.add(
-                new ScreenPreviewSectionController(
+                mFlags.isCustomClocksEnabled(activity)
+                        ? new PreviewWithClockCarouselSectionController(
                         activity,
                         lifecycleOwner,
                         screen,
                         wallpaperInfoFactory,
                         wallpaperColorsViewModel,
-                        displayUtils));
+                        displayUtils,
+                        mClockRegistryProvider,
+                        mClockCarouselViewModelProvider)
+                        : new ScreenPreviewSectionController(
+                                activity,
+                                lifecycleOwner,
+                                screen,
+                                wallpaperInfoFactory,
+                                wallpaperColorsViewModel,
+                                displayUtils));
 
         sectionControllers.add(
                 new ConnectedSectionController(
diff --git a/src/com/android/customization/module/ThemePickerInjector.kt b/src/com/android/customization/module/ThemePickerInjector.kt
index c958123..e4b60b9 100644
--- a/src/com/android/customization/module/ThemePickerInjector.kt
+++ b/src/com/android/customization/module/ThemePickerInjector.kt
@@ -28,6 +28,7 @@
 import com.android.customization.picker.clock.data.repository.ClockPickerRepositoryImpl
 import com.android.customization.picker.clock.data.repository.ClockRegistryProvider
 import com.android.customization.picker.clock.domain.interactor.ClockPickerInteractor
+import com.android.customization.picker.clock.ui.viewmodel.ClockCarouselViewModel
 import com.android.customization.picker.clock.ui.viewmodel.ClockSectionViewModel
 import com.android.customization.picker.color.data.repository.ColorPickerRepositoryImpl
 import com.android.customization.picker.color.domain.interactor.ColorPickerInteractor
@@ -35,6 +36,7 @@
 import com.android.customization.picker.notifications.data.repository.NotificationsRepository
 import com.android.customization.picker.notifications.domain.interactor.NotificationsInteractor
 import com.android.customization.picker.notifications.ui.viewmodel.NotificationSectionViewModel
+import com.android.customization.picker.preview.ui.section.PreviewWithClockCarouselSectionController
 import com.android.customization.picker.quickaffordance.data.repository.KeyguardQuickAffordancePickerRepository
 import com.android.customization.picker.quickaffordance.domain.interactor.KeyguardQuickAffordancePickerInteractor
 import com.android.customization.picker.quickaffordance.domain.interactor.KeyguardQuickAffordanceSnapshotRestorer
@@ -74,6 +76,7 @@
     private var clockRegistryProvider: ClockRegistryProvider? = null
     private var clockPickerInteractor: ClockPickerInteractor? = null
     private var clockSectionViewModel: ClockSectionViewModel? = null
+    private var clockCarouselViewModel: ClockCarouselViewModel? = null
     private var notificationsInteractor: NotificationsInteractor? = null
     private var notificationSectionViewModelFactory: NotificationSectionViewModel.Factory? = null
     private var colorPickerInteractor: ColorPickerInteractor? = null
@@ -87,6 +90,17 @@
                     NotificationSectionViewModel.Factory(
                         interactor = getNotificationsInteractor(activity),
                     ),
+                    getFlags(),
+                    getClockRegistryProvider(activity),
+                    object :
+                        PreviewWithClockCarouselSectionController.ClockCarouselViewModelProvider {
+                        override fun get(registry: ClockRegistry): ClockCarouselViewModel {
+                            return getClockCarouselViewModel(
+                                context = activity,
+                                clockRegistry = registry,
+                            )
+                        }
+                    }
                 )
                 .also { customizationSections = it }
     }
@@ -255,6 +269,16 @@
             }
     }
 
+    override fun getClockCarouselViewModel(
+        context: Context,
+        clockRegistry: ClockRegistry
+    ): ClockCarouselViewModel {
+        return clockCarouselViewModel
+            ?: ClockCarouselViewModel(getClockPickerInteractor(context, clockRegistry)).also {
+                clockCarouselViewModel = it
+            }
+    }
+
     protected fun getNotificationsInteractor(
         context: Context,
     ): NotificationsInteractor {
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 595057b..841c411 100644
--- a/src/com/android/customization/picker/clock/ui/binder/ClockCarouselViewBinder.kt
+++ b/src/com/android/customization/picker/clock/ui/binder/ClockCarouselViewBinder.kt
@@ -16,6 +16,7 @@
 package com.android.customization.picker.clock.ui.binder
 
 import android.view.View
+import androidx.core.view.isVisible
 import androidx.lifecycle.Lifecycle
 import androidx.lifecycle.LifecycleOwner
 import androidx.lifecycle.lifecycleScope
@@ -25,12 +26,22 @@
 import kotlinx.coroutines.launch
 
 object ClockCarouselViewBinder {
+    /**
+     * The binding is used by the view where there is an action executed from another view, e.g.
+     * toggling show/hide of the view that the binder is holding.
+     */
+    interface Binding {
+        fun show()
+        fun hide()
+    }
+
+    @JvmStatic
     fun bind(
         view: ClockCarouselView,
         viewModel: ClockCarouselViewModel,
         clockViewFactory: (clockId: String) -> View,
         lifecycleOwner: LifecycleOwner,
-    ) {
+    ): Binding {
         view.setUpImageCarouselView(
             clockIds = viewModel.allClockIds,
             onGetClockPreview = clockViewFactory,
@@ -41,5 +52,14 @@
                 launch { viewModel.selectedClockId.collect { view.setSelectedClockId(it) } }
             }
         }
+        return object : Binding {
+            override fun show() {
+                view.isVisible = true
+            }
+
+            override fun hide() {
+                view.isVisible = false
+            }
+        }
     }
 }
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 68ec014..1f49c55 100644
--- a/src/com/android/customization/picker/clock/ui/view/ClockCarouselView.kt
+++ b/src/com/android/customization/picker/clock/ui/view/ClockCarouselView.kt
@@ -37,7 +37,7 @@
     private lateinit var adapter: ClockCarouselAdapter
 
     init {
-        val view = LayoutInflater.from(context).inflate(R.layout.clock_carousel_view, this)
+        val view = LayoutInflater.from(context).inflate(R.layout.clock_carousel, this)
         carousel = view.requireViewById(R.id.carousel)
     }
 
diff --git a/src/com/android/customization/picker/preview/ui/section/PreviewWithClockCarouselSectionController.kt b/src/com/android/customization/picker/preview/ui/section/PreviewWithClockCarouselSectionController.kt
new file mode 100644
index 0000000..d90961b
--- /dev/null
+++ b/src/com/android/customization/picker/preview/ui/section/PreviewWithClockCarouselSectionController.kt
@@ -0,0 +1,98 @@
+/*
+ * 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.preview.ui.section
+
+import android.app.Activity
+import android.content.Context
+import android.view.ViewStub
+import androidx.lifecycle.LifecycleOwner
+import androidx.lifecycle.lifecycleScope
+import com.android.customization.picker.clock.data.repository.ClockRegistryProvider
+import com.android.customization.picker.clock.ui.binder.ClockCarouselViewBinder
+import com.android.customization.picker.clock.ui.view.ClockCarouselView
+import com.android.customization.picker.clock.ui.viewmodel.ClockCarouselViewModel
+import com.android.systemui.shared.clocks.ClockRegistry
+import com.android.wallpaper.R
+import com.android.wallpaper.model.WallpaperColorsViewModel
+import com.android.wallpaper.module.CurrentWallpaperInfoFactory
+import com.android.wallpaper.module.CustomizationSections
+import com.android.wallpaper.picker.customization.ui.section.ScreenPreviewSectionController
+import com.android.wallpaper.picker.customization.ui.section.ScreenPreviewView
+import com.android.wallpaper.util.DisplayUtils
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.launch
+import kotlinx.coroutines.withContext
+
+/** Controls the screen preview section. */
+@OptIn(ExperimentalCoroutinesApi::class)
+class PreviewWithClockCarouselSectionController(
+    private val activity: Activity,
+    private val lifecycleOwner: LifecycleOwner,
+    private val initialScreen: CustomizationSections.Screen,
+    private val wallpaperInfoFactory: CurrentWallpaperInfoFactory,
+    private val colorViewModel: WallpaperColorsViewModel,
+    private val displayUtils: DisplayUtils,
+    private val clockRegistryProvider: ClockRegistryProvider,
+    private val clockCarouselViewModelProvider: ClockCarouselViewModelProvider,
+) :
+    ScreenPreviewSectionController(
+        activity,
+        lifecycleOwner,
+        initialScreen,
+        wallpaperInfoFactory,
+        colorViewModel,
+        displayUtils,
+    ) {
+    private var clockCarouselBinding: ClockCarouselViewBinder.Binding? = null
+    override fun createView(context: Context): ScreenPreviewView {
+        val view = super.createView(context)
+        val carouselViewStub: ViewStub = view.requireViewById(R.id.clock_carousel_view_stub)
+        carouselViewStub.layoutResource = R.layout.clock_carousel_view
+        val carouselView: ClockCarouselView = carouselViewStub.inflate() as ClockCarouselView
+        lifecycleOwner.lifecycleScope.launch {
+            val registry = withContext(Dispatchers.IO) { clockRegistryProvider.get() }
+            clockCarouselBinding =
+                ClockCarouselViewBinder.bind(
+                    view = carouselView,
+                    viewModel = clockCarouselViewModelProvider.get(registry),
+                    clockViewFactory = { clockId ->
+                        registry.createExampleClock(clockId)?.largeClock?.view!!
+                    },
+                    lifecycleOwner = lifecycleOwner,
+                )
+            onScreenSwitched(
+                isOnLockScreen = initialScreen == CustomizationSections.Screen.LOCK_SCREEN
+            )
+        }
+        return view
+    }
+
+    override fun onScreenSwitched(isOnLockScreen: Boolean) {
+        super.onScreenSwitched(isOnLockScreen)
+        if (isOnLockScreen) {
+            clockCarouselBinding?.show()
+        } else {
+            clockCarouselBinding?.hide()
+        }
+    }
+
+    interface ClockCarouselViewModelProvider {
+        fun get(registry: ClockRegistry): ClockCarouselViewModel
+    }
+}
diff --git a/tests/src/com/android/customization/testing/TestCustomizationInjector.kt b/tests/src/com/android/customization/testing/TestCustomizationInjector.kt
index fca4904..3dce587 100644
--- a/tests/src/com/android/customization/testing/TestCustomizationInjector.kt
+++ b/tests/src/com/android/customization/testing/TestCustomizationInjector.kt
@@ -11,6 +11,7 @@
 import com.android.customization.picker.clock.data.repository.ClockRegistryProvider
 import com.android.customization.picker.clock.data.repository.FakeClockPickerRepository
 import com.android.customization.picker.clock.domain.interactor.ClockPickerInteractor
+import com.android.customization.picker.clock.ui.viewmodel.ClockCarouselViewModel
 import com.android.customization.picker.clock.ui.viewmodel.ClockSectionViewModel
 import com.android.customization.picker.color.data.repository.ColorPickerRepositoryImpl
 import com.android.customization.picker.color.domain.interactor.ColorPickerInteractor
@@ -48,6 +49,7 @@
     private var clockSectionViewModel: ClockSectionViewModel? = null
     private var colorPickerInteractor: ColorPickerInteractor? = null
     private var colorPickerViewModelFactory: ColorPickerViewModel.Factory? = null
+    private var clockCarouselViewModel: ClockCarouselViewModel? = null
 
     override fun getCustomizationPreferences(context: Context): CustomizationPreferences {
         return customizationPreferences
@@ -179,6 +181,16 @@
                 .also { colorPickerViewModelFactory = it }
     }
 
+    override fun getClockCarouselViewModel(
+        context: Context,
+        clockRegistry: ClockRegistry
+    ): ClockCarouselViewModel {
+        return clockCarouselViewModel
+            ?: ClockCarouselViewModel(getClockPickerInteractor(context, clockRegistry)).also {
+                clockCarouselViewModel = it
+            }
+    }
+
     companion object {
         private const val KEY_QUICK_AFFORDANCE_SNAPSHOT_RESTORER = 1
     }