Merge "Use the Android RadioButton for clock size options" into main
diff --git a/res/layout/clock_size_radio_button_group.xml b/res/layout/clock_size_radio_button_group.xml
deleted file mode 100644
index 4e7d1b4..0000000
--- a/res/layout/clock_size_radio_button_group.xml
+++ /dev/null
@@ -1,100 +0,0 @@
-<?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.
-  ~
-  -->
-<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_width="match_parent"
-    android:layout_height="wrap_content"
-    android:orientation="vertical">
-
-    <LinearLayout
-        android:id="@+id/button_container_dynamic"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:layout_marginBottom="8dp"
-        android:orientation="horizontal">
-
-        <RadioButton
-            android:id="@+id/radio_button_dynamic"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_gravity="center_vertical"
-            android:layout_marginEnd="8dp"
-            android:clickable="false"
-            android:importantForAccessibility="no"/>
-
-        <LinearLayout
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:orientation="vertical">
-
-            <TextView
-                style="@style/SectionTitleTextStyle"
-                android:layout_width="wrap_content"
-                android:layout_height="wrap_content"
-                android:ellipsize="end"
-                android:singleLine="true"
-                android:text="@string/clock_size_dynamic" />
-
-            <TextView
-                style="@style/SectionSubtitleTextStyle"
-                android:layout_width="wrap_content"
-                android:layout_height="wrap_content"
-                android:maxLines="2"
-                android:ellipsize="end"
-                android:singleLine="false"
-                android:text="@string/clock_size_dynamic_description" />
-        </LinearLayout>
-    </LinearLayout>
-
-    <LinearLayout
-        android:id="@+id/button_container_small"
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:minHeight="@dimen/touch_target_min_height"
-        android:orientation="horizontal">
-
-        <RadioButton
-            android:id="@+id/radio_button_large"
-            android:layout_width="wrap_content"
-            android:layout_height="wrap_content"
-            android:layout_gravity="center_vertical"
-            android:layout_marginEnd="8dp"
-            android:clickable="false"
-            android:importantForAccessibility="no"/>
-
-        <LinearLayout
-            android:layout_width="match_parent"
-            android:layout_height="wrap_content"
-            android:orientation="vertical">
-            <TextView
-                style="@style/SectionTitleTextStyle"
-                android:layout_width="wrap_content"
-                android:layout_height="wrap_content"
-                android:ellipsize="end"
-                android:singleLine="true"
-                android:text="@string/clock_size_small" />
-
-            <TextView
-                style="@style/SectionSubtitleTextStyle"
-                android:layout_width="wrap_content"
-                android:layout_height="wrap_content"
-                android:maxLines="2"
-                android:ellipsize="end"
-                android:singleLine="false"
-                android:text="@string/clock_size_small_description" />
-        </LinearLayout>
-    </LinearLayout>
-</LinearLayout>
\ No newline at end of file
diff --git a/res/layout/fragment_clock_settings.xml b/res/layout/fragment_clock_settings.xml
index 5736265..f25164f 100644
--- a/res/layout/fragment_clock_settings.xml
+++ b/res/layout/fragment_clock_settings.xml
@@ -14,7 +14,6 @@
   ~ limitations under the License.
   ~
   -->
-
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="match_parent"
     android:layout_height="match_parent"
@@ -159,11 +158,30 @@
                     android:splitTrack="false" />
             </LinearLayout>
 
-            <com.android.customization.picker.clock.ui.view.ClockSizeRadioButtonGroup
+            <RadioGroup
                 android:id="@+id/clock_size_radio_button_group"
                 android:layout_width="match_parent"
                 android:layout_height="wrap_content"
-                android:paddingHorizontal="16dp" />
+                android:orientation="vertical"
+                android:layout_marginHorizontal="16dp">
+                <!-- The radio button text is set when binding the view -->
+                <RadioButton android:id="@+id/radio_dynamic"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:paddingStart="8dp"
+                    android:maxLines="3"
+                    android:ellipsize="end"
+                    android:singleLine="false"
+                    android:layout_marginBottom="8dp"/>
+                <!-- The radio button text is set when binding the view -->
+                <RadioButton android:id="@+id/radio_small"
+                    android:layout_width="wrap_content"
+                    android:layout_height="wrap_content"
+                    android:paddingStart="8dp"
+                    android:maxLines="3"
+                    android:ellipsize="end"
+                    android:singleLine="false" />
+            </RadioGroup>
         </FrameLayout>
     </LinearLayout>
 </LinearLayout>
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 6e745d5..0f39c54 100644
--- a/src/com/android/customization/picker/clock/ui/binder/ClockSettingsBinder.kt
+++ b/src/com/android/customization/picker/clock/ui/binder/ClockSettingsBinder.kt
@@ -15,11 +15,18 @@
  */
 package com.android.customization.picker.clock.ui.binder
 
+import android.content.Context
 import android.content.res.Configuration
+import android.text.Spannable
+import android.text.SpannableString
+import android.text.style.TextAppearanceSpan
 import android.view.LayoutInflater
 import android.view.View
 import android.view.ViewGroup
 import android.widget.LinearLayout
+import android.widget.RadioButton
+import android.widget.RadioGroup
+import android.widget.RadioGroup.OnCheckedChangeListener
 import android.widget.SeekBar
 import androidx.core.view.doOnPreDraw
 import androidx.core.view.isInvisible
@@ -35,7 +42,6 @@
 import com.android.customization.picker.clock.ui.adapter.ClockSettingsTabAdapter
 import com.android.customization.picker.clock.ui.view.ClockCarouselView
 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
 import com.android.customization.picker.color.ui.binder.ColorOptionIconBinder
@@ -83,14 +89,27 @@
             }
         )
 
-        val sizeOptions =
-            view.requireViewById<ClockSizeRadioButtonGroup>(R.id.clock_size_radio_button_group)
-        sizeOptions.onRadioButtonClickListener =
-            object : ClockSizeRadioButtonGroup.OnRadioButtonClickListener {
-                override fun onClick(size: ClockSize) {
-                    viewModel.setClockSize(size)
-                }
+        val onCheckedChangeListener = OnCheckedChangeListener { _, id ->
+            when (id) {
+                R.id.radio_dynamic -> viewModel.setClockSize(ClockSize.DYNAMIC)
+                R.id.radio_small -> viewModel.setClockSize(ClockSize.SMALL)
             }
+        }
+        val clockSizeRadioGroup =
+            view.requireViewById<RadioGroup>(R.id.clock_size_radio_button_group)
+        clockSizeRadioGroup.setOnCheckedChangeListener(onCheckedChangeListener)
+        view.requireViewById<RadioButton>(R.id.radio_dynamic).text =
+            getRadioText(
+                view.context.applicationContext,
+                view.resources.getString(R.string.clock_size_dynamic),
+                view.resources.getString(R.string.clock_size_dynamic_description)
+            )
+        view.requireViewById<RadioButton>(R.id.radio_small).text =
+            getRadioText(
+                view.context.applicationContext,
+                view.resources.getString(R.string.clock_size_small),
+                view.resources.getString(R.string.clock_size_small_description)
+            )
 
         val colorOptionContainer = view.requireViewById<View>(R.id.color_picker_container)
         lifecycleOwner.lifecycleScope.launch {
@@ -110,11 +129,11 @@
                         when (tab) {
                             ClockSettingsViewModel.Tab.COLOR -> {
                                 colorOptionContainer.isVisible = true
-                                sizeOptions.isInvisible = true
+                                clockSizeRadioGroup.isInvisible = true
                             }
                             ClockSettingsViewModel.Tab.SIZE -> {
                                 colorOptionContainer.isInvisible = true
-                                sizeOptions.isVisible = true
+                                clockSizeRadioGroup.isVisible = true
                             }
                         }
                     }
@@ -189,16 +208,28 @@
                             clockHostView.addView(clockView)
                             when (size) {
                                 ClockSize.DYNAMIC -> {
-                                    sizeOptions.radioButtonDynamic.isChecked = true
-                                    sizeOptions.radioButtonSmall.isChecked = false
+                                    // When clock size data flow emits clock size signal, we want
+                                    // to update the view without triggering on checked change,
+                                    // which is supposed to be triggered by user interaction only.
+                                    clockSizeRadioGroup.setOnCheckedChangeListener(null)
+                                    clockSizeRadioGroup.check(R.id.radio_dynamic)
+                                    clockSizeRadioGroup.setOnCheckedChangeListener(
+                                        onCheckedChangeListener
+                                    )
                                     clockHostView.doOnPreDraw {
                                         it.pivotX = it.width / 2F
                                         it.pivotY = it.height / 2F
                                     }
                                 }
                                 ClockSize.SMALL -> {
-                                    sizeOptions.radioButtonDynamic.isChecked = false
-                                    sizeOptions.radioButtonSmall.isChecked = true
+                                    // When clock size data flow emits clock size signal, we want
+                                    // to update the view without triggering on checked change,
+                                    // which is supposed to be triggered by user interaction only.
+                                    clockSizeRadioGroup.setOnCheckedChangeListener(null)
+                                    clockSizeRadioGroup.check(R.id.radio_small)
+                                    clockSizeRadioGroup.setOnCheckedChangeListener(
+                                        onCheckedChangeListener
+                                    )
                                     clockHostView.doOnPreDraw {
                                         it.pivotX = ClockCarouselView.getCenteredHostViewPivotX(it)
                                         it.pivotY = 0F
@@ -238,4 +269,25 @@
             }
         )
     }
+
+    private fun getRadioText(
+        context: Context,
+        title: String,
+        description: String
+    ): SpannableString {
+        val text = SpannableString(title + "\n" + description)
+        text.setSpan(
+            TextAppearanceSpan(context, R.style.SectionTitleTextStyle),
+            0,
+            title.length,
+            Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
+        )
+        text.setSpan(
+            TextAppearanceSpan(context, R.style.SectionSubtitleTextStyle),
+            title.length + 1,
+            title.length + 1 + description.length,
+            Spannable.SPAN_EXCLUSIVE_EXCLUSIVE
+        )
+        return text
+    }
 }
diff --git a/src/com/android/customization/picker/clock/ui/view/ClockSizeRadioButtonGroup.kt b/src/com/android/customization/picker/clock/ui/view/ClockSizeRadioButtonGroup.kt
deleted file mode 100644
index 909491a..0000000
--- a/src/com/android/customization/picker/clock/ui/view/ClockSizeRadioButtonGroup.kt
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * 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.util.AttributeSet
-import android.view.LayoutInflater
-import android.view.View
-import android.widget.FrameLayout
-import android.widget.RadioButton
-import com.android.customization.picker.clock.shared.ClockSize
-import com.android.wallpaper.R
-
-/** The radio button group to pick the clock size. */
-class ClockSizeRadioButtonGroup(
-    context: Context,
-    attrs: AttributeSet?,
-) : FrameLayout(context, attrs) {
-
-    interface OnRadioButtonClickListener {
-        fun onClick(size: ClockSize)
-    }
-
-    val radioButtonDynamic: RadioButton
-    val radioButtonSmall: RadioButton
-    var onRadioButtonClickListener: OnRadioButtonClickListener? = null
-
-    init {
-        LayoutInflater.from(context).inflate(R.layout.clock_size_radio_button_group, this, true)
-        radioButtonDynamic = requireViewById(R.id.radio_button_dynamic)
-        val buttonDynamic = requireViewById<View>(R.id.button_container_dynamic)
-        buttonDynamic.setOnClickListener { onRadioButtonClickListener?.onClick(ClockSize.DYNAMIC) }
-        radioButtonSmall = requireViewById(R.id.radio_button_large)
-        val buttonLarge = requireViewById<View>(R.id.button_container_small)
-        buttonLarge.setOnClickListener { onRadioButtonClickListener?.onClick(ClockSize.SMALL) }
-    }
-}