Merge "Color Picker Section (1/3)" into tm-qpr-dev am: 13a16340b4

Original change: https://googleplex-android-review.googlesource.com/c/platform/packages/apps/ThemePicker/+/20806327

Change-Id: I5c1394e5994dfe9233b9b5fb590bd678082a4831
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
diff --git a/res/color/keyguard_quick_affordance_slot_tab_text_color.xml b/res/color/picker_fragment_tab_text_color.xml
similarity index 100%
rename from res/color/keyguard_quick_affordance_slot_tab_text_color.xml
rename to res/color/picker_fragment_tab_text_color.xml
diff --git a/res/drawable/color_option_section_selected.xml b/res/drawable/color_option_section_selected.xml
new file mode 100644
index 0000000..13451a5
--- /dev/null
+++ b/res/drawable/color_option_section_selected.xml
@@ -0,0 +1,43 @@
+<?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.
+-->
+<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
+    <item
+        android:height="@dimen/component_color_selected_small_diameter_default"
+        android:width="@dimen/component_color_selected_small_diameter_default"
+        android:gravity="center">
+        <shape
+            android:shape="ring"
+            android:innerRadius="@dimen/component_color_overflow_small_radius_default"
+            android:thickness="2dp"
+            android:useLevel="false">
+            <solid android:color="@color/text_color_primary"/>
+        </shape>
+    </item>
+    <item
+        android:height="@dimen/component_color_selected_small_diameter_default"
+        android:width="@dimen/component_color_selected_small_diameter_default"
+        android:gravity="center">
+        <shape
+            android:shape="ring"
+            android:innerRadius="@dimen/component_color_overflow_small_radius_default"
+            android:thickness="-3dp"
+            android:useLevel="false">
+            <solid android:color="@color/color_surface"/>
+        </shape>
+    </item>
+</layer-list>
\ No newline at end of file
diff --git a/res/drawable/color_overflow.xml b/res/drawable/color_overflow.xml
new file mode 100644
index 0000000..90c2684
--- /dev/null
+++ b/res/drawable/color_overflow.xml
@@ -0,0 +1,34 @@
+<?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.
+-->
+<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
+    <item
+        android:height="@dimen/component_color_overflow_small_diameter_default"
+        android:width="@dimen/component_color_overflow_small_diameter_default"
+        android:gravity="center">
+        <shape
+            android:shape="ring"
+            android:innerRadius="@dimen/component_color_overflow_small_radius_default"
+            android:thickness="-1dp"
+            android:useLevel="false">
+            <solid android:color="@color/color_surface_variant"/>
+        </shape>
+    </item>
+    <item
+        android:drawable="@drawable/ic_more_horiz"
+        android:gravity="center"/>
+</layer-list>
\ No newline at end of file
diff --git a/res/drawable/color_section_background.xml b/res/drawable/color_section_background.xml
new file mode 100644
index 0000000..f96824b
--- /dev/null
+++ b/res/drawable/color_section_background.xml
@@ -0,0 +1,29 @@
+<?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.
+  ~
+  -->
+
+<shape
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:shape="rectangle">
+
+    <solid android:color="@color/color_surface" />
+
+    <corners
+        android:topLeftRadius="32dp"
+        android:topRightRadius="32dp"
+        android:bottomLeftRadius="8dp"
+        android:bottomRightRadius="8dp" />
+</shape>
\ No newline at end of file
diff --git a/res/drawable/ic_more_horiz.xml b/res/drawable/ic_more_horiz.xml
new file mode 100644
index 0000000..7c17df2
--- /dev/null
+++ b/res/drawable/ic_more_horiz.xml
@@ -0,0 +1,25 @@
+<!--
+     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.
+-->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+    android:width="24dp"
+    android:height="24dp"
+    android:tint="?attr/colorControlNormal"
+    android:viewportHeight="24"
+    android:viewportWidth="24">
+    <path
+        android:fillColor="@color/text_color_primary"
+        android:pathData="M6,14Q5.175,14 4.588,13.412Q4,12.825 4,12Q4,11.175 4.588,10.587Q5.175,10 6,10Q6.825,10 7.412,10.587Q8,11.175 8,12Q8,12.825 7.412,13.412Q6.825,14 6,14ZM12,14Q11.175,14 10.588,13.412Q10,12.825 10,12Q10,11.175 10.588,10.587Q11.175,10 12,10Q12.825,10 13.413,10.587Q14,11.175 14,12Q14,12.825 13.413,13.412Q12.825,14 12,14ZM18,14Q17.175,14 16.587,13.412Q16,12.825 16,12Q16,11.175 16.587,10.587Q17.175,10 18,10Q18.825,10 19.413,10.587Q20,11.175 20,12Q20,12.825 19.413,13.412Q18.825,14 18,14Z"/>
+</vector>
\ No newline at end of file
diff --git a/res/drawable/keyguard_quick_affordance_picker_background.xml b/res/drawable/picker_fragment_background.xml
similarity index 100%
rename from res/drawable/keyguard_quick_affordance_picker_background.xml
rename to res/drawable/picker_fragment_background.xml
diff --git a/res/drawable/keyguard_quick_affordance_slot_tab_background.xml b/res/drawable/picker_fragment_tab_background.xml
similarity index 100%
rename from res/drawable/keyguard_quick_affordance_slot_tab_background.xml
rename to res/drawable/picker_fragment_tab_background.xml
diff --git a/res/layout/color_option_section.xml b/res/layout/color_option_section.xml
new file mode 100644
index 0000000..d10f8e5
--- /dev/null
+++ b/res/layout/color_option_section.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.
+-->
+<!--
+    This displays the selection outline. It is dynamically sized, constrained remain square and
+    have a maximum size, and be centered within its parent. Defines a layout_weight of 1, and should
+    be used with a Linear Layout parent where weightSum is defined.
+ -->
+<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    android:layout_width="0dp"
+    android:layout_height="wrap_content"
+    android:layout_gravity="center"
+    android:clipChildren="false"
+    android:gravity="center"
+    android:padding="@dimen/option_tile_grid_tile_padding_min"
+    android:layout_weight="1"
+    app:layout_constraintDimensionRatio="1:1"
+    app:layout_constraintWidth_max="@dimen/component_color_chip_small_diameter_default">
+    <!--
+        This is the color wheel itself, constrained to a maximum size and centered. The
+        constraint percentage is sized to leave a padding for the outer selection outline,
+        proportionate to 2dp for a 40dp color wheel
+    -->
+    <androidx.constraintlayout.widget.ConstraintLayout
+        android:id="@+id/option_tile"
+        android:layout_width="0dp"
+        android:layout_height="0dp"
+        android:layout_gravity="center"
+        android:gravity="center"
+        app:layout_constraintBottom_toBottomOf="parent"
+        app:layout_constraintDimensionRatio="1:1"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toTopOf="parent"
+        app:layout_constraintWidth_percent="0.909">
+
+        <ImageView
+            android:id="@+id/color_preview_0"
+            android:layout_width="0dp"
+            android:layout_height="0dp"
+            android:adjustViewBounds="true"
+            android:src="@drawable/color_chip_seed_filled0"
+            app:layout_constraintHeight_percent=".50"
+            app:layout_constraintLeft_toLeftOf="parent"
+            app:layout_constraintTop_toTopOf="parent"
+            app:layout_constraintWidth_percent=".50" />
+
+        <ImageView
+            android:id="@+id/color_preview_1"
+            android:layout_width="0dp"
+            android:layout_height="0dp"
+            android:adjustViewBounds="true"
+            android:src="@drawable/color_chip_seed_filled2"
+            app:layout_constraintHeight_percent=".50"
+            app:layout_constraintLeft_toRightOf="@id/color_preview_0"
+            app:layout_constraintTop_toTopOf="parent"
+            app:layout_constraintWidth_percent=".50" />
+
+        <ImageView
+            android:id="@+id/color_preview_2"
+            android:layout_width="0dp"
+            android:layout_height="0dp"
+            android:adjustViewBounds="true"
+            android:src="@drawable/color_chip_seed_filled1"
+            app:layout_constraintHeight_percent=".50"
+            app:layout_constraintLeft_toLeftOf="parent"
+            app:layout_constraintTop_toBottomOf="@id/color_preview_0"
+            app:layout_constraintWidth_percent=".50" />
+
+        <ImageView
+            android:id="@+id/color_preview_3"
+            android:layout_width="0dp"
+            android:layout_height="0dp"
+            android:adjustViewBounds="true"
+            android:src="@drawable/color_chip_seed_filled3"
+            app:layout_constraintHeight_percent=".50"
+            app:layout_constraintLeft_toRightOf="@id/color_preview_2"
+            app:layout_constraintTop_toBottomOf="@id/color_preview_1"
+            app:layout_constraintWidth_percent=".50" />
+    </androidx.constraintlayout.widget.ConstraintLayout>
+
+    <ImageView
+        android:id="@+id/option_selected"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:adjustViewBounds="true"
+        android:src="@drawable/color_option_section_selected"
+        android:visibility="gone"/>
+</androidx.constraintlayout.widget.ConstraintLayout>
diff --git a/res/layout/color_option_section_overflow.xml b/res/layout/color_option_section_overflow.xml
new file mode 100644
index 0000000..fb25c35
--- /dev/null
+++ b/res/layout/color_option_section_overflow.xml
@@ -0,0 +1,56 @@
+<?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.
+-->
+<!--
+    This is added to keep sizing consistent with the color section options. For the color
+    section options, this displays the selection outline.
+ -->
+<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    android:layout_width="0dp"
+    android:layout_height="wrap_content"
+    android:layout_gravity="center"
+    android:clipChildren="false"
+    android:gravity="center"
+    android:padding="@dimen/option_tile_grid_tile_padding_min"
+    android:layout_weight="1"
+    app:layout_constraintDimensionRatio="1:1"
+    app:layout_constraintWidth_max="@dimen/component_color_chip_small_diameter_default">
+
+    <!--
+        This is added to keep sizing consistent with the color section options. For the color
+         section options, this is the color wheel itself.
+    -->
+    <androidx.constraintlayout.widget.ConstraintLayout
+        android:id="@+id/option_tile"
+        android:layout_width="0dp"
+        android:layout_height="0dp"
+        android:layout_gravity="center"
+        android:gravity="center"
+        app:layout_constraintBottom_toBottomOf="parent"
+        app:layout_constraintDimensionRatio="1:1"
+        app:layout_constraintEnd_toEndOf="parent"
+        app:layout_constraintStart_toStartOf="parent"
+        app:layout_constraintTop_toTopOf="parent"
+        app:layout_constraintWidth_percent="0.909"
+        android:clipChildren="false">
+
+        <ImageView
+            android:layout_width="match_parent"
+            android:layout_height="match_parent"
+            android:adjustViewBounds="true"
+            android:src="@drawable/color_overflow" />
+    </androidx.constraintlayout.widget.ConstraintLayout>
+</androidx.constraintlayout.widget.ConstraintLayout>
diff --git a/res/layout/color_section_view2.xml b/res/layout/color_section_view2.xml
new file mode 100644
index 0000000..9ad140b
--- /dev/null
+++ b/res/layout/color_section_view2.xml
@@ -0,0 +1,51 @@
+<?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.
+-->
+<com.android.customization.picker.color.ColorSectionView2
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:paddingBottom="@dimen/section_bottom_padding"
+    android:paddingHorizontal="@dimen/section_horizontal_padding"
+    android:orientation="vertical">
+
+    <LinearLayout
+        android:id="@+id/color_section_option_container"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:orientation="horizontal"
+        android:background="@drawable/color_section_background"
+        android:paddingVertical="24dp"
+        android:paddingHorizontal="24dp"
+        android:weightSum="@integer/color_section_num_columns">
+
+        <!--
+            This is just an invisible placeholder put in place so that the parent keeps its height
+            stable as the RecyclerView updates from 0 items to N items. Keeping it stable allows the
+            layout logic to keep the size of the preview container stable as well, which bodes well
+            for setting up the SurfaceView for remote rendering without changing its size after the
+            content is loaded into the RecyclerView.
+
+            It's critical for any TextViews inside the included layout to have text.
+            -->
+        <include
+            android:layout_width="0dp"
+            android:layout_height="wrap_content"
+            layout="@layout/color_option_section_overflow"
+            android:visibility="invisible"
+            android:layout_weight="1"/>
+    </LinearLayout>
+</com.android.customization.picker.color.ColorSectionView2>
diff --git a/res/layout/fragment_color_picker.xml b/res/layout/fragment_color_picker.xml
new file mode 100644
index 0000000..d91ac5e
--- /dev/null
+++ b/res/layout/fragment_color_picker.xml
@@ -0,0 +1,124 @@
+<?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"
+    xmlns:app="http://schemas.android.com/apk/res-auto"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:orientation="vertical">
+
+    <FrameLayout
+        android:id="@+id/section_header_container"
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content">
+
+        <include layout="@layout/section_header" />
+
+    </FrameLayout>
+
+    <com.android.wallpaper.picker.DisplayAspectRatioFrameLayout
+        android:layout_width="match_parent"
+        android:layout_height="0dp"
+        android:layout_weight="1"
+        android:paddingTop="36dp"
+        android:paddingBottom="40dp">
+
+        <include
+            android:id="@+id/preview"
+            layout="@layout/wallpaper_preview_card"
+            android:layout_width="0dp"
+            android:layout_height="match_parent"
+            android:layout_gravity="center"/>
+
+    </com.android.wallpaper.picker.DisplayAspectRatioFrameLayout>
+
+    <LinearLayout
+        android:layout_width="match_parent"
+        android:layout_height="wrap_content"
+        android:orientation="vertical"
+        android:layout_marginHorizontal="24dp"
+        android:layout_marginBottom="28dp"
+        android:background="@drawable/picker_fragment_background"
+        android:paddingTop="22dp"
+        android:paddingBottom="62dp">
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content"
+            >
+
+            <androidx.recyclerview.widget.RecyclerView
+                android:id="@+id/color_type_tabs"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:clipToPadding="false"
+                android:paddingHorizontal="16dp" />
+
+            <!--
+            This is just an invisible placeholder put in place so that the parent keeps its height
+            stable as the RecyclerView updates from 0 items to N items. Keeping it stable allows the
+            layout logic to keep the size of the preview container stable as well, which bodes well
+            for setting up the SurfaceView for remote rendering without changing its size after the
+            content is loaded into the RecyclerView.
+
+            It's critical for any TextViews inside the included layout to have text.
+            -->
+            <include
+                layout="@layout/picker_fragment_tab"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:visibility="invisible" />
+
+        </FrameLayout>
+
+        <View
+            android:layout_width="0dp"
+            android:layout_height="22dp" />
+
+        <FrameLayout
+            android:layout_width="match_parent"
+            android:layout_height="wrap_content">
+
+            <androidx.viewpager2.widget.ViewPager2
+                android:id="@+id/color_section_view_pager"
+                android:layout_width="match_parent"
+                android:layout_height="wrap_content"
+                android:layout_marginTop="@dimen/color_options_container_top_margin"
+                android:clipChildren="false"
+                android:clipToPadding="false"/>
+
+            <!--
+            This is just an invisible placeholder put in place so that the parent keeps its height
+            stable as the RecyclerView updates from 0 items to N items. Keeping it stable allows the
+            layout logic to keep the size of the preview container stable as well, which bodes well
+            for setting up the SurfaceView for remote rendering without changing its size after the
+            content is loaded into the RecyclerView.
+
+            It's critical for any TextViews inside the included layout to have text.
+            -->
+            <include
+                layout="@layout/color_option"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:visibility="invisible" />
+
+        </FrameLayout>
+
+    </LinearLayout>
+
+</LinearLayout>
diff --git a/res/layout/fragment_lock_screen_quick_affordances.xml b/res/layout/fragment_lock_screen_quick_affordances.xml
index 331d501..3fc7275 100644
--- a/res/layout/fragment_lock_screen_quick_affordances.xml
+++ b/res/layout/fragment_lock_screen_quick_affordances.xml
@@ -51,7 +51,7 @@
         android:orientation="vertical"
         android:layout_marginHorizontal="24dp"
         android:layout_marginBottom="28dp"
-        android:background="@drawable/keyguard_quick_affordance_picker_background"
+        android:background="@drawable/picker_fragment_background"
         android:paddingTop="22dp"
         android:paddingBottom="62dp">
 
@@ -77,7 +77,7 @@
             It's critical for any TextViews inside the included layout to have text.
             -->
             <include
-                layout="@layout/keyguard_quick_affordance_slot_tab"
+                layout="@layout/picker_fragment_tab"
                 android:layout_width="wrap_content"
                 android:layout_height="wrap_content"
                 android:visibility="invisible" />
diff --git a/res/layout/keyguard_quick_affordance_enablement_dialog.xml b/res/layout/keyguard_quick_affordance_enablement_dialog.xml
index d6ba105..f3d4d8c 100644
--- a/res/layout/keyguard_quick_affordance_enablement_dialog.xml
+++ b/res/layout/keyguard_quick_affordance_enablement_dialog.xml
@@ -19,7 +19,7 @@
     xmlns:android="http://schemas.android.com/apk/res/android"
     android:layout_width="wrap_content"
     android:layout_height="wrap_content"
-    android:background="@drawable/keyguard_quick_affordance_picker_background"
+    android:background="@drawable/picker_fragment_background"
     android:orientation="vertical"
     android:padding="24dp">
 
diff --git a/res/layout/keyguard_quick_affordance_slot_tab.xml b/res/layout/picker_fragment_tab.xml
similarity index 87%
rename from res/layout/keyguard_quick_affordance_slot_tab.xml
rename to res/layout/picker_fragment_tab.xml
index c4934d8..cd04758 100644
--- a/res/layout/keyguard_quick_affordance_slot_tab.xml
+++ b/res/layout/picker_fragment_tab.xml
@@ -21,12 +21,12 @@
     android:id="@+id/text"
     android:layout_width="wrap_content"
     android:layout_height="wrap_content"
-    android:textColor="@color/keyguard_quick_affordance_slot_tab_text_color"
+    android:textColor="@color/picker_fragment_tab_text_color"
     android:paddingVertical="8dp"
     android:paddingHorizontal="16dp"
     android:minWidth="48dp"
     android:minHeight="48dp"
     android:gravity="center"
-    android:background="@drawable/keyguard_quick_affordance_slot_tab_background"
+    android:background="@drawable/picker_fragment_tab_background"
     android:text="Placeholder for stable size calculation, please do not remove."
     tools:ignore="HardcodedText" />
diff --git a/res/values-w800dp/integers.xml b/res/values-w800dp/integers.xml
index 23fa48a..cef5c90 100644
--- a/res/values-w800dp/integers.xml
+++ b/res/values-w800dp/integers.xml
@@ -16,4 +16,5 @@
 -->
 <resources>
     <integer name="options_grid_num_columns">6</integer>
+    <integer name="color_section_num_columns">5</integer>
 </resources>
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index 64d9941..9099c93 100644
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -133,6 +133,11 @@
     <!-- For the color option section -->
     <dimen name="color_options_container_top_margin">24dp</dimen>
 
+    <dimen name="component_color_overflow_small_radius_default">20dp</dimen>
+    <dimen name="component_color_overflow_small_diameter_default">40dp</dimen>
+    <dimen name="component_color_selected_small_radius_default">22dp</dimen>
+    <dimen name="component_color_selected_small_diameter_default">44dp</dimen>
+
     <!-- For the color page. -->
     <dimen name="color_page_indicator_margin_top">16dp</dimen>
 
diff --git a/res/values/integers.xml b/res/values/integers.xml
index 6e2db17..2129ccd 100644
--- a/res/values/integers.xml
+++ b/res/values/integers.xml
@@ -16,4 +16,5 @@
 -->
 <resources>
     <integer name="options_grid_num_columns">4</integer>
+    <integer name="color_section_num_columns">6</integer>
 </resources>
diff --git a/src/com/android/customization/model/color/ColorSectionController2.java b/src/com/android/customization/model/color/ColorSectionController2.java
new file mode 100644
index 0000000..257bb94
--- /dev/null
+++ b/src/com/android/customization/model/color/ColorSectionController2.java
@@ -0,0 +1,241 @@
+/*
+ * 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.model.color;
+
+import static com.android.customization.model.color.ColorOptionsProvider.COLOR_SOURCE_HOME;
+import static com.android.customization.model.color.ColorOptionsProvider.COLOR_SOURCE_LOCK;
+import static com.android.customization.model.color.ColorOptionsProvider.COLOR_SOURCE_PRESET;
+
+import android.app.Activity;
+import android.app.WallpaperColors;
+import android.content.Context;
+import android.os.Handler;
+import android.os.SystemClock;
+import android.stats.style.StyleEnums;
+import android.text.TextUtils;
+import android.util.Log;
+import android.view.LayoutInflater;
+
+import androidx.annotation.Nullable;
+import androidx.lifecycle.LifecycleOwner;
+
+import com.android.customization.model.CustomizationManager;
+import com.android.customization.model.theme.OverlayManagerCompat;
+import com.android.customization.module.CustomizationInjector;
+import com.android.customization.module.ThemesUserEventLogger;
+import com.android.customization.picker.color.ColorPickerFragment;
+import com.android.customization.picker.color.ColorSectionView2;
+import com.android.wallpaper.R;
+import com.android.wallpaper.model.CustomizationSectionController;
+import com.android.wallpaper.model.WallpaperColorsViewModel;
+import com.android.wallpaper.module.InjectorProvider;
+
+import com.google.common.collect.Iterables;
+import com.google.common.collect.Lists;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Color section view's controller for the logic of color customization.
+ */
+public class ColorSectionController2 implements CustomizationSectionController<ColorSectionView2> {
+
+    private static final String TAG = "ColorSectionController";
+    private static final long MIN_COLOR_APPLY_PERIOD = 500L;
+
+    private final ThemesUserEventLogger mEventLogger;
+    private final ColorCustomizationManager mColorManager;
+    private final WallpaperColorsViewModel mWallpaperColorsViewModel;
+    private final LifecycleOwner mLifecycleOwner;
+    private final CustomizationSectionNavigationController mSectionNavigationController;
+
+    private List<ColorOption> mWallpaperColorOptions = new ArrayList<>();
+    private List<ColorOption> mPresetColorOptions = new ArrayList<>();
+    private ColorOption mSelectedColor;
+    @Nullable private WallpaperColors mHomeWallpaperColors;
+    @Nullable private WallpaperColors mLockWallpaperColors;
+    // Uses a boolean value to indicate whether wallpaper color is ready because WallpaperColors
+    // maybe be null when it's ready.
+    private boolean mHomeWallpaperColorsReady;
+    private boolean mLockWallpaperColorsReady;
+    private long mLastColorApplyingTime = 0L;
+    private ColorSectionView2 mColorSectionView;
+
+    public ColorSectionController2(Activity activity, WallpaperColorsViewModel viewModel,
+            LifecycleOwner lifecycleOwner,
+            CustomizationSectionNavigationController sectionNavigationController) {
+        CustomizationInjector injector = (CustomizationInjector) InjectorProvider.getInjector();
+        mEventLogger = (ThemesUserEventLogger) injector.getUserEventLogger(activity);
+        mColorManager = ColorCustomizationManager.getInstance(activity,
+                new OverlayManagerCompat(activity));
+        mWallpaperColorsViewModel = viewModel;
+        mLifecycleOwner = lifecycleOwner;
+        mSectionNavigationController = sectionNavigationController;
+    }
+
+    @Override
+    public boolean isAvailable(@Nullable Context context) {
+        return context != null && ColorUtils.isMonetEnabled(context) && mColorManager.isAvailable();
+    }
+
+    @Override
+    public ColorSectionView2 createView(Context context) {
+        mColorSectionView = (ColorSectionView2) LayoutInflater.from(context).inflate(
+                R.layout.color_section_view2, /* root= */ null);
+
+        mWallpaperColorsViewModel.getHomeWallpaperColors().observe(mLifecycleOwner,
+                homeColors -> {
+                    mHomeWallpaperColors = homeColors;
+                    mHomeWallpaperColorsReady = true;
+                    maybeLoadColors();
+                });
+        mWallpaperColorsViewModel.getLockWallpaperColors().observe(mLifecycleOwner,
+                lockColors -> {
+                    mLockWallpaperColors = lockColors;
+                    mLockWallpaperColorsReady = true;
+                    maybeLoadColors();
+                });
+        return mColorSectionView;
+    }
+
+    private void maybeLoadColors() {
+        if (mHomeWallpaperColorsReady && mLockWallpaperColorsReady) {
+            mColorManager.setWallpaperColors(mHomeWallpaperColors, mLockWallpaperColors);
+            loadColorOptions(/* reload= */ false);
+        }
+    }
+
+    private void loadColorOptions(boolean reload) {
+        mColorManager.fetchOptions(new CustomizationManager.OptionsFetchedListener<ColorOption>() {
+            @Override
+            public void onOptionsLoaded(List<ColorOption> options) {
+                List<ColorOption> wallpaperColorOptions = new ArrayList<>();
+                List<ColorOption> presetColorOptions = new ArrayList<>();
+                for (ColorOption option : options) {
+                    if (option instanceof ColorSeedOption) {
+                        wallpaperColorOptions.add(option);
+                    } else if (option instanceof ColorBundle) {
+                        presetColorOptions.add(option);
+                    }
+                }
+                mWallpaperColorOptions = wallpaperColorOptions;
+                mPresetColorOptions = presetColorOptions;
+                mSelectedColor = findActiveColorOption(mWallpaperColorOptions,
+                        mPresetColorOptions);
+
+                mColorSectionView.post(() -> setUpColorSectionView(mWallpaperColorOptions,
+                        mPresetColorOptions));
+            }
+
+            @Override
+            public void onError(@Nullable Throwable throwable) {
+                if (throwable != null) {
+                    Log.e(TAG, "Error loading theme bundles", throwable);
+                }
+            }
+        }, reload);
+    }
+
+    private void setUpColorSectionView(List<ColorOption> wallpaperColorOptions,
+            List<ColorOption> presetColorOptions) {
+        int wallpaperOptionSize = wallpaperColorOptions.size();
+
+        List<ColorOption> subOptions = wallpaperColorOptions.subList(0,
+                Math.min(5, wallpaperOptionSize));
+        // add additional options based on preset colors if there are less than 5 wallpaper colors
+        List<ColorOption> additionalSubOptions = presetColorOptions.subList(0,
+                Math.min(Math.max(0, 5 - wallpaperOptionSize), presetColorOptions.size()));
+        subOptions.addAll(additionalSubOptions);
+
+        mColorSectionView.setOverflowOnClick(() -> {
+            mSectionNavigationController.navigateTo(new ColorPickerFragment());
+            return null;
+        });
+        mColorSectionView.setColorOptionOnClick(selectedOption -> {
+            if (mSelectedColor.equals(selectedOption)) {
+                return null;
+            }
+            mSelectedColor = (ColorOption) selectedOption;
+            // Post with delay for color option to run ripple.
+            new Handler().postDelayed(()-> applyColor(mSelectedColor), /* delayMillis= */ 100);
+            return null;
+        });
+        mColorSectionView.setItems(subOptions, mColorManager);
+    }
+
+    private ColorOption findActiveColorOption(List<ColorOption> wallpaperColorOptions,
+            List<ColorOption> presetColorOptions) {
+        ColorOption activeColorOption = null;
+        for (ColorOption colorOption : Lists.newArrayList(
+                Iterables.concat(wallpaperColorOptions, presetColorOptions))) {
+            if (colorOption.isActive(mColorManager)) {
+                activeColorOption = colorOption;
+                break;
+            }
+        }
+        // Use the first one option by default. This should not happen as above should have an
+        // active option found.
+        if (activeColorOption == null) {
+            activeColorOption = wallpaperColorOptions.isEmpty()
+                    ? presetColorOptions.get(0)
+                    : wallpaperColorOptions.get(0);
+        }
+        return activeColorOption;
+    }
+
+    private void applyColor(ColorOption colorOption) {
+        if (SystemClock.elapsedRealtime() - mLastColorApplyingTime < MIN_COLOR_APPLY_PERIOD) {
+            return;
+        }
+        mLastColorApplyingTime = SystemClock.elapsedRealtime();
+        mColorManager.apply(colorOption, new CustomizationManager.Callback() {
+            @Override
+            public void onSuccess() {
+                mColorSectionView.announceForAccessibility(
+                        mColorSectionView.getContext().getString(R.string.color_changed));
+                mEventLogger.logColorApplied(getColorAction(colorOption), colorOption);
+            }
+
+            @Override
+            public void onError(@Nullable Throwable throwable) {
+                Log.w(TAG, "Apply theme with error: " + throwable);
+            }
+        });
+    }
+
+    private int getColorAction(ColorOption colorOption) {
+        int action = StyleEnums.DEFAULT_ACTION;
+        boolean isForBoth = mLockWallpaperColors == null || mLockWallpaperColors.equals(
+                mHomeWallpaperColors);
+
+        if (TextUtils.equals(colorOption.getSource(), COLOR_SOURCE_PRESET)) {
+            action = StyleEnums.COLOR_PRESET_APPLIED;
+        } else if (isForBoth) {
+            action = StyleEnums.COLOR_WALLPAPER_HOME_LOCK_APPLIED;
+        } else {
+            switch (colorOption.getSource()) {
+                case COLOR_SOURCE_HOME:
+                    action = StyleEnums.COLOR_WALLPAPER_HOME_APPLIED;
+                    break;
+                case COLOR_SOURCE_LOCK:
+                    action = StyleEnums.COLOR_WALLPAPER_LOCK_APPLIED;
+                    break;
+            }
+        }
+        return action;
+    }
+}
diff --git a/src/com/android/customization/module/DefaultCustomizationSections.java b/src/com/android/customization/module/DefaultCustomizationSections.java
index 2fb530a..c5affd1 100644
--- a/src/com/android/customization/module/DefaultCustomizationSections.java
+++ b/src/com/android/customization/module/DefaultCustomizationSections.java
@@ -8,6 +8,7 @@
 import androidx.lifecycle.ViewModelProvider;
 
 import com.android.customization.model.color.ColorSectionController;
+import com.android.customization.model.color.ColorSectionController2;
 import com.android.customization.model.grid.GridOptionsManager;
 import com.android.customization.model.grid.GridSectionController;
 import com.android.customization.model.mode.DarkModeSectionController;
@@ -50,7 +51,7 @@
     }
 
     @Override
-    public List<CustomizationSectionController<?>> getSectionControllersForScreen(
+    public List<CustomizationSectionController<?>> getRevampedUISectionControllersForScreen(
             Screen screen,
             FragmentActivity activity,
             LifecycleOwner lifecycleOwner,
@@ -76,8 +77,8 @@
                         displayUtils));
 
         // Theme color section.
-        sectionControllers.add(new ColorSectionController(
-                activity, wallpaperColorsViewModel, lifecycleOwner, savedInstanceState));
+        sectionControllers.add(new ColorSectionController2(
+                activity, wallpaperColorsViewModel, lifecycleOwner, sectionNavigationController));
 
         // Wallpaper quick switch section.
         sectionControllers.add(
diff --git a/src/com/android/customization/picker/color/ColorPickerFragment.kt b/src/com/android/customization/picker/color/ColorPickerFragment.kt
new file mode 100644
index 0000000..c8ecb7f
--- /dev/null
+++ b/src/com/android/customization/picker/color/ColorPickerFragment.kt
@@ -0,0 +1,41 @@
+/*
+ * 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.color
+
+import android.os.Bundle
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import com.android.wallpaper.R
+import com.android.wallpaper.picker.AppbarFragment
+
+// TODO (b/262924623): Color Picker Fragment
+class ColorPickerFragment : AppbarFragment() {
+    override fun onCreateView(
+        inflater: LayoutInflater,
+        container: ViewGroup?,
+        savedInstanceState: Bundle?
+    ): View {
+        val view =
+            inflater.inflate(
+                R.layout.fragment_color_picker,
+                container,
+                false,
+            )
+        setUpToolbar(view)
+        return view
+    }
+}
diff --git a/src/com/android/customization/picker/color/ColorSectionView2.kt b/src/com/android/customization/picker/color/ColorSectionView2.kt
new file mode 100644
index 0000000..3e4e4bc
--- /dev/null
+++ b/src/com/android/customization/picker/color/ColorSectionView2.kt
@@ -0,0 +1,93 @@
+/*
+ * 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.color
+
+import android.content.Context
+import android.util.AttributeSet
+import android.view.LayoutInflater
+import android.widget.ImageView
+import android.widget.LinearLayout
+import com.android.customization.model.color.ColorCustomizationManager
+import com.android.customization.model.color.ColorOption
+import com.android.wallpaper.R
+import com.android.wallpaper.picker.SectionView
+
+/**
+ * The class inherits from {@link SectionView} as the view representing the color section of the
+ * customization picker. It displays a list of color options and an overflow option.
+ */
+class ColorSectionView2(context: Context, attrs: AttributeSet?) : SectionView(context, attrs) {
+
+    private val items = mutableListOf<ColorOption>()
+    private var onClick: ((ColorOption) -> Unit)? = null
+    private var overflowOnClick: (() -> Unit)? = null
+
+    // TODO (b/262924623): make adjustments for large screen
+    fun setItems(items: List<ColorOption>, manager: ColorCustomizationManager) {
+        this.items.clear()
+        this.items.addAll(items)
+        val optionContainer = findViewById<LinearLayout>(R.id.color_section_option_container)
+        optionContainer.removeAllViews()
+        // Last color option is either the last index of the items list, or the second last index
+        // of column count. Save the last column of the option container for the overflow option
+        val lastOptionIndex = minOf(optionContainer.weightSum.toInt() - 2, items.size - 1)
+        if (items.isNotEmpty()) {
+            for (position in 0..lastOptionIndex) {
+                val item = items[position]
+                val itemView =
+                    LayoutInflater.from(context)
+                        .inflate(R.layout.color_option_section, optionContainer, false)
+                item.bindThumbnailTile(itemView.findViewById(R.id.option_tile))
+                if (item.isActive(manager)) {
+                    val optionSelectedView = itemView.findViewById<ImageView>(R.id.option_selected)
+                    optionSelectedView.visibility = VISIBLE
+                }
+                itemView.setOnClickListener { onClick?.invoke(item) }
+                optionContainer.addView(itemView)
+            }
+        }
+        // add overflow option
+        val itemView =
+            LayoutInflater.from(context)
+                .inflate(R.layout.color_option_section_overflow, optionContainer, false)
+        itemView.setOnClickListener { overflowOnClick?.invoke() }
+        optionContainer.addView(itemView)
+    }
+
+    /** Sets the on click callback for a color option. */
+    fun setColorOptionOnClick(onClick: (ColorOption) -> Unit) {
+        this.onClick = onClick
+        if (items.isNotEmpty()) {
+            val optionContainer = findViewById<LinearLayout>(R.id.color_section_option_container)
+            val lastOptionIndex = minOf(optionContainer.childCount - 2, items.size - 1)
+            for (position in 0..lastOptionIndex) {
+                val item = items[position]
+                val itemView = optionContainer.getChildAt(position)
+                itemView.setOnClickListener { onClick.invoke(item) }
+            }
+        }
+    }
+
+    /** Sets the on click callback for the overflow option. */
+    fun setOverflowOnClick(onClick: () -> Unit) {
+        this.overflowOnClick = onClick
+        val optionContainer = findViewById<LinearLayout>(R.id.color_section_option_container)
+        if (optionContainer.childCount > 0) {
+            val itemView = optionContainer.getChildAt(optionContainer.childCount - 1)
+            itemView.setOnClickListener { onClick.invoke() }
+        }
+    }
+}
diff --git a/src/com/android/customization/picker/quickaffordance/ui/adapter/SlotTabAdapter.kt b/src/com/android/customization/picker/quickaffordance/ui/adapter/SlotTabAdapter.kt
index acafef4..5203ed3 100644
--- a/src/com/android/customization/picker/quickaffordance/ui/adapter/SlotTabAdapter.kt
+++ b/src/com/android/customization/picker/quickaffordance/ui/adapter/SlotTabAdapter.kt
@@ -44,7 +44,7 @@
         return ViewHolder(
             LayoutInflater.from(parent.context)
                 .inflate(
-                    R.layout.keyguard_quick_affordance_slot_tab,
+                    R.layout.picker_fragment_tab,
                     parent,
                     false,
                 )
diff --git a/src/com/android/customization/widget/OptionSelectorController.java b/src/com/android/customization/widget/OptionSelectorController.java
index 8805caf..fc665b9 100644
--- a/src/com/android/customization/widget/OptionSelectorController.java
+++ b/src/com/android/customization/widget/OptionSelectorController.java
@@ -183,6 +183,16 @@
             @Override
             public TileViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
                 View v = LayoutInflater.from(parent.getContext()).inflate(viewType, parent, false);
+                // Provide width constraint when a grid layout manager is not use and width is set
+                // to match parent
+                if (!mUseGrid
+                        && v.getLayoutParams().width == RecyclerView.LayoutParams.MATCH_PARENT) {
+                    Resources res = mContainer.getContext().getResources();
+                    RecyclerView.LayoutParams layoutParams = new RecyclerView.LayoutParams(
+                            res.getDimensionPixelSize(R.dimen.option_tile_width),
+                            RecyclerView.LayoutParams.WRAP_CONTENT);
+                    v.setLayoutParams(layoutParams);
+                }
                 return new TileViewHolder(v);
             }