Merge "Import translations. DO NOT MERGE ANYWHERE" into tm-qpr-dev
diff --git a/res/layout/clock_size_radio_button_group.xml b/res/layout/clock_size_radio_button_group.xml
index d520756..4264007 100644
--- a/res/layout/clock_size_radio_button_group.xml
+++ b/res/layout/clock_size_radio_button_group.xml
@@ -54,7 +54,7 @@
     </LinearLayout>
 
     <LinearLayout
-        android:id="@+id/button_container_large"
+        android:id="@+id/button_container_small"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
         android:orientation="horizontal">
@@ -72,6 +72,6 @@
             android:layout_width="wrap_content"
             android:layout_height="wrap_content"
             android:layout_gravity="center_vertical"
-            android:text="@string/clock_size_large" />
+            android:text="@string/clock_size_small" />
     </LinearLayout>
 </LinearLayout>
\ No newline at end of file
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 6eeea9c..c1bdc54 100755
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -33,7 +33,7 @@
     <!-- The content description of clock entry. [CHAR LIMIT=NONE] -->
     <string name="clock_picker_entry_content_description">Change a custom clock</string>
 
-    <!-- Title of a section of the customization picker where the user can configure Clock face. [CHAR LIMIT=15] -->
+    <!-- Title of a section of the customization picker where the user can configure Clock face. [CHAR LIMIT=19] -->
     <string name="clock_settings_title">Clock Settings</string>
 
     <!-- Title of a tab to change the clock color. [CHAR LIMIT=15] -->
@@ -51,6 +51,9 @@
     <!-- Title of a radio button to apply clock size large. [CHAR LIMIT=15] -->
     <string name="clock_size_large">Large</string>
 
+    <!-- Title of a radio button to apply clock size small. [CHAR LIMIT=15] -->
+    <string name="clock_size_small">Small</string>
+
     <!-- Title of a section of the customization picker where the user can select a Grid size for
         the home screen. [CHAR LIMIT=15] -->
     <string name="grid_title">App grid</string>
diff --git a/src/com/android/customization/module/ThemePickerInjector.kt b/src/com/android/customization/module/ThemePickerInjector.kt
index aed5a8a..4bef78d 100644
--- a/src/com/android/customization/module/ThemePickerInjector.kt
+++ b/src/com/android/customization/module/ThemePickerInjector.kt
@@ -303,10 +303,11 @@
         return clockPickerInteractor
             ?: ClockPickerInteractor(
                     ClockPickerRepositoryImpl(
+                        secureSettingsRepository = getSecureSettingsRepository(context),
                         registry = clockRegistry,
                         scope = GlobalScope,
                         backgroundDispatcher = Dispatchers.IO,
-                    )
+                    ),
                 )
                 .also { clockPickerInteractor = it }
     }
diff --git a/src/com/android/customization/picker/HorizontalTouchMovementAwareNestedScrollView.kt b/src/com/android/customization/picker/HorizontalTouchMovementAwareNestedScrollView.kt
new file mode 100644
index 0000000..06cf753
--- /dev/null
+++ b/src/com/android/customization/picker/HorizontalTouchMovementAwareNestedScrollView.kt
@@ -0,0 +1,64 @@
+/*
+ * 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
+
+import android.content.Context
+import android.util.AttributeSet
+import android.view.MotionEvent
+import android.view.ViewConfiguration
+import androidx.core.widget.NestedScrollView
+import kotlin.math.abs
+
+/**
+ * This nested scroll view will detect horizontal touch movements and stop vertical scrolls when a
+ * horizontal touch movement is detected.
+ */
+class HorizontalTouchMovementAwareNestedScrollView(context: Context, attrs: AttributeSet?) :
+    NestedScrollView(context, attrs) {
+
+    private var startXPosition = 0f
+    private var startYPosition = 0f
+    private var isHorizontalTouchMovement = false
+
+    override fun onInterceptTouchEvent(event: MotionEvent): Boolean {
+        when (event.action) {
+            MotionEvent.ACTION_DOWN -> {
+                startXPosition = event.x
+                startYPosition = event.y
+                isHorizontalTouchMovement = false
+            }
+            MotionEvent.ACTION_MOVE -> {
+                val xMoveDistance = abs(event.x - startXPosition)
+                val yMoveDistance = abs(event.y - startYPosition)
+                if (
+                    !isHorizontalTouchMovement &&
+                        xMoveDistance > yMoveDistance &&
+                        xMoveDistance > ViewConfiguration.get(context).scaledTouchSlop
+                ) {
+                    isHorizontalTouchMovement = true
+                }
+            }
+            else -> {}
+        }
+        return if (isHorizontalTouchMovement) {
+            // We only want to intercept the touch event when the touch moves more vertically than
+            // horizontally. So we return false.
+            false
+        } else {
+            super.onInterceptTouchEvent(event)
+        }
+    }
+}
diff --git a/src/com/android/customization/picker/clock/data/repository/ClockPickerRepository.kt b/src/com/android/customization/picker/clock/data/repository/ClockPickerRepository.kt
index 1904197..690b649 100644
--- a/src/com/android/customization/picker/clock/data/repository/ClockPickerRepository.kt
+++ b/src/com/android/customization/picker/clock/data/repository/ClockPickerRepository.kt
@@ -35,5 +35,5 @@
 
     fun setClockColor(color: Int?)
 
-    fun setClockSize(size: ClockSize)
+    suspend fun setClockSize(size: ClockSize)
 }
diff --git a/src/com/android/customization/picker/clock/data/repository/ClockPickerRepositoryImpl.kt b/src/com/android/customization/picker/clock/data/repository/ClockPickerRepositoryImpl.kt
index 9e140aa..6c845f9 100644
--- a/src/com/android/customization/picker/clock/data/repository/ClockPickerRepositoryImpl.kt
+++ b/src/com/android/customization/picker/clock/data/repository/ClockPickerRepositoryImpl.kt
@@ -16,24 +16,29 @@
  */
 package com.android.customization.picker.clock.data.repository
 
+import android.provider.Settings
 import android.util.Log
 import com.android.customization.picker.clock.shared.ClockSize
 import com.android.customization.picker.clock.shared.model.ClockMetadataModel
 import com.android.systemui.plugins.ClockMetadata
 import com.android.systemui.shared.clocks.ClockRegistry
+import com.android.wallpaper.settings.data.repository.SecureSettingsRepository
 import kotlinx.coroutines.CoroutineDispatcher
 import kotlinx.coroutines.CoroutineScope
 import kotlinx.coroutines.channels.awaitClose
 import kotlinx.coroutines.flow.Flow
-import kotlinx.coroutines.flow.MutableStateFlow
-import kotlinx.coroutines.flow.asStateFlow
+import kotlinx.coroutines.flow.SharedFlow
+import kotlinx.coroutines.flow.SharingStarted
 import kotlinx.coroutines.flow.callbackFlow
+import kotlinx.coroutines.flow.map
 import kotlinx.coroutines.flow.mapNotNull
+import kotlinx.coroutines.flow.shareIn
 import kotlinx.coroutines.launch
 import kotlinx.coroutines.withContext
 
 /** Implementation of [ClockPickerRepository], using [ClockRegistry]. */
 class ClockPickerRepositoryImpl(
+    private val secureSettingsRepository: SecureSettingsRepository,
     private val registry: ClockRegistry,
     private val scope: CoroutineScope,
     private val backgroundDispatcher: CoroutineDispatcher,
@@ -66,7 +71,12 @@
                     trySend(model)
                 }
 
-                val listener = ClockRegistry.ClockChangeListener { scope.launch { send() } }
+                val listener =
+                    object : ClockRegistry.ClockChangeListener {
+                        override fun onCurrentClockChanged() {
+                            scope.launch { send() }
+                        }
+                    }
                 registry.registerClockChangeListener(listener)
                 send()
                 awaitClose { registry.unregisterClockChangeListener(listener) }
@@ -81,12 +91,26 @@
         registry.seedColor = color
     }
 
-    // TODO(b/262924055): Use the shared system UI component to query the clock size
-    private val _selectedClockSize = MutableStateFlow(ClockSize.DYNAMIC)
-    override val selectedClockSize: Flow<ClockSize> = _selectedClockSize.asStateFlow()
+    override val selectedClockSize: SharedFlow<ClockSize> =
+        secureSettingsRepository
+            .intSetting(
+                name = Settings.Secure.LOCKSCREEN_USE_DOUBLE_LINE_CLOCK,
+            )
+            .map { setting -> setting == 1 }
+            .map { isDynamic -> if (isDynamic) ClockSize.DYNAMIC else ClockSize.SMALL }
+            .shareIn(
+                scope = scope,
+                started = SharingStarted.WhileSubscribed(),
+                replay = 1,
+            )
 
-    override fun setClockSize(size: ClockSize) {
-        _selectedClockSize.value = size
+    override suspend fun setClockSize(size: ClockSize) {
+        withContext(backgroundDispatcher) {
+            secureSettingsRepository.set(
+                name = Settings.Secure.LOCKSCREEN_USE_DOUBLE_LINE_CLOCK,
+                value = if (size == ClockSize.DYNAMIC) 1 else 0,
+            )
+        }
     }
 
     private fun ClockMetadata.toModel(color: Int?): ClockMetadataModel {
diff --git a/src/com/android/customization/picker/clock/domain/interactor/ClockPickerInteractor.kt b/src/com/android/customization/picker/clock/domain/interactor/ClockPickerInteractor.kt
index 846ea21..c12778b 100644
--- a/src/com/android/customization/picker/clock/domain/interactor/ClockPickerInteractor.kt
+++ b/src/com/android/customization/picker/clock/domain/interactor/ClockPickerInteractor.kt
@@ -44,7 +44,7 @@
         repository.setClockColor(color)
     }
 
-    fun setClockSize(size: ClockSize) {
+    suspend fun setClockSize(size: ClockSize) {
         repository.setClockSize(size)
     }
 }
diff --git a/src/com/android/customization/picker/clock/shared/ClockSize.kt b/src/com/android/customization/picker/clock/shared/ClockSize.kt
index 91c5cd4..279ee54 100644
--- a/src/com/android/customization/picker/clock/shared/ClockSize.kt
+++ b/src/com/android/customization/picker/clock/shared/ClockSize.kt
@@ -18,5 +18,5 @@
 
 enum class ClockSize {
     DYNAMIC,
-    LARGE,
+    SMALL,
 }
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 e785ebd..ecbb901 100644
--- a/src/com/android/customization/picker/clock/ui/binder/ClockSettingsBinder.kt
+++ b/src/com/android/customization/picker/clock/ui/binder/ClockSettingsBinder.kt
@@ -108,11 +108,11 @@
                         when (size) {
                             ClockSize.DYNAMIC -> {
                                 sizeOptions.radioButtonDynamic.isChecked = true
-                                sizeOptions.radioButtonLarge.isChecked = false
+                                sizeOptions.radioButtonSmall.isChecked = false
                             }
-                            ClockSize.LARGE -> {
+                            ClockSize.SMALL -> {
                                 sizeOptions.radioButtonDynamic.isChecked = false
-                                sizeOptions.radioButtonLarge.isChecked = true
+                                sizeOptions.radioButtonSmall.isChecked = true
                             }
                         }
                     }
diff --git a/src/com/android/customization/picker/clock/ui/view/ClockSizeRadioButtonGroup.kt b/src/com/android/customization/picker/clock/ui/view/ClockSizeRadioButtonGroup.kt
index fcf8904..909491a 100644
--- a/src/com/android/customization/picker/clock/ui/view/ClockSizeRadioButtonGroup.kt
+++ b/src/com/android/customization/picker/clock/ui/view/ClockSizeRadioButtonGroup.kt
@@ -35,7 +35,7 @@
     }
 
     val radioButtonDynamic: RadioButton
-    val radioButtonLarge: RadioButton
+    val radioButtonSmall: RadioButton
     var onRadioButtonClickListener: OnRadioButtonClickListener? = null
 
     init {
@@ -43,8 +43,8 @@
         radioButtonDynamic = requireViewById(R.id.radio_button_dynamic)
         val buttonDynamic = requireViewById<View>(R.id.button_container_dynamic)
         buttonDynamic.setOnClickListener { onRadioButtonClickListener?.onClick(ClockSize.DYNAMIC) }
-        radioButtonLarge = requireViewById(R.id.radio_button_large)
-        val buttonLarge = requireViewById<View>(R.id.button_container_large)
-        buttonLarge.setOnClickListener { onRadioButtonClickListener?.onClick(ClockSize.LARGE) }
+        radioButtonSmall = requireViewById(R.id.radio_button_large)
+        val buttonLarge = requireViewById<View>(R.id.button_container_small)
+        buttonLarge.setOnClickListener { onRadioButtonClickListener?.onClick(ClockSize.SMALL) }
     }
 }
diff --git a/src/com/android/customization/picker/clock/ui/viewmodel/ClockSettingsViewModel.kt b/src/com/android/customization/picker/clock/ui/viewmodel/ClockSettingsViewModel.kt
index 54aaec3..1ffb7b8 100644
--- a/src/com/android/customization/picker/clock/ui/viewmodel/ClockSettingsViewModel.kt
+++ b/src/com/android/customization/picker/clock/ui/viewmodel/ClockSettingsViewModel.kt
@@ -38,6 +38,7 @@
 import kotlinx.coroutines.flow.mapLatest
 import kotlinx.coroutines.flow.shareIn
 import kotlinx.coroutines.flow.stateIn
+import kotlinx.coroutines.launch
 
 /** View model for the clock settings screen. */
 class ClockSettingsViewModel
@@ -189,7 +190,7 @@
     val selectedClockSize: Flow<ClockSize> = interactor.selectedClockSize
 
     fun setClockSize(size: ClockSize) {
-        interactor.setClockSize(size)
+        viewModelScope.launch { interactor.setClockSize(size) }
     }
 
     private val _selectedTabPosition = MutableStateFlow(Tab.COLOR)
diff --git a/tests/src/com/android/customization/picker/clock/data/repository/FakeClockPickerRepository.kt b/tests/src/com/android/customization/picker/clock/data/repository/FakeClockPickerRepository.kt
index c201527..1614c61 100644
--- a/tests/src/com/android/customization/picker/clock/data/repository/FakeClockPickerRepository.kt
+++ b/tests/src/com/android/customization/picker/clock/data/repository/FakeClockPickerRepository.kt
@@ -35,7 +35,7 @@
             ClockMetadataModel(selectedClock.clockId, selectedClock.name, clockColor)
         }
 
-    private val _selectedClockSize = MutableStateFlow(ClockSize.LARGE)
+    private val _selectedClockSize = MutableStateFlow(ClockSize.SMALL)
     override val selectedClockSize: Flow<ClockSize> = _selectedClockSize.asStateFlow()
 
     override fun setSelectedClock(clockId: String) {
@@ -46,7 +46,7 @@
         _clockColor.value = color
     }
 
-    override fun setClockSize(size: ClockSize) {
+    override suspend fun setClockSize(size: ClockSize) {
         _selectedClockSize.value = size
     }
 
diff --git a/tests/src/com/android/customization/picker/clock/domain/interactor/ClockPickerInteractorTest.kt b/tests/src/com/android/customization/picker/clock/domain/interactor/ClockPickerInteractorTest.kt
index a6ad6de..883d68b 100644
--- a/tests/src/com/android/customization/picker/clock/domain/interactor/ClockPickerInteractorTest.kt
+++ b/tests/src/com/android/customization/picker/clock/domain/interactor/ClockPickerInteractorTest.kt
@@ -42,7 +42,7 @@
         underTest.setClockSize(ClockSize.DYNAMIC)
         Truth.assertThat(observedClockSize()).isEqualTo(ClockSize.DYNAMIC)
 
-        underTest.setClockSize(ClockSize.LARGE)
-        Truth.assertThat(observedClockSize()).isEqualTo(ClockSize.LARGE)
+        underTest.setClockSize(ClockSize.SMALL)
+        Truth.assertThat(observedClockSize()).isEqualTo(ClockSize.SMALL)
     }
 }
diff --git a/tests/src/com/android/customization/picker/clock/ui/viewmodel/ClockSettingsTabViewModelTest.kt b/tests/src/com/android/customization/picker/clock/ui/viewmodel/ClockSettingsTabViewModelTest.kt
index 72f5055..215e178 100644
--- a/tests/src/com/android/customization/picker/clock/ui/viewmodel/ClockSettingsTabViewModelTest.kt
+++ b/tests/src/com/android/customization/picker/clock/ui/viewmodel/ClockSettingsTabViewModelTest.kt
@@ -97,8 +97,8 @@
         underTest.setClockSize(ClockSize.DYNAMIC)
         assertThat(observedClockSize()).isEqualTo(ClockSize.DYNAMIC)
 
-        underTest.setClockSize(ClockSize.LARGE)
-        assertThat(observedClockSize()).isEqualTo(ClockSize.LARGE)
+        underTest.setClockSize(ClockSize.SMALL)
+        assertThat(observedClockSize()).isEqualTo(ClockSize.SMALL)
     }
 
     @Test