Merge "Import translations. DO NOT MERGE ANYWHERE" into udc-dev
diff --git a/res/layout/clock_carousel.xml b/res/layout/clock_carousel.xml
index e253f1a..a43e804 100644
--- a/res/layout/clock_carousel.xml
+++ b/res/layout/clock_carousel.xml
@@ -42,8 +42,9 @@
             android:id="@+id/clock_scale_view_0"
             android:layout_width="@dimen/screen_preview_width"
             android:layout_height="wrap_content"
-            android:layout_gravity="center">
-            <FrameLayout
+            android:layout_gravity="center"
+            android:clipChildren="false">
+            <com.android.customization.picker.clock.ui.view.ClockHostView
                 android:id="@+id/clock_host_view_0"
                 android:layout_width="match_parent"
                 android:layout_height="match_parent"
@@ -72,8 +73,9 @@
             android:id="@+id/clock_scale_view_1"
             android:layout_width="@dimen/screen_preview_width"
             android:layout_height="wrap_content"
-            android:layout_gravity="center">
-            <FrameLayout
+            android:layout_gravity="center"
+            android:clipChildren="false">
+            <com.android.customization.picker.clock.ui.view.ClockHostView
                 android:id="@+id/clock_host_view_1"
                 android:layout_width="match_parent"
                 android:layout_height="match_parent"
@@ -104,8 +106,9 @@
             android:id="@+id/clock_scale_view_2"
             android:layout_width="@dimen/screen_preview_width"
             android:layout_height="wrap_content"
-            android:layout_gravity="center">
-            <FrameLayout
+            android:layout_gravity="center"
+            android:clipChildren="false">
+            <com.android.customization.picker.clock.ui.view.ClockHostView
                 android:id="@+id/clock_host_view_2"
                 android:layout_width="match_parent"
                 android:layout_height="match_parent"
@@ -134,8 +137,9 @@
             android:id="@+id/clock_scale_view_3"
             android:layout_width="@dimen/screen_preview_width"
             android:layout_height="wrap_content"
-            android:layout_gravity="center">
-            <FrameLayout
+            android:layout_gravity="center"
+            android:clipChildren="false">
+            <com.android.customization.picker.clock.ui.view.ClockHostView
                 android:id="@+id/clock_host_view_3"
                 android:layout_width="match_parent"
                 android:layout_height="match_parent"
@@ -164,8 +168,9 @@
             android:id="@+id/clock_scale_view_4"
             android:layout_width="@dimen/screen_preview_width"
             android:layout_height="wrap_content"
-            android:layout_gravity="center">
-            <FrameLayout
+            android:layout_gravity="center"
+            android:clipChildren="false">
+            <com.android.customization.picker.clock.ui.view.ClockHostView
                 android:id="@+id/clock_host_view_4"
                 android:layout_width="match_parent"
                 android:layout_height="match_parent"
diff --git a/res/layout/fragment_clock_settings.xml b/res/layout/fragment_clock_settings.xml
index 74741f5..23fbfb8 100644
--- a/res/layout/fragment_clock_settings.xml
+++ b/res/layout/fragment_clock_settings.xml
@@ -34,7 +34,8 @@
         android:layout_height="0dp"
         android:layout_weight="1"
         android:paddingTop="20dp"
-        android:paddingBottom="40dp">
+        android:paddingBottom="40dp"
+        android:clipChildren="false">
 
         <include
             android:id="@+id/lock_preview"
@@ -43,7 +44,7 @@
             android:layout_height="match_parent"
             android:layout_gravity="center" />
 
-        <FrameLayout
+        <com.android.customization.picker.clock.ui.view.ClockHostView
             android:id="@+id/clock_host_view"
             android:layout_width="match_parent"
             android:layout_height="match_parent"
diff --git a/res/layout/single_clock_view.xml b/res/layout/single_clock_view.xml
index ca408d7..ffc6039 100644
--- a/res/layout/single_clock_view.xml
+++ b/res/layout/single_clock_view.xml
@@ -17,8 +17,9 @@
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="@dimen/screen_preview_width"
     android:layout_height="wrap_content"
-    android:layout_gravity="center">
-    <FrameLayout
+    android:layout_gravity="center"
+    android:clipChildren="false">
+    <com.android.customization.picker.clock.ui.view.ClockHostView
         android:id="@+id/single_clock_host_view"
         android:layout_width="match_parent"
         android:layout_height="match_parent"
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 f455600..c95561c 100644
--- a/src/com/android/customization/picker/clock/ui/binder/ClockCarouselViewBinder.kt
+++ b/src/com/android/customization/picker/clock/ui/binder/ClockCarouselViewBinder.kt
@@ -64,7 +64,6 @@
 
                                 hideSmartspace(hasCustomWeatherDataDisplay)
                             },
-                            previewRatio = clockViewFactory.getRatio(),
                         )
                     }
                 }
diff --git a/src/com/android/customization/picker/clock/ui/binder/ClockSettingsBinder.kt b/src/com/android/customization/picker/clock/ui/binder/ClockSettingsBinder.kt
index 65631cc..921151b 100644
--- a/src/com/android/customization/picker/clock/ui/binder/ClockSettingsBinder.kt
+++ b/src/com/android/customization/picker/clock/ui/binder/ClockSettingsBinder.kt
@@ -19,7 +19,6 @@
 import android.view.LayoutInflater
 import android.view.View
 import android.view.ViewGroup
-import android.widget.FrameLayout
 import android.widget.LinearLayout
 import android.widget.SeekBar
 import androidx.core.view.isInvisible
@@ -33,6 +32,7 @@
 import androidx.recyclerview.widget.RecyclerView
 import com.android.customization.picker.clock.shared.ClockSize
 import com.android.customization.picker.clock.ui.adapter.ClockSettingsTabAdapter
+import com.android.customization.picker.clock.ui.view.ClockHostView
 import com.android.customization.picker.clock.ui.view.ClockSizeRadioButtonGroup
 import com.android.customization.picker.clock.ui.view.ClockViewFactory
 import com.android.customization.picker.clock.ui.viewmodel.ClockSettingsViewModel
@@ -55,8 +55,7 @@
         clockViewFactory: ClockViewFactory,
         lifecycleOwner: LifecycleOwner,
     ) {
-        val clockHostView: FrameLayout = view.requireViewById(R.id.clock_host_view)
-
+        val clockHostView: ClockHostView = view.requireViewById(R.id.clock_host_view)
         val tabView: RecyclerView = view.requireViewById(R.id.tabs)
         val tabAdapter = ClockSettingsTabAdapter()
         tabView.adapter = tabAdapter
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 3cf5471..46a2801 100644
--- a/src/com/android/customization/picker/clock/ui/view/ClockCarouselView.kt
+++ b/src/com/android/customization/picker/clock/ui/view/ClockCarouselView.kt
@@ -56,10 +56,8 @@
         clockIds: List<String>,
         onGetClockController: (clockId: String) -> ClockController,
         onClockSelected: (clockId: String) -> Unit,
-        previewRatio: Float,
     ) {
-        adapter =
-            ClockCarouselAdapter(clockIds, onGetClockController, onClockSelected, previewRatio)
+        adapter = ClockCarouselAdapter(clockIds, onGetClockController, onClockSelected)
         carousel.setAdapter(adapter)
         carousel.refresh()
         motionLayout.setTransitionListener(
@@ -100,17 +98,11 @@
                     scalingDownClockController
                         ?.largeClock
                         ?.animations
-                        ?.onPickerCarouselSwiping(
-                            1 - progress,
-                            previewRatio,
-                        )
+                        ?.onPickerCarouselSwiping(1 - progress)
                     scalingUpClockController
                         ?.largeClock
                         ?.animations
-                        ?.onPickerCarouselSwiping(
-                            progress,
-                            previewRatio,
-                        )
+                        ?.onPickerCarouselSwiping(progress)
                     val scalingUpScale = getScalingUpScale(progress)
                     val scalingDownScale = getScalingDownScale(progress)
                     scalingUpClockView?.scaleX = scalingUpScale
@@ -133,17 +125,11 @@
                     scalingDownClockController
                         ?.largeClock
                         ?.animations
-                        ?.onPickerCarouselSwiping(
-                            if (isStart) 1f else 0f,
-                            previewRatio,
-                        )
+                        ?.onPickerCarouselSwiping(if (isStart) 1f else 0f)
                     scalingUpClockController
                         ?.largeClock
                         ?.animations
-                        ?.onPickerCarouselSwiping(
-                            if (isStart) 0f else 1f,
-                            previewRatio,
-                        )
+                        ?.onPickerCarouselSwiping(if (isStart) 0f else 1f)
                     showingCardView?.alpha = if (isStart) 0f else 1f
                     hidingCardView?.alpha = if (isStart) 1f else 0f
                 }
@@ -171,8 +157,7 @@
     class ClockCarouselAdapter(
         val clockIds: List<String>,
         val onGetClockController: (clockId: String) -> ClockController,
-        private val onClockSelected: (clockId: String) -> Unit,
-        private val previewRatio: Float,
+        private val onClockSelected: (clockId: String) -> Unit
     ) : Carousel.Adapter {
 
         override fun count(): Int {
@@ -188,9 +173,8 @@
                 getClockScaleViewId(viewRoot.id)?.let { viewRoot.findViewById(it) as? View }
                     ?: return
             val clockHostView =
-                getClockHostViewId(viewRoot.id)?.let { viewRoot.findViewById(it) as? ViewGroup }
+                getClockHostViewId(viewRoot.id)?.let { viewRoot.findViewById(it) as? ClockHostView }
                     ?: return
-
             clockHostView.removeAllViews()
             val clockView = onGetClockController(clockIds[index]).largeClock.view
             // The clock view might still be attached to an existing parent. Detach before adding to
@@ -205,7 +189,7 @@
                 onGetClockController(clockIds[index])
                     .largeClock
                     .animations
-                    .onPickerCarouselSwiping(0F, previewRatio)
+                    .onPickerCarouselSwiping(0F)
             } else {
                 cardView.alpha = 0f
                 clockScaleView.scaleX = 1f
@@ -213,7 +197,7 @@
                 onGetClockController(clockIds[index])
                     .largeClock
                     .animations
-                    .onPickerCarouselSwiping(1F, previewRatio)
+                    .onPickerCarouselSwiping(1F)
             }
         }
 
diff --git a/src/com/android/customization/picker/clock/ui/view/ClockHostView.kt b/src/com/android/customization/picker/clock/ui/view/ClockHostView.kt
new file mode 100644
index 0000000..512fcd1
--- /dev/null
+++ b/src/com/android/customization/picker/clock/ui/view/ClockHostView.kt
@@ -0,0 +1,55 @@
+package com.android.customization.picker.clock.ui.view
+
+import android.content.Context
+import android.util.AttributeSet
+import android.view.View
+import android.view.View.MeasureSpec.EXACTLY
+import android.widget.FrameLayout
+import com.android.wallpaper.util.ScreenSizeCalculator
+
+/**
+ * The parent view for each clock view in picker carousel This view will give a container with the
+ * same size of lockscreen to layout clock and scale down it to the size in picker carousel
+ * according to ratio of preview to LS
+ */
+class ClockHostView(
+    context: Context,
+    attrs: AttributeSet?,
+) : FrameLayout(context, attrs) {
+    private var previewRatio: Float = 1F
+        set(value) {
+            if (field != value) {
+                field = value
+                scaleX = previewRatio
+                scaleY = previewRatio
+                invalidate()
+            }
+        }
+
+    override fun onMeasure(widthMeasureSpec: Int, heightMeasureSpec: Int) {
+        super.onMeasure(widthMeasureSpec, heightMeasureSpec)
+        val screenSize = ScreenSizeCalculator.getInstance().getScreenSize(display)
+        previewRatio = measuredWidth / screenSize.x.toFloat()
+    }
+
+    /**
+     * In clock picker, we want to clock layout and render at lockscreen size and scale down so that
+     * the preview in clock carousel will be the same as lockscreen
+     */
+    override fun measureChildWithMargins(
+        child: View?,
+        parentWidthMeasureSpec: Int,
+        widthUsed: Int,
+        parentHeightMeasureSpec: Int,
+        heightUsed: Int
+    ) {
+        val screenSize = ScreenSizeCalculator.getInstance().getScreenSize(display)
+        super.measureChildWithMargins(
+            child,
+            MeasureSpec.makeMeasureSpec(screenSize.x, EXACTLY),
+            widthUsed,
+            MeasureSpec.makeMeasureSpec(screenSize.y, EXACTLY),
+            heightUsed
+        )
+    }
+}
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 782d69e..d085b7b 100644
--- a/src/com/android/customization/picker/clock/ui/view/ClockViewFactory.kt
+++ b/src/com/android/customization/picker/clock/ui/view/ClockViewFactory.kt
@@ -16,6 +16,7 @@
 package com.android.customization.picker.clock.ui.view
 
 import android.app.Activity
+import android.graphics.Rect
 import android.util.TypedValue
 import android.view.View
 import androidx.annotation.ColorInt
@@ -35,13 +36,6 @@
     private val timeTickListeners: ConcurrentHashMap<Int, TimeTicker> = ConcurrentHashMap()
     private val clockControllers: HashMap<String, ClockController> = HashMap()
 
-    fun getRatio(): Float {
-        val screenSizeCalculator = ScreenSizeCalculator.getInstance()
-        val screenSize = screenSizeCalculator.getScreenSize(activity.windowManager.defaultDisplay)
-        return activity.resources.getDimensionPixelSize(R.dimen.screen_preview_width).toFloat() /
-            screenSize.x.toFloat()
-    }
-
     fun getController(clockId: String): ClockController {
         return clockControllers[clockId] ?: initClockController(clockId)
     }
@@ -98,12 +92,11 @@
         activity.theme.resolveAttribute(android.R.attr.isLightTheme, isLightTheme, true)
         val isRegionDark = isLightTheme.data == 0
         controller.largeClock.events.onRegionDarknessChanged(isRegionDark)
-
         // Configure font size
         controller.largeClock.events.onFontSettingChanged(
-            activity.resources.getDimensionPixelSize(R.dimen.large_clock_text_size).toFloat() *
-                getRatio()
+            activity.resources.getDimensionPixelSize(R.dimen.large_clock_text_size).toFloat()
         )
+        controller.largeClock.events.onTargetRegionChanged(getLargeClockRegion())
         // Use placeholder for weather clock preview in picker
         controller.events.onWeatherDataChanged(
             WeatherData(
@@ -117,6 +110,22 @@
         return controller
     }
 
+    /**
+     * Simulate the function of getLargeClockRegion in KeyguardClockSwitch so that we can get a
+     * proper region corresponding to lock screen in picker and for onTargetRegionChanged to scale
+     * and position the clock view
+     */
+    fun getLargeClockRegion(): Rect {
+        val screenSizeCalculator = ScreenSizeCalculator.getInstance()
+        val screenSize = screenSizeCalculator.getScreenSize(activity.windowManager.defaultDisplay)
+        val largeClockTopMargin =
+            activity.resources.getDimensionPixelSize(R.dimen.keyguard_large_clock_top_margin)
+        val targetHeight =
+            activity.resources.getDimensionPixelSize(R.dimen.large_clock_text_size) * 2
+        val top = (screenSize.y / 2 - targetHeight / 2 + largeClockTopMargin / 2)
+        return Rect(0, top, screenSize.x, (top + targetHeight))
+    }
+
     companion object {
         val DESCRIPTION_PLACEHODLER = ""
         val TEMPERATURE_PLACEHOLDER = 58
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 5941e3d..4bd5f1c 100644
--- a/src/com/android/customization/picker/preview/ui/section/PreviewWithClockCarouselSectionController.kt
+++ b/src/com/android/customization/picker/preview/ui/section/PreviewWithClockCarouselSectionController.kt
@@ -18,7 +18,9 @@
 package com.android.customization.picker.preview.ui.section
 
 import android.content.Context
+import android.graphics.Rect
 import android.os.Bundle
+import android.view.TouchDelegate
 import android.view.View
 import android.view.View.OnAttachStateChangeListener
 import android.view.ViewGroup
@@ -98,6 +100,20 @@
             clockColorAndSizeButton?.setOnClickListener {
                 navigationController.navigateTo(ClockSettingsFragment())
             }
+            // clockColorAndSizeButton's touch target has to be increased programmatically
+            // rather than with padding because this button only appears in the lock screen tab.
+            view.post {
+                val rect = Rect()
+                clockColorAndSizeButton?.getHitRect(rect)
+                val padding =
+                    context
+                        .getResources()
+                        .getDimensionPixelSize(R.dimen.screen_preview_section_vertical_space)
+                rect.top -= padding
+                rect.bottom += padding
+                val touchDelegate = TouchDelegate(rect, clockColorAndSizeButton)
+                view.setTouchDelegate(touchDelegate)
+            }
 
             val carouselViewStub: ViewStub = view.requireViewById(R.id.clock_carousel_view_stub)
             carouselViewStub.layoutResource = R.layout.clock_carousel_view