Merge Android 13 QPR3 tm-qpr-dev-plus-aosp-without-vendor@9936994
Bug: 275386652
Merged-In: Idf6dc5a825f7541912a7bb891ce8f2b5b52aea9f
Change-Id: I1759d6a65bde0446b487a4c167a6731bf3bd5b4f
diff --git a/Android.bp b/Android.bp
index 6d9ff8f..f6c8558 100644
--- a/Android.bp
+++ b/Android.bp
@@ -77,6 +77,7 @@
"SettingsLibSettingsTheme",
"SystemUI-statsd",
"styleprotoslite",
+ "androidx.lifecycle_lifecycle-livedata-ktx",
"androidx.lifecycle_lifecycle-runtime-ktx",
"androidx.lifecycle_lifecycle-viewmodel-ktx",
"androidx.recyclerview_recyclerview",
diff --git a/ktfmt_includes.txt b/ktfmt_includes.txt
index 112b4a1..0708ab2 100644
--- a/ktfmt_includes.txt
+++ b/ktfmt_includes.txt
@@ -1,3 +1,4 @@
+src/
+src_override/
+tests/
+-src/com/android/customization/module/SysUiStatsLogger.kt
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_selected_no_background.xml b/res/drawable/color_option_selected_no_background.xml
new file mode 100644
index 0000000..13451a5
--- /dev/null
+++ b/res/drawable/color_option_selected_no_background.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/ic_clock_24px.xml b/res/drawable/ic_clock_24px.xml
index b3f1fee..946bc51 100644
--- a/res/drawable/ic_clock_24px.xml
+++ b/res/drawable/ic_clock_24px.xml
@@ -20,6 +20,6 @@
android:viewportHeight="24"
android:tint="?attr/colorControlNormal">
<path
- android:fillColor="@android:color/white"
+ android:fillColor="?android:textColorPrimary"
android:pathData="M15.3,16.7 L16.7,15.3 13,11.6V7H11V12.4ZM12,22Q9.925,22 8.1,21.212Q6.275,20.425 4.925,19.075Q3.575,17.725 2.788,15.9Q2,14.075 2,12Q2,9.925 2.788,8.1Q3.575,6.275 4.925,4.925Q6.275,3.575 8.1,2.787Q9.925,2 12,2Q14.075,2 15.9,2.787Q17.725,3.575 19.075,4.925Q20.425,6.275 21.212,8.1Q22,9.925 22,12Q22,14.075 21.212,15.9Q20.425,17.725 19.075,19.075Q17.725,20.425 15.9,21.212Q14.075,22 12,22ZM12,12Q12,12 12,12Q12,12 12,12Q12,12 12,12Q12,12 12,12Q12,12 12,12Q12,12 12,12Q12,12 12,12Q12,12 12,12ZM12,20Q15.325,20 17.663,17.663Q20,15.325 20,12Q20,8.675 17.663,6.337Q15.325,4 12,4Q8.675,4 6.338,6.337Q4,8.675 4,12Q4,15.325 6.338,17.663Q8.675,20 12,20Z"/>
</vector>
\ No newline at end of file
diff --git a/res/drawable/ic_contrast.xml b/res/drawable/ic_contrast.xml
new file mode 100644
index 0000000..6e9f3bd
--- /dev/null
+++ b/res/drawable/ic_contrast.xml
@@ -0,0 +1,11 @@
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:autoMirrored="true"
+ android:tint="@color/text_color_primary_inverse"
+ android:viewportHeight="24"
+ android:viewportWidth="24">
+ <path
+ android:fillColor="@android:color/white"
+ android:pathData="M12,22Q9.925,22 8.1,21.212Q6.275,20.425 4.925,19.075Q3.575,17.725 2.788,15.9Q2,14.075 2,12Q2,9.925 2.788,8.1Q3.575,6.275 4.925,4.925Q6.275,3.575 8.1,2.787Q9.925,2 12,2Q14.075,2 15.9,2.787Q17.725,3.575 19.075,4.925Q20.425,6.275 21.212,8.1Q22,9.925 22,12Q22,14.075 21.212,15.9Q20.425,17.725 19.075,19.075Q17.725,20.425 15.9,21.212Q14.075,22 12,22ZM13,19.925Q15.975,19.55 17.988,17.312Q20,15.075 20,12Q20,8.925 17.988,6.687Q15.975,4.45 13,4.075Z" />
+</vector>
\ 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/ic_nav_color.xml b/res/drawable/ic_nav_color.xml
new file mode 100644
index 0000000..cfa64e2
--- /dev/null
+++ b/res/drawable/ic_nav_color.xml
@@ -0,0 +1,23 @@
+<!--
+ Copyright (C) 2019 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.
+-->
+<!-- Represents the color icon (a palette) -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+ <path android:fillColor="@android:color/white" android:pathData="M12,22Q9.95,22 8.125,21.212Q6.3,20.425 4.938,19.062Q3.575,17.7 2.788,15.875Q2,14.05 2,12Q2,9.925 2.812,8.1Q3.625,6.275 5.013,4.925Q6.4,3.575 8.25,2.787Q10.1,2 12.2,2Q14.2,2 15.975,2.688Q17.75,3.375 19.087,4.588Q20.425,5.8 21.212,7.463Q22,9.125 22,11.05Q22,13.925 20.25,15.462Q18.5,17 16,17H14.15Q13.925,17 13.838,17.125Q13.75,17.25 13.75,17.4Q13.75,17.7 14.125,18.262Q14.5,18.825 14.5,19.55Q14.5,20.8 13.812,21.4Q13.125,22 12,22ZM12,12Q12,12 12,12Q12,12 12,12Q12,12 12,12Q12,12 12,12Q12,12 12,12Q12,12 12,12Q12,12 12,12Q12,12 12,12Q12,12 12,12Q12,12 12,12Q12,12 12,12Q12,12 12,12Q12,12 12,12Q12,12 12,12ZM6.5,13Q7.15,13 7.575,12.575Q8,12.15 8,11.5Q8,10.85 7.575,10.425Q7.15,10 6.5,10Q5.85,10 5.425,10.425Q5,10.85 5,11.5Q5,12.15 5.425,12.575Q5.85,13 6.5,13ZM9.5,9Q10.15,9 10.575,8.575Q11,8.15 11,7.5Q11,6.85 10.575,6.425Q10.15,6 9.5,6Q8.85,6 8.425,6.425Q8,6.85 8,7.5Q8,8.15 8.425,8.575Q8.85,9 9.5,9ZM14.5,9Q15.15,9 15.575,8.575Q16,8.15 16,7.5Q16,6.85 15.575,6.425Q15.15,6 14.5,6Q13.85,6 13.425,6.425Q13,6.85 13,7.5Q13,8.15 13.425,8.575Q13.85,9 14.5,9ZM17.5,13Q18.15,13 18.575,12.575Q19,12.15 19,11.5Q19,10.85 18.575,10.425Q18.15,10 17.5,10Q16.85,10 16.425,10.425Q16,10.85 16,11.5Q16,12.15 16.425,12.575Q16.85,13 17.5,13ZM12,20Q12.225,20 12.363,19.875Q12.5,19.75 12.5,19.55Q12.5,19.2 12.125,18.725Q11.75,18.25 11.75,17.3Q11.75,16.25 12.475,15.625Q13.2,15 14.25,15H16Q17.65,15 18.825,14.037Q20,13.075 20,11.05Q20,8.025 17.688,6.012Q15.375,4 12.2,4Q8.8,4 6.4,6.325Q4,8.65 4,12Q4,15.325 6.338,17.663Q8.675,20 12,20Z"/>
+</vector>
diff --git a/res/drawable/keyguard_quick_affordance_icon_container_background.xml b/res/drawable/keyguard_quick_affordance_icon_container_background.xml
deleted file mode 100644
index 8bd8af4..0000000
--- a/res/drawable/keyguard_quick_affordance_icon_container_background.xml
+++ /dev/null
@@ -1,20 +0,0 @@
-<!--
- Copyright (C) 2021 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">
- <corners android:radius="20dp" />
- <solid android:color="@color/color_surface_variant" />
-</shape>
diff --git a/res/drawable/keyguard_quick_affordance_icon_container_background_selected.xml b/res/drawable/keyguard_quick_affordance_icon_container_background_selected.xml
deleted file mode 100644
index 93a80eb..0000000
--- a/res/drawable/keyguard_quick_affordance_icon_container_background_selected.xml
+++ /dev/null
@@ -1,34 +0,0 @@
-<!--
- Copyright (C) 2021 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" >
-
- <stroke
- android:width="2dp"
- android:color="@color/text_color_primary" />
-
- <solid android:color="@color/color_surface_variant" />
-
- <corners android:radius="20dp" />
-
- <padding
- android:left="5dp"
- android:top="5dp"
- android:right="5dp"
- android:bottom="5dp" />
-
-</shape>
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 95%
rename from res/drawable/keyguard_quick_affordance_slot_tab_background.xml
rename to res/drawable/picker_fragment_tab_background.xml
index 3fbced3..3dad344 100644
--- a/res/drawable/keyguard_quick_affordance_slot_tab_background.xml
+++ b/res/drawable/picker_fragment_tab_background.xml
@@ -15,6 +15,6 @@
-->
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
- <corners android:radius="50dp" />
+ <corners android:radius="12dp" />
<solid android:color="@color/keyguard_quick_affordance_slot_tab_background_color" />
</shape>
diff --git a/res/drawable/saturation_progress_drawable.xml b/res/drawable/saturation_progress_drawable.xml
new file mode 100644
index 0000000..6ba7e81
--- /dev/null
+++ b/res/drawable/saturation_progress_drawable.xml
@@ -0,0 +1,37 @@
+<?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"
+ android:paddingMode="stack" >
+ <item android:id="@android:id/background"
+ android:gravity="center_vertical|fill_horizontal">
+ <inset
+ android:insetLeft="22dp"
+ android:insetRight="22dp" >
+ <shape>
+ <size android:height="4dp" />
+ <corners android:radius="2dp" />
+ <solid android:color="@color/color_surface_variant" />
+ </shape>
+ </inset>
+ </item>
+ <item android:id="@android:id/progress"
+ android:gravity="center_vertical|fill_horizontal">
+ <com.android.customization.picker.clock.ui.view.SaturationProgressDrawable
+ android:drawable="@drawable/saturation_progress_full_drawable"
+ />
+ </item>
+</layer-list>
\ No newline at end of file
diff --git a/res/drawable/saturation_progress_full_drawable.xml b/res/drawable/saturation_progress_full_drawable.xml
new file mode 100644
index 0000000..9d14bcd
--- /dev/null
+++ b/res/drawable/saturation_progress_full_drawable.xml
@@ -0,0 +1,35 @@
+<?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"
+ android:autoMirrored="true">
+ <item android:id="@+id/slider_foreground"
+ android:height="48dp">
+ <shape>
+ <size android:height="48dp" />
+ <solid android:color="@color/color_accent_primary" />
+ <corners android:radius="24dp"/>
+ </shape>
+ </item>
+ <item
+ android:id="@+id/slider_icon"
+ android:gravity="center_vertical|right"
+ android:height="20dp"
+ android:width="20dp"
+ android:right="14dp"
+ android:drawable="@drawable/ic_contrast" />
+</layer-list>
\ No newline at end of file
diff --git a/res/drawable/top_connected_section_background.xml b/res/drawable/top_connected_section_background.xml
new file mode 100644
index 0000000..f96824b
--- /dev/null
+++ b/res/drawable/top_connected_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/layout/clock_carousel.xml b/res/layout/clock_carousel.xml
new file mode 100644
index 0000000..35defd6
--- /dev/null
+++ b/res/layout/clock_carousel.xml
@@ -0,0 +1,122 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2023 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<androidx.constraintlayout.motion.widget.MotionLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:app="http://schemas.android.com/apk/res-auto"
+ android:id="@+id/motion_container"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ app:layoutDescription="@xml/carousel_scene">
+
+ <com.android.wallpaper.picker.DisplayAspectRatioFrameLayout
+ android:id="@+id/item_view_0"
+ android:layout_width="@dimen/clock_carousel_item_width"
+ android:layout_height="@dimen/clock_carousel_item_height"
+ android:layout_marginEnd="@dimen/clock_carousel_item_margin"
+ app:layout_constraintBottom_toBottomOf="parent"
+ app:layout_constraintEnd_toStartOf="@+id/item_view_1"
+ app:layout_constraintTop_toTopOf="parent">
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:layout_gravity="center" />
+ </com.android.wallpaper.picker.DisplayAspectRatioFrameLayout>
+
+ <com.android.wallpaper.picker.DisplayAspectRatioFrameLayout
+ android:id="@+id/item_view_1"
+ android:layout_width="@dimen/clock_carousel_item_width"
+ android:layout_height="@dimen/clock_carousel_item_height"
+ android:layout_marginEnd="@dimen/clock_carousel_item_margin"
+ app:layout_constraintBottom_toBottomOf="parent"
+ app:layout_constraintEnd_toStartOf="@+id/item_view_2"
+ app:layout_constraintTop_toTopOf="parent" >
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:layout_gravity="center" />
+ </com.android.wallpaper.picker.DisplayAspectRatioFrameLayout>
+
+ <com.android.wallpaper.picker.DisplayAspectRatioFrameLayout
+ android:id="@+id/item_view_2"
+ android:layout_width="@dimen/clock_carousel_item_width"
+ android:layout_height="@dimen/clock_carousel_item_height"
+ app:layout_constraintBottom_toBottomOf="parent"
+ app:layout_constraintEnd_toEndOf="parent"
+ app:layout_constraintHorizontal_bias="0.5"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintTop_toTopOf="parent">
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:layout_gravity="center" />
+ </com.android.wallpaper.picker.DisplayAspectRatioFrameLayout>
+
+ <com.android.wallpaper.picker.DisplayAspectRatioFrameLayout
+ android:id="@+id/item_view_3"
+ android:layout_width="@dimen/clock_carousel_item_width"
+ android:layout_height="@dimen/clock_carousel_item_height"
+ android:layout_marginStart="@dimen/clock_carousel_item_margin"
+ app:layout_constraintBottom_toBottomOf="parent"
+ app:layout_constraintStart_toEndOf="@+id/item_view_2"
+ app:layout_constraintTop_toTopOf="parent" >
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:layout_gravity="center" />
+ </com.android.wallpaper.picker.DisplayAspectRatioFrameLayout>
+
+ <com.android.wallpaper.picker.DisplayAspectRatioFrameLayout
+ android:id="@+id/item_view_4"
+ android:layout_width="@dimen/clock_carousel_item_width"
+ android:layout_height="@dimen/clock_carousel_item_height"
+ android:layout_marginStart="@dimen/clock_carousel_item_margin"
+ app:layout_constraintBottom_toBottomOf="parent"
+ app:layout_constraintStart_toEndOf="@+id/item_view_3"
+ app:layout_constraintTop_toTopOf="parent" >
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:layout_gravity="center" />
+ </com.android.wallpaper.picker.DisplayAspectRatioFrameLayout>
+
+ <androidx.constraintlayout.helper.widget.Carousel
+ android:id="@+id/carousel"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ app:carousel_backwardTransition="@+id/backward"
+ app:carousel_firstView="@+id/item_view_2"
+ app:carousel_forwardTransition="@+id/forward"
+ app:carousel_infinite="true"
+ app:carousel_nextState="@+id/next"
+ app:carousel_previousState="@+id/previous"
+ app:constraint_referenced_ids="item_view_0,item_view_1,item_view_2,item_view_3,item_view_4" />
+
+ <!-- The guidelines make sure that only the view in the middle show between the lines -->
+ <androidx.constraintlayout.widget.Guideline
+ android:id="@+id/guideline_start"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:orientation="vertical"
+ app:layout_constraintGuide_begin="@dimen/clock_carousel_guideline_margin" />
+
+ <androidx.constraintlayout.widget.Guideline
+ android:id="@+id/guideline_end"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:orientation="vertical"
+ app:layout_constraintGuide_end="@dimen/clock_carousel_guideline_margin" />
+</androidx.constraintlayout.motion.widget.MotionLayout>
\ No newline at end of file
diff --git a/res/drawable/keyguard_quick_affordance_slot_tab_background.xml b/res/layout/clock_carousel_view.xml
similarity index 63%
copy from res/drawable/keyguard_quick_affordance_slot_tab_background.xml
copy to res/layout/clock_carousel_view.xml
index 3fbced3..f1c959c 100644
--- a/res/drawable/keyguard_quick_affordance_slot_tab_background.xml
+++ b/res/layout/clock_carousel_view.xml
@@ -1,5 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
<!--
- Copyright (C) 2021 The Android Open Source Project
+ 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.
@@ -13,8 +14,7 @@
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">
- <corners android:radius="50dp" />
- <solid android:color="@color/keyguard_quick_affordance_slot_tab_background_color" />
-</shape>
+<com.android.customization.picker.clock.ui.view.ClockCarouselView
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="@dimen/screen_preview_height" />
\ No newline at end of file
diff --git a/res/layout/clock_section_view.xml b/res/layout/clock_section_view.xml
index 8512498..31f08fc 100644
--- a/res/layout/clock_section_view.xml
+++ b/res/layout/clock_section_view.xml
@@ -14,7 +14,7 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-<com.android.customization.picker.clock.ClockSectionView
+<com.android.customization.picker.clock.ui.view.ClockSectionView
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
@@ -33,13 +33,13 @@
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:text="@string/clock_title"
+ android:text="@string/clock_color_and_size_title"
style="@style/SectionTitleTextStyle" />
<TextView
+ android:id="@+id/selected_clock_color_and_size"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:text="@string/clock_description"
style="@style/SectionSubtitleTextStyle"/>
</LinearLayout>
@@ -49,7 +49,5 @@
android:scaleType="center"
android:src="@drawable/ic_clock_24px"
android:background="@drawable/option_border_color"
- android:contentDescription="@string/clock_picker_entry_content_description"
- android:tint="@color/text_color_primary" />
-
-</com.android.customization.picker.clock.ClockSectionView>
\ No newline at end of file
+ android:contentDescription="@string/clock_picker_entry_content_description" />
+</com.android.customization.picker.clock.ui.view.ClockSectionView>
\ No newline at end of file
diff --git a/res/layout/clock_size_radio_button_group.xml b/res/layout/clock_size_radio_button_group.xml
new file mode 100644
index 0000000..4264007
--- /dev/null
+++ b/res/layout/clock_size_radio_button_group.xml
@@ -0,0 +1,77 @@
+<?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" />
+
+ <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:text="@string/clock_size_dynamic" />
+
+ <TextView
+ style="@style/SectionSubtitleTextStyle"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ 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: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" />
+
+ <TextView
+ style="@style/SectionTitleTextStyle"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center_vertical"
+ android:text="@string/clock_size_small" />
+ </LinearLayout>
+</LinearLayout>
\ No newline at end of file
diff --git a/res/layout/color_option_2.xml b/res/layout/color_option_2.xml
new file mode 100644
index 0000000..2ac0fe6
--- /dev/null
+++ b/res/layout/color_option_2.xml
@@ -0,0 +1,90 @@
+<?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.
+-->
+<!-- Content description is set programmatically on the parent FrameLayout -->
+<LinearLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:orientation="vertical"
+ android:clipChildren="false">
+ <FrameLayout
+ android:id="@+id/icon_container"
+ android:layout_width="@dimen/option_tile_width"
+ android:layout_height="@dimen/option_tile_width"
+ android:clipChildren="false">
+
+ <ImageView
+ android:id="@id/selection_border"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:background="@drawable/option_item_border"
+ android:alpha="0"
+ android:importantForAccessibility="no" />
+
+ <ImageView
+ android:id="@id/background"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:background="@drawable/option_item_background"
+ android:importantForAccessibility="no" />
+
+ <FrameLayout
+ android:id="@id/foreground"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+ <ImageView
+ android:id="@+id/color_preview_0"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center"
+ android:layout_marginRight="@dimen/color_seed_chip_margin"
+ android:layout_marginBottom="@dimen/color_seed_chip_margin"
+ android:src="@drawable/color_chip_seed_filled0"
+ android:importantForAccessibility="no"/>
+
+ <ImageView
+ android:id="@+id/color_preview_1"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center"
+ android:layout_marginLeft="@dimen/color_seed_chip_margin"
+ android:layout_marginBottom="@dimen/color_seed_chip_margin"
+ android:src="@drawable/color_chip_seed_filled2"
+ android:importantForAccessibility="no"/>
+
+ <ImageView
+ android:id="@+id/color_preview_2"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center"
+ android:layout_marginRight="@dimen/color_seed_chip_margin"
+ android:layout_marginTop="@dimen/color_seed_chip_margin"
+ android:src="@drawable/color_chip_seed_filled1"
+ android:importantForAccessibility="no"/>
+
+ <ImageView
+ android:id="@+id/color_preview_3"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center"
+ android:layout_marginLeft="@dimen/color_seed_chip_margin"
+ android:layout_marginTop="@dimen/color_seed_chip_margin"
+ android:src="@drawable/color_chip_seed_filled3"
+ android:importantForAccessibility="no" />
+ </FrameLayout>
+ </FrameLayout>
+</LinearLayout>
+
diff --git a/res/layout/color_option_no_background.xml b/res/layout/color_option_no_background.xml
new file mode 100644
index 0000000..b90b480
--- /dev/null
+++ b/res/layout/color_option_no_background.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_selected_no_background"
+ android:visibility="gone"/>
+</androidx.constraintlayout.widget.ConstraintLayout>
diff --git a/res/layout/color_option_overflow_no_background.xml b/res/layout/color_option_overflow_no_background.xml
new file mode 100644
index 0000000..fb25c35
--- /dev/null
+++ b/res/layout/color_option_overflow_no_background.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_option_with_background.xml b/res/layout/color_option_with_background.xml
new file mode 100644
index 0000000..36990b5
--- /dev/null
+++ b/res/layout/color_option_with_background.xml
@@ -0,0 +1,93 @@
+<?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.
+-->
+<!-- Content description is set programmatically on the parent FrameLayout -->
+<!-- TODO (b/272109171): Remove after clock settings is refactored to use OptionItemAdapter -->
+<LinearLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:orientation="vertical" >
+ <FrameLayout
+ android:id="@+id/icon_container"
+ android:layout_width="@dimen/option_item_size"
+ android:layout_height="@dimen/option_item_size"
+ android:importantForAccessibility="yes">
+
+ <ImageView
+ android:id="@id/selection_border"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:background="@drawable/option_item_border"
+ android:alpha="0"
+ android:importantForAccessibility="no" />
+
+ <ImageView
+ android:id="@id/background"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:background="@drawable/option_item_background"
+ android:importantForAccessibility="no" />
+
+ <ImageView
+ android:id="@+id/color_preview_0"
+ android:layout_width="@dimen/component_color_chip_small_radius_default2"
+ android:layout_height="@dimen/component_color_chip_small_radius_default2"
+ android:layout_gravity="center"
+ android:layout_marginRight="@dimen/color_seed_chip_margin2"
+ android:layout_marginBottom="@dimen/color_seed_chip_margin2"
+ android:src="@drawable/color_chip_seed_filled0"
+ android:importantForAccessibility="no"/>
+
+ <ImageView
+ android:id="@+id/color_preview_1"
+ android:layout_width="@dimen/component_color_chip_small_radius_default2"
+ android:layout_height="@dimen/component_color_chip_small_radius_default2"
+ android:layout_gravity="center"
+ android:layout_marginLeft="@dimen/color_seed_chip_margin2"
+ android:layout_marginBottom="@dimen/color_seed_chip_margin2"
+ android:src="@drawable/color_chip_seed_filled2"
+ android:importantForAccessibility="no"/>
+
+ <ImageView
+ android:id="@+id/color_preview_2"
+ android:layout_width="@dimen/component_color_chip_small_radius_default2"
+ android:layout_height="@dimen/component_color_chip_small_radius_default2"
+ android:layout_gravity="center"
+ android:layout_marginRight="@dimen/color_seed_chip_margin2"
+ android:layout_marginTop="@dimen/color_seed_chip_margin2"
+ android:src="@drawable/color_chip_seed_filled1"
+ android:importantForAccessibility="no"/>
+
+ <ImageView
+ android:id="@+id/color_preview_3"
+ android:layout_width="@dimen/component_color_chip_small_radius_default2"
+ android:layout_height="@dimen/component_color_chip_small_radius_default2"
+ android:layout_gravity="center"
+ android:layout_marginLeft="@dimen/color_seed_chip_margin2"
+ android:layout_marginTop="@dimen/color_seed_chip_margin2"
+ android:src="@drawable/color_chip_seed_filled3"
+ android:importantForAccessibility="no"/>
+ </FrameLayout>
+
+ <TextView
+ android:id="@+id/option_title"
+ android:layout_width="@dimen/option_tile_width"
+ android:layout_height="wrap_content"
+ android:layout_marginTop="@dimen/option_bottom_margin"
+ android:textColor="@color/text_color_primary"
+ android:visibility="gone"
+ android:gravity="center" />
+</LinearLayout>
diff --git a/res/layout/color_section_view2.xml b/res/layout/color_section_view2.xml
new file mode 100644
index 0000000..687bcef
--- /dev/null
+++ b/res/layout/color_section_view2.xml
@@ -0,0 +1,67 @@
+<?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.ui.view.ColorSectionView2 xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginBottom="@dimen/section_bottom_padding"
+ android:layout_marginHorizontal="@dimen/section_horizontal_padding"
+ android:orientation="vertical"
+ android:background="@drawable/top_connected_section_background">
+
+ <!--
+ 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.
+ -->
+ <LinearLayout
+ android:id="@+id/color_section_option_container"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="horizontal"
+ android:paddingVertical="24dp"
+ android:paddingHorizontal="24dp"
+ android:weightSum="@integer/color_section_num_columns">
+ <include
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ layout="@layout/color_option_overflow_no_background"
+ android:visibility="invisible"
+ android:layout_weight="1"/>
+ </LinearLayout>
+
+ <TextView
+ android:id="@+id/more_colors"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center_horizontal"
+ android:layout_marginTop="10dp"
+ android:minHeight="48dp"
+ android:gravity="center"
+ android:drawablePadding="12dp"
+ android:drawableStart="@drawable/ic_nav_color"
+ android:drawableTint="@color/text_color_primary"
+ android:text="@string/more_colors"
+ android:textAppearance="@android:style/TextAppearance.DeviceDefault.Small"
+ android:textColor="@color/text_color_primary"
+ android:visibility="gone"
+ tools:ignore="UseCompatTextViewDrawableXml" />
+</com.android.customization.picker.color.ui.view.ColorSectionView2>
diff --git a/res/layout/fragment_clock_carousel_demo.xml b/res/layout/fragment_clock_carousel_demo.xml
new file mode 100644
index 0000000..6a54bcb
--- /dev/null
+++ b/res/layout/fragment_clock_carousel_demo.xml
@@ -0,0 +1,35 @@
+<?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.customization.picker.clock.ui.view.ClockCarouselView
+ android:id="@+id/image_carousel_view"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content" />
+</LinearLayout>
\ No newline at end of file
diff --git a/res/layout/fragment_clock_custom_picker_demo.xml b/res/layout/fragment_clock_custom_picker_demo.xml
new file mode 100644
index 0000000..c05c4a8
--- /dev/null
+++ b/res/layout/fragment_clock_custom_picker_demo.xml
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="utf-8"?>
+<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:app="http://schemas.android.com/apk/res-auto"
+ android:orientation="vertical"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent">
+ <FrameLayout
+ android:id="@+id/section_header_container"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ app:layout_constraintBottom_toTopOf="@+id/clock_preview_card_list_demo"
+ app:layout_constraintEnd_toEndOf="parent"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintTop_toTopOf="parent">
+ <include layout="@layout/section_header" />
+ </FrameLayout>
+ <androidx.recyclerview.widget.RecyclerView
+ android:id="@+id/clock_preview_card_list_demo"
+ android:layout_width="match_parent"
+ android:layout_height="0dp"
+ app:layout_constraintBottom_toBottomOf="parent"
+ app:layout_constraintTop_toBottomOf="@+id/section_header_container"
+ android:clipToPadding="false" />
+</androidx.constraintlayout.widget.ConstraintLayout>
\ No newline at end of file
diff --git a/res/layout/fragment_clock_settings.xml b/res/layout/fragment_clock_settings.xml
new file mode 100644
index 0000000..5208222
--- /dev/null
+++ b/res/layout/fragment_clock_settings.xml
@@ -0,0 +1,147 @@
+<?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="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/lock_preview"
+ layout="@layout/wallpaper_preview_card"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:layout_gravity="center" />
+
+ <FrameLayout
+ android:id="@+id/clock_host_view"
+ android:layout_width="match_parent"
+ 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="wrap_content"
+ android:layout_height="wrap_content">
+
+ <androidx.recyclerview.widget.RecyclerView
+ android:id="@+id/tabs"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:clipToPadding="false"
+ android:paddingHorizontal="16dp"
+ android:layout_gravity="center_horizontal" />
+
+ <!--
+ 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>
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:paddingTop="16dp">
+
+ <LinearLayout
+ android:id="@+id/color_picker_container"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical">
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginBottom="16dp">
+
+ <androidx.recyclerview.widget.RecyclerView
+ android:id="@+id/color_options"
+ 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.
+ -->
+ <include
+ layout="@layout/color_option_with_background"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:visibility="invisible" />
+ </FrameLayout>
+
+ <SeekBar
+ android:id="@+id/slider"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center_vertical"
+ android:minHeight="48dp"
+ android:thumb="@null"
+ android:background="@null"
+ android:paddingHorizontal="16dp"
+ android:progressDrawable="@drawable/saturation_progress_drawable"
+ android:splitTrack="false" />
+ </LinearLayout>
+
+ <com.android.customization.picker.clock.ui.view.ClockSizeRadioButtonGroup
+ android:id="@+id/clock_size_radio_button_group"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:paddingHorizontal="16dp" />
+ </FrameLayout>
+ </LinearLayout>
+</LinearLayout>
diff --git a/res/layout/fragment_color_picker.xml b/res/layout/fragment_color_picker.xml
new file mode 100644
index 0000000..7cf94d6
--- /dev/null
+++ b/res/layout/fragment_color_picker.xml
@@ -0,0 +1,150 @@
+<?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="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.DisplayAspectRatioLinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="0dp"
+ android:layout_weight="1"
+ android:layout_marginHorizontal="24dp"
+ android:paddingTop="20dp"
+ android:paddingBottom="40dp"
+ android:orientation="horizontal"
+ android:gravity="center_vertical">
+
+ <include
+ android:id="@+id/lock_preview"
+ layout="@layout/wallpaper_preview_card"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"/>
+
+ <include
+ android:id="@+id/home_preview"
+ layout="@layout/wallpaper_preview_card"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"/>
+ </com.android.wallpaper.picker.DisplayAspectRatioLinearLayout>
+
+ <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:clipChildren="false">
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ >
+
+ <androidx.recyclerview.widget.RecyclerView
+ android:id="@+id/color_type_tabs"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:clipToPadding="false"
+ android:paddingHorizontal="16dp"
+ android:layout_gravity="center_horizontal"/>
+
+ <!--
+ 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="6dp" />
+
+ <TextView
+ android:id="@+id/color_type_tab_subhead"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:textColor="@color/text_color_secondary"
+ android:textSize="12sp"
+ android:gravity="center"
+ android:paddingHorizontal="16dp"/>
+
+ <View
+ android:layout_width="0dp"
+ android:layout_height="8dp" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:clipChildren="false">
+
+ <androidx.recyclerview.widget.RecyclerView
+ android:id="@+id/color_options"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:clipToPadding="false"
+ android:paddingHorizontal="16dp"
+ android:clipChildren="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_2"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:visibility="invisible" />
+
+ </FrameLayout>
+
+ <FrameLayout
+ android:id="@+id/dark_mode_toggle_container"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content" />
+
+ </LinearLayout>
+
+</LinearLayout>
diff --git a/res/layout/fragment_grid.xml b/res/layout/fragment_grid.xml
new file mode 100644
index 0000000..4f0aaef
--- /dev/null
+++ b/res/layout/fragment_grid.xml
@@ -0,0 +1,93 @@
+<?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="match_parent"
+ android:orientation="vertical"
+ android:clipChildren="false">
+
+ <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="20dp"
+ 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:paddingBottom="62dp"
+ android:clipChildren="false">
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:layout_marginTop="22dp"
+ android:clipChildren="false">
+
+ <androidx.recyclerview.widget.RecyclerView
+ android:id="@id/options"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:layout_gravity="center_horizontal"
+ android:clipToPadding="false"
+ android:paddingHorizontal="16dp"
+ android:clipChildren="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/grid_option_2"
+ 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..36d1697 100644
--- a/res/layout/fragment_lock_screen_quick_affordances.xml
+++ b/res/layout/fragment_lock_screen_quick_affordances.xml
@@ -18,7 +18,8 @@
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
- android:orientation="vertical">
+ android:orientation="vertical"
+ android:clipChildren="false">
<FrameLayout
android:id="@+id/section_header_container"
@@ -33,7 +34,7 @@
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
- android:paddingTop="36dp"
+ android:paddingTop="20dp"
android:paddingBottom="40dp">
<include
@@ -51,9 +52,10 @@
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">
+ android:paddingBottom="62dp"
+ android:clipChildren="false">
<FrameLayout
android:layout_width="match_parent"
@@ -62,8 +64,9 @@
<androidx.recyclerview.widget.RecyclerView
android:id="@id/slot_tabs"
- android:layout_width="match_parent"
+ android:layout_width="wrap_content"
android:layout_height="wrap_content"
+ android:layout_gravity="center_horizontal"
android:clipToPadding="false"
android:paddingHorizontal="16dp" />
@@ -77,7 +80,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" />
@@ -90,14 +93,17 @@
<FrameLayout
android:layout_width="match_parent"
- android:layout_height="wrap_content">
+ android:layout_height="wrap_content"
+ android:clipChildren="false">
<androidx.recyclerview.widget.RecyclerView
android:id="@id/affordances"
- android:layout_width="match_parent"
+ android:layout_width="wrap_content"
android:layout_height="wrap_content"
+ android:layout_gravity="center_horizontal"
android:clipToPadding="false"
- android:paddingHorizontal="16dp" />
+ android:paddingHorizontal="16dp"
+ android:clipChildren="false" />
<!--
This is just an invisible placeholder put in place so that the parent keeps its height
diff --git a/res/layout/grid_option_2.xml b/res/layout/grid_option_2.xml
new file mode 100644
index 0000000..a8b453a
--- /dev/null
+++ b/res/layout/grid_option_2.xml
@@ -0,0 +1,70 @@
+<?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:tools="http://schemas.android.com/tools"
+ android:layout_width="@dimen/option_item_size"
+ android:layout_height="wrap_content"
+ android:orientation="vertical"
+ android:gravity="center_horizontal"
+ android:clipChildren="false">
+
+ <FrameLayout
+ android:layout_width="@dimen/option_item_size"
+ android:layout_height="@dimen/option_item_size"
+ android:clipChildren="false">
+
+ <ImageView
+ android:id="@id/selection_border"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:background="@drawable/option_item_border"
+ android:alpha="0"
+ android:importantForAccessibility="no" />
+
+ <ImageView
+ android:id="@id/background"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:background="@drawable/option_item_background"
+ android:importantForAccessibility="no" />
+
+ <ImageView
+ android:id="@id/foreground"
+ android:layout_width="58dp"
+ android:layout_height="58dp"
+ android:layout_gravity="center" />
+
+ </FrameLayout>
+
+ <View
+ android:layout_width="0dp"
+ android:layout_height="8dp" />
+
+ <TextView
+ android:id="@id/text"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:textColor="@color/text_color_primary"
+ android:singleLine="true"
+ android:ellipsize="end"
+ android:text="Placeholder for stable size calculation, please do not remove."
+ tools:ignore="HardcodedText" />
+
+</LinearLayout>
diff --git a/res/layout/grid_preview_card.xml b/res/layout/grid_preview_card.xml
index e333ca7..a2691df 100644
--- a/res/layout/grid_preview_card.xml
+++ b/res/layout/grid_preview_card.xml
@@ -38,4 +38,13 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:importantForAccessibility="noHideDescendants" />
+
+ <ImageView
+ android:id="@+id/grid_fadein_scrim"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:background="?android:colorSecondary"
+ android:forceHasOverlappingRendering="false"
+ android:importantForAccessibility="no"
+ android:visibility="invisible" />
</androidx.cardview.widget.CardView>
diff --git a/res/layout/keyguard_quick_affordance.xml b/res/layout/keyguard_quick_affordance.xml
index b3b6893..1e5c339 100644
--- a/res/layout/keyguard_quick_affordance.xml
+++ b/res/layout/keyguard_quick_affordance.xml
@@ -19,18 +19,34 @@
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
- android:layout_width="@dimen/keyguard_quick_affordance_picker_item_width"
+ android:layout_width="@dimen/option_item_size"
android:layout_height="wrap_content"
android:orientation="vertical"
- android:gravity="center_horizontal">
+ android:gravity="center_horizontal"
+ android:clipChildren="false">
<FrameLayout
- android:id="@+id/icon_container"
- android:layout_width="@dimen/keyguard_quick_affordance_icon_container_size"
- android:layout_height="@dimen/keyguard_quick_affordance_icon_container_size" >
+ android:layout_width="@dimen/option_item_size"
+ android:layout_height="@dimen/option_item_size"
+ android:clipChildren="false">
<ImageView
- android:id="@+id/icon"
+ android:id="@id/selection_border"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:background="@drawable/option_item_border"
+ android:alpha="0"
+ android:importantForAccessibility="no" />
+
+ <ImageView
+ android:id="@id/background"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:background="@drawable/option_item_background"
+ android:importantForAccessibility="no" />
+
+ <ImageView
+ android:id="@id/foreground"
android:layout_width="@dimen/keyguard_quick_affordance_icon_size"
android:layout_height="@dimen/keyguard_quick_affordance_icon_size"
android:layout_gravity="center"
@@ -43,7 +59,7 @@
android:layout_height="8dp" />
<TextView
- android:id="@+id/name"
+ android:id="@id/text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="@color/text_color_primary"
@@ -52,4 +68,4 @@
android:text="Placeholder for stable size calculation, please do not remove."
tools:ignore="HardcodedText" />
-</LinearLayout>
\ No newline at end of file
+</LinearLayout>
diff --git a/res/layout/keyguard_quick_affordance_enablement_dialog.xml b/res/layout/keyguard_quick_affordance_enablement_dialog.xml
deleted file mode 100644
index d6ba105..0000000
--- a/res/layout/keyguard_quick_affordance_enablement_dialog.xml
+++ /dev/null
@@ -1,59 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?><!--
- ~ Copyright (C) 2022 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="wrap_content"
- android:layout_height="wrap_content"
- android:background="@drawable/keyguard_quick_affordance_picker_background"
- android:orientation="vertical"
- android:padding="24dp">
-
- <ImageView
- android:id="@+id/icon"
- android:layout_width="32dp"
- android:layout_height="32dp"
- android:tint="@color/color_accent_primary"
- android:layout_gravity="center_horizontal"
- android:layout_marginBottom="16dp" />
-
- <TextView
- android:id="@+id/title"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:gravity="center"
- android:textAppearance="@style/TextAppearance.MaterialComponents.Headline4"
- android:layout_gravity="center_horizontal"
- android:layout_marginBottom="16dp" />
-
- <TextView
- android:id="@+id/message"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- android:textAppearance="@style/TextAppearance.MaterialComponents.Body1"
- android:layout_gravity="center_horizontal"
- android:layout_marginBottom="38dp" />
-
- <Button
- android:id="@+id/button"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- style="@style/ActionPrimaryButton"
- android:background="@drawable/button_background"
- android:layout_gravity="end" />
-
-</LinearLayout>
diff --git a/res/layout/more_settings_section_view.xml b/res/layout/more_settings_section_view.xml
new file mode 100644
index 0000000..b60bb45
--- /dev/null
+++ b/res/layout/more_settings_section_view.xml
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2022 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.settings.ui.view.MoreSettingsSectionView
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:background="?selectableItemBackground"
+ android:clickable="true"
+ android:paddingVertical="@dimen/section_top_padding"
+ android:paddingHorizontal="@dimen/section_horizontal_padding"
+ android:orientation="vertical">
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="@string/more_settings_section_title"
+ style="@style/SectionTitleTextStyle" />
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="@string/more_settings_section_description"
+ style="@style/SectionSubtitleTextStyle"/>
+
+</com.android.customization.picker.settings.ui.view.MoreSettingsSectionView>
diff --git a/res/layout/notification_section.xml b/res/layout/notification_section.xml
new file mode 100644
index 0000000..713624e
--- /dev/null
+++ b/res/layout/notification_section.xml
@@ -0,0 +1,57 @@
+<?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.notifications.ui.view.NotificationSectionView
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:background="?selectableItemBackground"
+ android:clickable="true"
+ android:paddingVertical="@dimen/section_top_padding"
+ android:paddingHorizontal="@dimen/section_horizontal_padding"
+ android:orientation="horizontal"
+ android:gravity="center_vertical">
+
+ <LinearLayout
+ android:layout_width="0dp"
+ android:layout_height="wrap_content"
+ android:layout_weight="1"
+ android:orientation="vertical">
+
+ <TextView
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:text="@string/notifications_section_title"
+ style="@style/SectionTitleTextStyle" />
+
+ <TextView
+ android:id="@+id/subtitle"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ style="@style/SectionSubtitleTextStyle"/>
+ </LinearLayout>
+
+ <Switch
+ android:id="@+id/switcher"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:clickable="false"
+ style="@style/Switch.SettingsLib"
+ tools:ignore="UseSwitchCompatOrMaterialXml" />
+
+</com.android.customization.picker.notifications.ui.view.NotificationSectionView>
diff --git a/res/layout/keyguard_quick_affordance_slot_tab.xml b/res/layout/picker_fragment_tab.xml
similarity index 84%
rename from res/layout/keyguard_quick_affordance_slot_tab.xml
rename to res/layout/picker_fragment_tab.xml
index c4934d8..2e6e8fa 100644
--- a/res/layout/keyguard_quick_affordance_slot_tab.xml
+++ b/res/layout/picker_fragment_tab.xml
@@ -21,12 +21,14 @@
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:minHeight="36dp"
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."
+ android:maxLines="1"
+ android:ellipsize="end"
tools:ignore="HardcodedText" />
diff --git a/res/layout/single_clock_view.xml b/res/layout/single_clock_view.xml
new file mode 100644
index 0000000..e7ac518
--- /dev/null
+++ b/res/layout/single_clock_view.xml
@@ -0,0 +1,25 @@
+<?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.wallpaper.picker.DisplayAspectRatioFrameLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="@dimen/clock_carousel_item_height">
+ <FrameLayout
+ android:id="@+id/single_clock_host_view"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:layout_gravity="center" />
+</com.android.wallpaper.picker.DisplayAspectRatioFrameLayout>
\ No newline at end of file
diff --git a/res/values-af/strings.xml b/res/values-af/strings.xml
index 6f73a7b..4a6733e 100644
--- a/res/values-af/strings.xml
+++ b/res/values-af/strings.xml
@@ -19,9 +19,7 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_name" msgid="1647136562008520313">"Muurpapier en styl"</string>
<string name="theme_title" msgid="2144932106319405101">"Styl"</string>
- <string name="clock_title" msgid="1974314575211361352">"Gepasmaakte horlosie"</string>
- <string name="clock_description" msgid="3563839327378948">"Kies gepasmaakte horlosie"</string>
- <string name="clock_picker_entry_content_description" msgid="8377139273468595734">"Verander ’n gepasmaakte horlosie"</string>
+ <string name="clock_title" msgid="2126046720254613991">"Horlosie"</string>
<string name="grid_title" msgid="1688173478777254123">"Programrooster"</string>
<string name="apply_theme_btn" msgid="6293081192321303991">"Pas toe"</string>
<string name="edit_custom_theme_lbl" msgid="5211377705710775224">"Tik om te wysig"</string>
@@ -91,15 +89,4 @@
<string name="preset_color_tab" msgid="3133391839341329314">"Basiese kleure"</string>
<string name="color_changed" msgid="7029571720331641235">"Kleur het verander"</string>
<string name="adaptive_color_title" msgid="1336508599235896205">"Dinamies"</string>
- <string name="keyguard_slot_name_bottom_start" msgid="6717374042663171860">"Linkerknoppie"</string>
- <string name="keyguard_slot_name_bottom_end" msgid="7636885379738905151">"Regterknoppie"</string>
- <string name="keyguard_affordance_none" msgid="1751643933430782312">"Geen"</string>
- <string name="keyguard_affordance_enablement_dialog_title" msgid="3389730825561696493">"Merk die volgende as jy “<xliff:g id="APPNAME">%1$s</xliff:g>” wil kies"</string>
- <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8117011931337357438">"Maak <xliff:g id="APPNAME">%1$s</xliff:g> oop"</string>
- <string name="keyguard_affordance_enablement_dialog_message" msgid="6136286758939253570">"Om die <xliff:g id="APPNAME">%1$s</xliff:g>-app as ’n kortpad by te voeg, moet jy seker maak dat"</string>
- <string name="keyguard_affordance_enablement_dialog_dismiss_button" msgid="629754625264422508">"Klaar"</string>
- <string name="keyguard_quick_affordance_title" msgid="4242813186995735584">"Kortpaaie"</string>
- <string name="keyguard_quick_affordance_section_title" msgid="2806304242671717309">"Kortpaaie"</string>
- <string name="keyguard_quick_affordance_two_selected_template" msgid="1757099194522296363">"<xliff:g id="FIRST">%1$s</xliff:g>, <xliff:g id="SECOND">%2$s</xliff:g>"</string>
- <string name="keyguard_quick_affordance_none_selected" msgid="8494127020144112003">"Geen"</string>
</resources>
diff --git a/res/values-am/strings.xml b/res/values-am/strings.xml
index 33cb057..7399eca 100644
--- a/res/values-am/strings.xml
+++ b/res/values-am/strings.xml
@@ -17,11 +17,9 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="1647136562008520313">"ልጣፍ እና ቅጥ"</string>
+ <string name="app_name" msgid="1647136562008520313">"ልጣፍ & ቅጥ"</string>
<string name="theme_title" msgid="2144932106319405101">"ቅጥ"</string>
- <string name="clock_title" msgid="1974314575211361352">"ብጁ ሰዓት"</string>
- <string name="clock_description" msgid="3563839327378948">"ብጁ ሰዓት ይምረጡ"</string>
- <string name="clock_picker_entry_content_description" msgid="8377139273468595734">"ብጁ ሰዓትን ይለውጡ"</string>
+ <string name="clock_title" msgid="2126046720254613991">"ሰዓት"</string>
<string name="grid_title" msgid="1688173478777254123">"የመተግበሪያ ፍርግርግ"</string>
<string name="apply_theme_btn" msgid="6293081192321303991">"ተግብር"</string>
<string name="edit_custom_theme_lbl" msgid="5211377705710775224">"ለማርትዕ መታ ያድርጉ"</string>
@@ -91,15 +89,4 @@
<string name="preset_color_tab" msgid="3133391839341329314">"መሰረታዊ ቀለሞች"</string>
<string name="color_changed" msgid="7029571720331641235">"ቀለም ተቀይሯል"</string>
<string name="adaptive_color_title" msgid="1336508599235896205">"ተለዋዋጭ"</string>
- <string name="keyguard_slot_name_bottom_start" msgid="6717374042663171860">"የግራ አዝራር"</string>
- <string name="keyguard_slot_name_bottom_end" msgid="7636885379738905151">"የቀኝ አዝራር"</string>
- <string name="keyguard_affordance_none" msgid="1751643933430782312">"ምንም"</string>
- <string name="keyguard_affordance_enablement_dialog_title" msgid="3389730825561696493">"«<xliff:g id="APPNAME">%1$s</xliff:g>»ን ለመምረጥ የሚከተሉትን ይፈትሹ"</string>
- <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8117011931337357438">"<xliff:g id="APPNAME">%1$s</xliff:g> ይክፈቱ"</string>
- <string name="keyguard_affordance_enablement_dialog_message" msgid="6136286758939253570">"የ<xliff:g id="APPNAME">%1$s</xliff:g> መተግበሪያን እንደ አቋራጭ ለማከል የሚከተሉትን ማድረግዎን እርግጠኛ ይሁኑ"</string>
- <string name="keyguard_affordance_enablement_dialog_dismiss_button" msgid="629754625264422508">"ተከናውኗል"</string>
- <string name="keyguard_quick_affordance_title" msgid="4242813186995735584">"አቋራጮች"</string>
- <string name="keyguard_quick_affordance_section_title" msgid="2806304242671717309">"አቋራጮች"</string>
- <string name="keyguard_quick_affordance_two_selected_template" msgid="1757099194522296363">"<xliff:g id="FIRST">%1$s</xliff:g>፣ <xliff:g id="SECOND">%2$s</xliff:g>"</string>
- <string name="keyguard_quick_affordance_none_selected" msgid="8494127020144112003">"ምንም"</string>
</resources>
diff --git a/res/values-ar/strings.xml b/res/values-ar/strings.xml
index 0186d7e..ef802d2 100644
--- a/res/values-ar/strings.xml
+++ b/res/values-ar/strings.xml
@@ -17,11 +17,9 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="1647136562008520313">"الخلفية والأسلوب"</string>
+ <string name="app_name" msgid="1647136562008520313">"الخلفية والنمط"</string>
<string name="theme_title" msgid="2144932106319405101">"النمط"</string>
- <string name="clock_title" msgid="1974314575211361352">"خلفية شاشة ساعة مخصّصة"</string>
- <string name="clock_description" msgid="3563839327378948">"اختيار خلفية شاشة ساعة مخصّصة"</string>
- <string name="clock_picker_entry_content_description" msgid="8377139273468595734">"تغيير خلفية شاشة ساعة مخصّصة"</string>
+ <string name="clock_title" msgid="2126046720254613991">"الساعة"</string>
<string name="grid_title" msgid="1688173478777254123">"شبكة التطبيقات"</string>
<string name="apply_theme_btn" msgid="6293081192321303991">"تطبيق"</string>
<string name="edit_custom_theme_lbl" msgid="5211377705710775224">"انقُر للتعديل."</string>
@@ -91,15 +89,4 @@
<string name="preset_color_tab" msgid="3133391839341329314">"الألوان الأساسية"</string>
<string name="color_changed" msgid="7029571720331641235">"تم تغيير اللون."</string>
<string name="adaptive_color_title" msgid="1336508599235896205">"ألوان ديناميكية"</string>
- <string name="keyguard_slot_name_bottom_start" msgid="6717374042663171860">"الزر الأيسر"</string>
- <string name="keyguard_slot_name_bottom_end" msgid="7636885379738905151">"الزر الأيمن"</string>
- <string name="keyguard_affordance_none" msgid="1751643933430782312">"بدون أزرار"</string>
- <string name="keyguard_affordance_enablement_dialog_title" msgid="3389730825561696493">"لاختيار \"<xliff:g id="APPNAME">%1$s</xliff:g>\"، تأكّد مما يلي:"</string>
- <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8117011931337357438">"فتح <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
- <string name="keyguard_affordance_enablement_dialog_message" msgid="6136286758939253570">"لإضافة تطبيق \"<xliff:g id="APPNAME">%1$s</xliff:g>\" كاختصار، تأكَّد من"</string>
- <string name="keyguard_affordance_enablement_dialog_dismiss_button" msgid="629754625264422508">"تم"</string>
- <string name="keyguard_quick_affordance_title" msgid="4242813186995735584">"الاختصارات"</string>
- <string name="keyguard_quick_affordance_section_title" msgid="2806304242671717309">"الاختصارات"</string>
- <string name="keyguard_quick_affordance_two_selected_template" msgid="1757099194522296363">"\"<xliff:g id="FIRST">%1$s</xliff:g>\" و\"<xliff:g id="SECOND">%2$s</xliff:g>\""</string>
- <string name="keyguard_quick_affordance_none_selected" msgid="8494127020144112003">"بدون اختصارات"</string>
</resources>
diff --git a/res/values-as/strings.xml b/res/values-as/strings.xml
index c0106bd..81c77f0 100644
--- a/res/values-as/strings.xml
+++ b/res/values-as/strings.xml
@@ -19,9 +19,7 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_name" msgid="1647136562008520313">"ৱালপেপাৰ আৰু শৈলী"</string>
<string name="theme_title" msgid="2144932106319405101">"শৈলী"</string>
- <string name="clock_title" msgid="1974314575211361352">"কাষ্টম ঘড়ী"</string>
- <string name="clock_description" msgid="3563839327378948">"কাষ্টম ঘড়ী বাছক"</string>
- <string name="clock_picker_entry_content_description" msgid="8377139273468595734">"কাষ্টম ঘড়ী সলনি কৰক"</string>
+ <string name="clock_title" msgid="2126046720254613991">"ঘড়ী"</string>
<string name="grid_title" msgid="1688173478777254123">"এপৰ গ্ৰিড"</string>
<string name="apply_theme_btn" msgid="6293081192321303991">"প্ৰয়োগ কৰক"</string>
<string name="edit_custom_theme_lbl" msgid="5211377705710775224">"সম্পাদনা কৰিবলৈ টিপক"</string>
@@ -44,7 +42,7 @@
<string name="preview_name_shape" msgid="5676971146080968721">"আকৃতি"</string>
<string name="preview_name_wallpaper" msgid="1738652462949531828">"ৱালপেপাৰ"</string>
<string name="font_card_title" msgid="2343292653502548685">"ABC • abc • 123"</string>
- <string name="font_card_body" msgid="6790525594503904468">"প্ৰত্যেকখন স্ক্ৰীনত আপোনাৰ প্ৰিয় ফ’ণ্ট যোগ দিয়ক"</string>
+ <string name="font_card_body" msgid="6790525594503904468">"প্ৰত্যেকখন স্ক্ৰীণত আপোনাৰ প্ৰিয় ফণ্ট যোগ কৰক"</string>
<string name="grid_options_title" msgid="7071930966989877023">"এটা গ্ৰিডৰ আকাৰ বাছনি কৰক"</string>
<string name="grid_title_pattern" msgid="9188866567612607806">"<xliff:g id="ID_1">%1$d</xliff:g>x<xliff:g id="ID_2">%2$d</xliff:g>"</string>
<string name="applied_theme_msg" msgid="3749018706366796244">"শৈলী সফলতাৰে ছেট কৰা হ’ল"</string>
@@ -91,15 +89,4 @@
<string name="preset_color_tab" msgid="3133391839341329314">"প্ৰাথমিক ৰং"</string>
<string name="color_changed" msgid="7029571720331641235">"ৰং সলনি কৰা হৈছে"</string>
<string name="adaptive_color_title" msgid="1336508599235896205">"ডাইনামিক"</string>
- <string name="keyguard_slot_name_bottom_start" msgid="6717374042663171860">"বাওঁফালৰ বুটাম"</string>
- <string name="keyguard_slot_name_bottom_end" msgid="7636885379738905151">"সোঁফালৰ বুটাম"</string>
- <string name="keyguard_affordance_none" msgid="1751643933430782312">"নাই"</string>
- <string name="keyguard_affordance_enablement_dialog_title" msgid="3389730825561696493">"`<xliff:g id="APPNAME">%1$s</xliff:g>` বাছনি কৰিবলৈ এয়া পৰীক্ষা কৰক"</string>
- <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8117011931337357438">"<xliff:g id="APPNAME">%1$s</xliff:g> খোলক"</string>
- <string name="keyguard_affordance_enablement_dialog_message" msgid="6136286758939253570">"<xliff:g id="APPNAME">%1$s</xliff:g> এপ্টোক এটা শ্বৰ্টকাট হিচাপে যোগ দিবলৈ, এইকেইটা কথা নিশ্চিত কৰক"</string>
- <string name="keyguard_affordance_enablement_dialog_dismiss_button" msgid="629754625264422508">"কৰা হ’ল"</string>
- <string name="keyguard_quick_affordance_title" msgid="4242813186995735584">"শ্বৰ্টকাট"</string>
- <string name="keyguard_quick_affordance_section_title" msgid="2806304242671717309">"শ্বৰ্টকাট"</string>
- <string name="keyguard_quick_affordance_two_selected_template" msgid="1757099194522296363">"<xliff:g id="FIRST">%1$s</xliff:g>, <xliff:g id="SECOND">%2$s</xliff:g>"</string>
- <string name="keyguard_quick_affordance_none_selected" msgid="8494127020144112003">"নাই"</string>
</resources>
diff --git a/res/values-az/strings.xml b/res/values-az/strings.xml
index 7ab4454..2d8209b 100644
--- a/res/values-az/strings.xml
+++ b/res/values-az/strings.xml
@@ -19,9 +19,7 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_name" msgid="1647136562008520313">"Divar kağızı və üslub"</string>
<string name="theme_title" msgid="2144932106319405101">"Üslub"</string>
- <string name="clock_title" msgid="1974314575211361352">"Fərdi Saat"</string>
- <string name="clock_description" msgid="3563839327378948">"Fərdi saat seç"</string>
- <string name="clock_picker_entry_content_description" msgid="8377139273468595734">"Fərdi saatı dəyişdir"</string>
+ <string name="clock_title" msgid="2126046720254613991">"Saat"</string>
<string name="grid_title" msgid="1688173478777254123">"Tətbiq toru"</string>
<string name="apply_theme_btn" msgid="6293081192321303991">"Tətbiq edin"</string>
<string name="edit_custom_theme_lbl" msgid="5211377705710775224">"Redaktə etmək üçün klikləyin"</string>
@@ -91,15 +89,4 @@
<string name="preset_color_tab" msgid="3133391839341329314">"Əsas rənglər"</string>
<string name="color_changed" msgid="7029571720331641235">"Rəng dəyişdirildi"</string>
<string name="adaptive_color_title" msgid="1336508599235896205">"Dinamik"</string>
- <string name="keyguard_slot_name_bottom_start" msgid="6717374042663171860">"Sol düymə"</string>
- <string name="keyguard_slot_name_bottom_end" msgid="7636885379738905151">"Sağ düymə"</string>
- <string name="keyguard_affordance_none" msgid="1751643933430782312">"Heç biri"</string>
- <string name="keyguard_affordance_enablement_dialog_title" msgid="3389730825561696493">"\"<xliff:g id="APPNAME">%1$s</xliff:g>\" seçmək üçün aşağıdakıları yoxlayın"</string>
- <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8117011931337357438">"<xliff:g id="APPNAME">%1$s</xliff:g> linkini açın"</string>
- <string name="keyguard_affordance_enablement_dialog_message" msgid="6136286758939253570">"<xliff:g id="APPNAME">%1$s</xliff:g> tətbiqini qısayol kimi əlavə etmək üçün bunları təmin edin:"</string>
- <string name="keyguard_affordance_enablement_dialog_dismiss_button" msgid="629754625264422508">"Hazırdır"</string>
- <string name="keyguard_quick_affordance_title" msgid="4242813186995735584">"Qısayollar"</string>
- <string name="keyguard_quick_affordance_section_title" msgid="2806304242671717309">"Qısayollar"</string>
- <string name="keyguard_quick_affordance_two_selected_template" msgid="1757099194522296363">"<xliff:g id="FIRST">%1$s</xliff:g>, <xliff:g id="SECOND">%2$s</xliff:g>"</string>
- <string name="keyguard_quick_affordance_none_selected" msgid="8494127020144112003">"Heç biri"</string>
</resources>
diff --git a/res/values-b+sr+Latn/strings.xml b/res/values-b+sr+Latn/strings.xml
index cfc988f..d8aacd6 100644
--- a/res/values-b+sr+Latn/strings.xml
+++ b/res/values-b+sr+Latn/strings.xml
@@ -19,9 +19,7 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_name" msgid="1647136562008520313">"Pozadina i stil"</string>
<string name="theme_title" msgid="2144932106319405101">"Stil"</string>
- <string name="clock_title" msgid="1974314575211361352">"Prilagođeni sat"</string>
- <string name="clock_description" msgid="3563839327378948">"Prilagođeni sat"</string>
- <string name="clock_picker_entry_content_description" msgid="8377139273468595734">"Promenite prilagođeni sat"</string>
+ <string name="clock_title" msgid="2126046720254613991">"Sat"</string>
<string name="grid_title" msgid="1688173478777254123">"Mreža apl."</string>
<string name="apply_theme_btn" msgid="6293081192321303991">"Primeni"</string>
<string name="edit_custom_theme_lbl" msgid="5211377705710775224">"Dodirnite da biste izmenili"</string>
@@ -91,15 +89,4 @@
<string name="preset_color_tab" msgid="3133391839341329314">"Osnovne boje"</string>
<string name="color_changed" msgid="7029571720331641235">"Boja je promenjena"</string>
<string name="adaptive_color_title" msgid="1336508599235896205">"Dinamički"</string>
- <string name="keyguard_slot_name_bottom_start" msgid="6717374042663171860">"Levo dugme"</string>
- <string name="keyguard_slot_name_bottom_end" msgid="7636885379738905151">"Desno dugme"</string>
- <string name="keyguard_affordance_none" msgid="1751643933430782312">"Ništa"</string>
- <string name="keyguard_affordance_enablement_dialog_title" msgid="3389730825561696493">"Da biste izabrali „<xliff:g id="APPNAME">%1$s</xliff:g>“, proverite sledeće"</string>
- <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8117011931337357438">"Otvorite: <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
- <string name="keyguard_affordance_enablement_dialog_message" msgid="6136286758939253570">"Da biste dodali aplikaciju <xliff:g id="APPNAME">%1$s</xliff:g> kao prečicu, uverite se"</string>
- <string name="keyguard_affordance_enablement_dialog_dismiss_button" msgid="629754625264422508">"Gotovo"</string>
- <string name="keyguard_quick_affordance_title" msgid="4242813186995735584">"Prečice"</string>
- <string name="keyguard_quick_affordance_section_title" msgid="2806304242671717309">"Prečice"</string>
- <string name="keyguard_quick_affordance_two_selected_template" msgid="1757099194522296363">"<xliff:g id="FIRST">%1$s</xliff:g>, <xliff:g id="SECOND">%2$s</xliff:g>"</string>
- <string name="keyguard_quick_affordance_none_selected" msgid="8494127020144112003">"Ništa"</string>
</resources>
diff --git a/res/values-be/strings.xml b/res/values-be/strings.xml
index 7c75af1..4151478 100644
--- a/res/values-be/strings.xml
+++ b/res/values-be/strings.xml
@@ -19,9 +19,7 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_name" msgid="1647136562008520313">"Шпалеры і стыль"</string>
<string name="theme_title" msgid="2144932106319405101">"Стыль"</string>
- <string name="clock_title" msgid="1974314575211361352">"Гадзіннік"</string>
- <string name="clock_description" msgid="3563839327378948">"Выбар цыферблата"</string>
- <string name="clock_picker_entry_content_description" msgid="8377139273468595734">"Змяненне цыферблата"</string>
+ <string name="clock_title" msgid="2126046720254613991">"Гадзіннік"</string>
<string name="grid_title" msgid="1688173478777254123">"Сетка праграм"</string>
<string name="apply_theme_btn" msgid="6293081192321303991">"Ужыць"</string>
<string name="edit_custom_theme_lbl" msgid="5211377705710775224">"Дакраніцеся, каб рэдагаваць"</string>
@@ -91,15 +89,4 @@
<string name="preset_color_tab" msgid="3133391839341329314">"Асноўныя колеры"</string>
<string name="color_changed" msgid="7029571720331641235">"Колер зменены"</string>
<string name="adaptive_color_title" msgid="1336508599235896205">"Дынамічны"</string>
- <string name="keyguard_slot_name_bottom_start" msgid="6717374042663171860">"Левая кнопка"</string>
- <string name="keyguard_slot_name_bottom_end" msgid="7636885379738905151">"Правая кнопка"</string>
- <string name="keyguard_affordance_none" msgid="1751643933430782312">"Няма"</string>
- <string name="keyguard_affordance_enablement_dialog_title" msgid="3389730825561696493">"Каб выбраць праграму \"<xliff:g id="APPNAME">%1$s</xliff:g>\", зрабіце наступнае"</string>
- <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8117011931337357438">"Адкрыць \"<xliff:g id="APPNAME">%1$s</xliff:g>\""</string>
- <string name="keyguard_affordance_enablement_dialog_message" msgid="6136286758939253570">"Каб дадаць ярлык для праграмы \"<xliff:g id="APPNAME">%1$s</xliff:g>\", патрабуюцца наступныя ўмовы:"</string>
- <string name="keyguard_affordance_enablement_dialog_dismiss_button" msgid="629754625264422508">"Гатова"</string>
- <string name="keyguard_quick_affordance_title" msgid="4242813186995735584">"Ярлыкі"</string>
- <string name="keyguard_quick_affordance_section_title" msgid="2806304242671717309">"Ярлыкі"</string>
- <string name="keyguard_quick_affordance_two_selected_template" msgid="1757099194522296363">"<xliff:g id="FIRST">%1$s</xliff:g>, <xliff:g id="SECOND">%2$s</xliff:g>"</string>
- <string name="keyguard_quick_affordance_none_selected" msgid="8494127020144112003">"Няма"</string>
</resources>
diff --git a/res/values-bg/strings.xml b/res/values-bg/strings.xml
index 898aab8..849af69 100644
--- a/res/values-bg/strings.xml
+++ b/res/values-bg/strings.xml
@@ -19,9 +19,7 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_name" msgid="1647136562008520313">"Тапет и стил"</string>
<string name="theme_title" msgid="2144932106319405101">"Стил"</string>
- <string name="clock_title" msgid="1974314575211361352">"Персонал. циферблат"</string>
- <string name="clock_description" msgid="3563839327378948">"Персон. циферблат: Избор"</string>
- <string name="clock_picker_entry_content_description" msgid="8377139273468595734">"Промяна на персонализиран циферблат"</string>
+ <string name="clock_title" msgid="2126046720254613991">"Часовник"</string>
<string name="grid_title" msgid="1688173478777254123">"Решетка с прил."</string>
<string name="apply_theme_btn" msgid="6293081192321303991">"Прилагане"</string>
<string name="edit_custom_theme_lbl" msgid="5211377705710775224">"Докоснете, за да редактирате"</string>
@@ -91,15 +89,4 @@
<string name="preset_color_tab" msgid="3133391839341329314">"Основни цветове"</string>
<string name="color_changed" msgid="7029571720331641235">"Цветът бе променен"</string>
<string name="adaptive_color_title" msgid="1336508599235896205">"Динамично"</string>
- <string name="keyguard_slot_name_bottom_start" msgid="6717374042663171860">"Ляв бутон"</string>
- <string name="keyguard_slot_name_bottom_end" msgid="7636885379738905151">"Десен бутон"</string>
- <string name="keyguard_affordance_none" msgid="1751643933430782312">"Без"</string>
- <string name="keyguard_affordance_enablement_dialog_title" msgid="3389730825561696493">"За да изберете <xliff:g id="APPNAME">%1$s</xliff:g>, проверете следното:"</string>
- <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8117011931337357438">"Отваряне на <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
- <string name="keyguard_affordance_enablement_dialog_message" msgid="6136286758939253570">"За да добавите пряк път към приложението <xliff:g id="APPNAME">%1$s</xliff:g>, трябва да се уверите в следното:"</string>
- <string name="keyguard_affordance_enablement_dialog_dismiss_button" msgid="629754625264422508">"Готово"</string>
- <string name="keyguard_quick_affordance_title" msgid="4242813186995735584">"Преки пътища"</string>
- <string name="keyguard_quick_affordance_section_title" msgid="2806304242671717309">"Преки пътища"</string>
- <string name="keyguard_quick_affordance_two_selected_template" msgid="1757099194522296363">"<xliff:g id="FIRST">%1$s</xliff:g>, <xliff:g id="SECOND">%2$s</xliff:g>"</string>
- <string name="keyguard_quick_affordance_none_selected" msgid="8494127020144112003">"Няма"</string>
</resources>
diff --git a/res/values-bn/strings.xml b/res/values-bn/strings.xml
index 7d8cea7..b1c9abe 100644
--- a/res/values-bn/strings.xml
+++ b/res/values-bn/strings.xml
@@ -19,9 +19,7 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_name" msgid="1647136562008520313">"ওয়ালপেপার এবং স্টাইল"</string>
<string name="theme_title" msgid="2144932106319405101">"স্টাইল"</string>
- <string name="clock_title" msgid="1974314575211361352">"কাস্টম ঘড়ি"</string>
- <string name="clock_description" msgid="3563839327378948">"কাস্টম ঘড়ি বেছে নিন"</string>
- <string name="clock_picker_entry_content_description" msgid="8377139273468595734">"কাস্টম ঘড়ি পরিবর্তন করুন"</string>
+ <string name="clock_title" msgid="2126046720254613991">"ঘড়ি"</string>
<string name="grid_title" msgid="1688173478777254123">"অ্যাপ গ্রিড"</string>
<string name="apply_theme_btn" msgid="6293081192321303991">"প্রয়োগ করুন"</string>
<string name="edit_custom_theme_lbl" msgid="5211377705710775224">"এডিট করতে ট্যাপ করুন"</string>
@@ -91,15 +89,4 @@
<string name="preset_color_tab" msgid="3133391839341329314">"প্রাথমিক রঙ"</string>
<string name="color_changed" msgid="7029571720331641235">"রঙ পরিবর্তন করা হয়েছে"</string>
<string name="adaptive_color_title" msgid="1336508599235896205">"ডায়নামিক"</string>
- <string name="keyguard_slot_name_bottom_start" msgid="6717374042663171860">"বাঁদিকের বোতাম"</string>
- <string name="keyguard_slot_name_bottom_end" msgid="7636885379738905151">"ডানদিকের বোতাম"</string>
- <string name="keyguard_affordance_none" msgid="1751643933430782312">"কোনওটিই নয়"</string>
- <string name="keyguard_affordance_enablement_dialog_title" msgid="3389730825561696493">"`<xliff:g id="APPNAME">%1$s</xliff:g>` বেছে নিতে, এগুলি চেক করুন"</string>
- <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8117011931337357438">"<xliff:g id="APPNAME">%1$s</xliff:g> খুলুন"</string>
- <string name="keyguard_affordance_enablement_dialog_message" msgid="6136286758939253570">"শর্টকাট হিসেবে <xliff:g id="APPNAME">%1$s</xliff:g> অ্যাপ যোগ করতে, এইসব বিষয় নিশ্চিত করতে হবে"</string>
- <string name="keyguard_affordance_enablement_dialog_dismiss_button" msgid="629754625264422508">"হয়ে গেছে"</string>
- <string name="keyguard_quick_affordance_title" msgid="4242813186995735584">"শর্টকাট"</string>
- <string name="keyguard_quick_affordance_section_title" msgid="2806304242671717309">"শর্টকাট"</string>
- <string name="keyguard_quick_affordance_two_selected_template" msgid="1757099194522296363">"<xliff:g id="FIRST">%1$s</xliff:g>, <xliff:g id="SECOND">%2$s</xliff:g>"</string>
- <string name="keyguard_quick_affordance_none_selected" msgid="8494127020144112003">"কোনও শর্টকাট নেই"</string>
</resources>
diff --git a/res/values-bs/strings.xml b/res/values-bs/strings.xml
index edff91b..11c4587 100644
--- a/res/values-bs/strings.xml
+++ b/res/values-bs/strings.xml
@@ -19,9 +19,7 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_name" msgid="1647136562008520313">"Pozadinska slika i stil"</string>
<string name="theme_title" msgid="2144932106319405101">"Stil"</string>
- <string name="clock_title" msgid="1974314575211361352">"Prilagođeni sat"</string>
- <string name="clock_description" msgid="3563839327378948">"Odabir prilagođ. sata"</string>
- <string name="clock_picker_entry_content_description" msgid="8377139273468595734">"Promijenite prilagođeni sat"</string>
+ <string name="clock_title" msgid="2126046720254613991">"Sat"</string>
<string name="grid_title" msgid="1688173478777254123">"Mreža aplikacija"</string>
<string name="apply_theme_btn" msgid="6293081192321303991">"Primijeni"</string>
<string name="edit_custom_theme_lbl" msgid="5211377705710775224">"Dodirnite da uredite"</string>
@@ -91,15 +89,4 @@
<string name="preset_color_tab" msgid="3133391839341329314">"Osnovne boje"</string>
<string name="color_changed" msgid="7029571720331641235">"Boja je promijenjena"</string>
<string name="adaptive_color_title" msgid="1336508599235896205">"Dinamički"</string>
- <string name="keyguard_slot_name_bottom_start" msgid="6717374042663171860">"Lijevo dugme"</string>
- <string name="keyguard_slot_name_bottom_end" msgid="7636885379738905151">"Desno dugme"</string>
- <string name="keyguard_affordance_none" msgid="1751643933430782312">"Ništa"</string>
- <string name="keyguard_affordance_enablement_dialog_title" msgid="3389730825561696493">"Da odaberete aplikaciju \"<xliff:g id="APPNAME">%1$s</xliff:g>\" provjerite sljedeće"</string>
- <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8117011931337357438">"Otvori aplikaciju <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
- <string name="keyguard_affordance_enablement_dialog_message" msgid="6136286758939253570">"Da dodate aplikaciju <xliff:g id="APPNAME">%1$s</xliff:g> kao prečicu, pobrinite se za sljedeće"</string>
- <string name="keyguard_affordance_enablement_dialog_dismiss_button" msgid="629754625264422508">"Gotovo"</string>
- <string name="keyguard_quick_affordance_title" msgid="4242813186995735584">"Prečice"</string>
- <string name="keyguard_quick_affordance_section_title" msgid="2806304242671717309">"Prečice"</string>
- <string name="keyguard_quick_affordance_two_selected_template" msgid="1757099194522296363">"<xliff:g id="FIRST">%1$s</xliff:g>, <xliff:g id="SECOND">%2$s</xliff:g>"</string>
- <string name="keyguard_quick_affordance_none_selected" msgid="8494127020144112003">"Ništa"</string>
</resources>
diff --git a/res/values-ca/strings.xml b/res/values-ca/strings.xml
index 3cfcce6..f9a3a33 100644
--- a/res/values-ca/strings.xml
+++ b/res/values-ca/strings.xml
@@ -19,9 +19,7 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_name" msgid="1647136562008520313">"Estil i fons de pantalla"</string>
<string name="theme_title" msgid="2144932106319405101">"Estil"</string>
- <string name="clock_title" msgid="1974314575211361352">"Rellotge pers."</string>
- <string name="clock_description" msgid="3563839327378948">"Tria rellotge pers."</string>
- <string name="clock_picker_entry_content_description" msgid="8377139273468595734">"Canvia un rellotge personalitzat"</string>
+ <string name="clock_title" msgid="2126046720254613991">"Rellotge"</string>
<string name="grid_title" msgid="1688173478777254123">"Quadrícula d\'apps"</string>
<string name="apply_theme_btn" msgid="6293081192321303991">"Aplica"</string>
<string name="edit_custom_theme_lbl" msgid="5211377705710775224">"Toca per editar"</string>
@@ -91,15 +89,4 @@
<string name="preset_color_tab" msgid="3133391839341329314">"Colors bàsics"</string>
<string name="color_changed" msgid="7029571720331641235">"S\'ha canviat el color"</string>
<string name="adaptive_color_title" msgid="1336508599235896205">"Dinàmic"</string>
- <string name="keyguard_slot_name_bottom_start" msgid="6717374042663171860">"Botó esquerre"</string>
- <string name="keyguard_slot_name_bottom_end" msgid="7636885379738905151">"Botó dret"</string>
- <string name="keyguard_affordance_none" msgid="1751643933430782312">"Cap"</string>
- <string name="keyguard_affordance_enablement_dialog_title" msgid="3389730825561696493">"Per seleccionar <xliff:g id="APPNAME">%1$s</xliff:g>, comprova el següent"</string>
- <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8117011931337357438">"Obre <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
- <string name="keyguard_affordance_enablement_dialog_message" msgid="6136286758939253570">"Per afegir l\'aplicació <xliff:g id="APPNAME">%1$s</xliff:g> com a drecera, assegura\'t que:"</string>
- <string name="keyguard_affordance_enablement_dialog_dismiss_button" msgid="629754625264422508">"Fet"</string>
- <string name="keyguard_quick_affordance_title" msgid="4242813186995735584">"Dreceres"</string>
- <string name="keyguard_quick_affordance_section_title" msgid="2806304242671717309">"Dreceres"</string>
- <string name="keyguard_quick_affordance_two_selected_template" msgid="1757099194522296363">"<xliff:g id="FIRST">%1$s</xliff:g>, <xliff:g id="SECOND">%2$s</xliff:g>"</string>
- <string name="keyguard_quick_affordance_none_selected" msgid="8494127020144112003">"Cap"</string>
</resources>
diff --git a/res/values-cs/strings.xml b/res/values-cs/strings.xml
index 43f3c4d..3bdbe89 100644
--- a/res/values-cs/strings.xml
+++ b/res/values-cs/strings.xml
@@ -19,9 +19,7 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_name" msgid="1647136562008520313">"Tapeta a styl"</string>
<string name="theme_title" msgid="2144932106319405101">"Styl"</string>
- <string name="clock_title" msgid="1974314575211361352">"Vlastní hodiny"</string>
- <string name="clock_description" msgid="3563839327378948">"Výběr vlastních hodin"</string>
- <string name="clock_picker_entry_content_description" msgid="8377139273468595734">"Změna vlastních hodin"</string>
+ <string name="clock_title" msgid="2126046720254613991">"Hodiny"</string>
<string name="grid_title" msgid="1688173478777254123">"Mřížka aplikací"</string>
<string name="apply_theme_btn" msgid="6293081192321303991">"Použít"</string>
<string name="edit_custom_theme_lbl" msgid="5211377705710775224">"Klepnutím upravte"</string>
@@ -91,15 +89,4 @@
<string name="preset_color_tab" msgid="3133391839341329314">"Základní barvy"</string>
<string name="color_changed" msgid="7029571720331641235">"Barva byla změněna"</string>
<string name="adaptive_color_title" msgid="1336508599235896205">"Dynamické"</string>
- <string name="keyguard_slot_name_bottom_start" msgid="6717374042663171860">"Levé tlačítko"</string>
- <string name="keyguard_slot_name_bottom_end" msgid="7636885379738905151">"Pravé tlačítko"</string>
- <string name="keyguard_affordance_none" msgid="1751643933430782312">"Žádné"</string>
- <string name="keyguard_affordance_enablement_dialog_title" msgid="3389730825561696493">"Aby bylo možné vybrat aplikaci <xliff:g id="APPNAME">%1$s</xliff:g>, zkontrolujte následující"</string>
- <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8117011931337357438">"Otevřít aplikaci <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
- <string name="keyguard_affordance_enablement_dialog_message" msgid="6136286758939253570">"Podmínky pro to, aby aplikaci <xliff:g id="APPNAME">%1$s</xliff:g> bylo možné přidat jako zkratku:"</string>
- <string name="keyguard_affordance_enablement_dialog_dismiss_button" msgid="629754625264422508">"Hotovo"</string>
- <string name="keyguard_quick_affordance_title" msgid="4242813186995735584">"Zástupci"</string>
- <string name="keyguard_quick_affordance_section_title" msgid="2806304242671717309">"Zástupci"</string>
- <string name="keyguard_quick_affordance_two_selected_template" msgid="1757099194522296363">"<xliff:g id="FIRST">%1$s</xliff:g>, <xliff:g id="SECOND">%2$s</xliff:g>"</string>
- <string name="keyguard_quick_affordance_none_selected" msgid="8494127020144112003">"Žádné"</string>
</resources>
diff --git a/res/values-da/strings.xml b/res/values-da/strings.xml
index 1254892..68fe7b3 100644
--- a/res/values-da/strings.xml
+++ b/res/values-da/strings.xml
@@ -19,9 +19,7 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_name" msgid="1647136562008520313">"Baggrund og stil"</string>
<string name="theme_title" msgid="2144932106319405101">"Stil"</string>
- <string name="clock_title" msgid="1974314575211361352">"Tilpasset ur"</string>
- <string name="clock_description" msgid="3563839327378948">"Vælg tilpasset ur"</string>
- <string name="clock_picker_entry_content_description" msgid="8377139273468595734">"Juster et tilpasset ur"</string>
+ <string name="clock_title" msgid="2126046720254613991">"Ur"</string>
<string name="grid_title" msgid="1688173478777254123">"Appgitter"</string>
<string name="apply_theme_btn" msgid="6293081192321303991">"Anvend"</string>
<string name="edit_custom_theme_lbl" msgid="5211377705710775224">"Tryk for at redigere"</string>
@@ -91,15 +89,4 @@
<string name="preset_color_tab" msgid="3133391839341329314">"Standardfarver"</string>
<string name="color_changed" msgid="7029571720331641235">"Farven er ændret"</string>
<string name="adaptive_color_title" msgid="1336508599235896205">"Dynamisk"</string>
- <string name="keyguard_slot_name_bottom_start" msgid="6717374042663171860">"Venstre knap"</string>
- <string name="keyguard_slot_name_bottom_end" msgid="7636885379738905151">"Højre knap"</string>
- <string name="keyguard_affordance_none" msgid="1751643933430782312">"Ingen"</string>
- <string name="keyguard_affordance_enablement_dialog_title" msgid="3389730825561696493">"Hvis du vil vælge \"<xliff:g id="APPNAME">%1$s</xliff:g>\", skal du tjekke følgende"</string>
- <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8117011931337357438">"Åbn <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
- <string name="keyguard_affordance_enablement_dialog_message" msgid="6136286758939253570">"Før du tilføjer <xliff:g id="APPNAME">%1$s</xliff:g>-appen som en genvej, skal du sørge for følgende:"</string>
- <string name="keyguard_affordance_enablement_dialog_dismiss_button" msgid="629754625264422508">"Udfør"</string>
- <string name="keyguard_quick_affordance_title" msgid="4242813186995735584">"Genveje"</string>
- <string name="keyguard_quick_affordance_section_title" msgid="2806304242671717309">"Genveje"</string>
- <string name="keyguard_quick_affordance_two_selected_template" msgid="1757099194522296363">"<xliff:g id="FIRST">%1$s</xliff:g>, <xliff:g id="SECOND">%2$s</xliff:g>"</string>
- <string name="keyguard_quick_affordance_none_selected" msgid="8494127020144112003">"Ingen"</string>
</resources>
diff --git a/res/values-de/strings.xml b/res/values-de/strings.xml
index bb95b3d..c55bffb 100644
--- a/res/values-de/strings.xml
+++ b/res/values-de/strings.xml
@@ -19,9 +19,7 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_name" msgid="1647136562008520313">"Hintergrund & Stil"</string>
<string name="theme_title" msgid="2144932106319405101">"Design"</string>
- <string name="clock_title" msgid="1974314575211361352">"Benutzerdefinierte Uhr"</string>
- <string name="clock_description" msgid="3563839327378948">"Benutzerdefinierte Uhr wählen"</string>
- <string name="clock_picker_entry_content_description" msgid="8377139273468595734">"Benutzerdefinierte Uhr ändern"</string>
+ <string name="clock_title" msgid="2126046720254613991">"Uhr"</string>
<string name="grid_title" msgid="1688173478777254123">"App-Raster"</string>
<string name="apply_theme_btn" msgid="6293081192321303991">"Anwenden"</string>
<string name="edit_custom_theme_lbl" msgid="5211377705710775224">"Zum Bearbeiten tippen"</string>
@@ -91,15 +89,4 @@
<string name="preset_color_tab" msgid="3133391839341329314">"Standardfarben"</string>
<string name="color_changed" msgid="7029571720331641235">"Farbe geändert"</string>
<string name="adaptive_color_title" msgid="1336508599235896205">"Dynamisch"</string>
- <string name="keyguard_slot_name_bottom_start" msgid="6717374042663171860">"Linke Taste"</string>
- <string name="keyguard_slot_name_bottom_end" msgid="7636885379738905151">"Rechte Taste"</string>
- <string name="keyguard_affordance_none" msgid="1751643933430782312">"Keine"</string>
- <string name="keyguard_affordance_enablement_dialog_title" msgid="3389730825561696493">"Prüfe Folgendes, um <xliff:g id="APPNAME">%1$s</xliff:g>` auszuwählen"</string>
- <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8117011931337357438">"<xliff:g id="APPNAME">%1$s</xliff:g> öffnen"</string>
- <string name="keyguard_affordance_enablement_dialog_message" msgid="6136286758939253570">"Wenn du die <xliff:g id="APPNAME">%1$s</xliff:g> App als eine Verknüpfung hinzufügen möchtest, müssen folgende Bedingungen erfüllt sein"</string>
- <string name="keyguard_affordance_enablement_dialog_dismiss_button" msgid="629754625264422508">"Fertig"</string>
- <string name="keyguard_quick_affordance_title" msgid="4242813186995735584">"Verknüpfungen"</string>
- <string name="keyguard_quick_affordance_section_title" msgid="2806304242671717309">"Verknüpfungen"</string>
- <string name="keyguard_quick_affordance_two_selected_template" msgid="1757099194522296363">"<xliff:g id="FIRST">%1$s</xliff:g>, <xliff:g id="SECOND">%2$s</xliff:g>"</string>
- <string name="keyguard_quick_affordance_none_selected" msgid="8494127020144112003">"Keine"</string>
</resources>
diff --git a/res/values-el/strings.xml b/res/values-el/strings.xml
index 8bf703a..db4400f 100644
--- a/res/values-el/strings.xml
+++ b/res/values-el/strings.xml
@@ -19,9 +19,7 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_name" msgid="1647136562008520313">"Ταπετσαρία και στιλ"</string>
<string name="theme_title" msgid="2144932106319405101">"Στιλ"</string>
- <string name="clock_title" msgid="1974314575211361352">"Προσαρ. ρολόι"</string>
- <string name="clock_description" msgid="3563839327378948">"Επιλογή προσαρ. ρολογιού"</string>
- <string name="clock_picker_entry_content_description" msgid="8377139273468595734">"Αλλαγή προσαρ. ρολογιού"</string>
+ <string name="clock_title" msgid="2126046720254613991">"Ρολόι"</string>
<string name="grid_title" msgid="1688173478777254123">"Πλέγμα εφαρμ."</string>
<string name="apply_theme_btn" msgid="6293081192321303991">"Εφαρμογή"</string>
<string name="edit_custom_theme_lbl" msgid="5211377705710775224">"Πατήστε για επεξεργασία"</string>
@@ -91,15 +89,4 @@
<string name="preset_color_tab" msgid="3133391839341329314">"Βασικά χρώματα"</string>
<string name="color_changed" msgid="7029571720331641235">"Το χρώμα άλλαξε"</string>
<string name="adaptive_color_title" msgid="1336508599235896205">"Δυναμική"</string>
- <string name="keyguard_slot_name_bottom_start" msgid="6717374042663171860">"Κουμπί αριστερά"</string>
- <string name="keyguard_slot_name_bottom_end" msgid="7636885379738905151">"Κουμπί δεξιά"</string>
- <string name="keyguard_affordance_none" msgid="1751643933430782312">"Καμία"</string>
- <string name="keyguard_affordance_enablement_dialog_title" msgid="3389730825561696493">"Για να επιλέξετε \"<xliff:g id="APPNAME">%1$s</xliff:g>\", ελέγξτε τα εξής"</string>
- <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8117011931337357438">"Άνοιγμα <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
- <string name="keyguard_affordance_enablement_dialog_message" msgid="6136286758939253570">"Για να προσθέσετε την εφαρμογή <xliff:g id="APPNAME">%1$s</xliff:g> ως συντόμευση, βεβαιωθείτε ότι"</string>
- <string name="keyguard_affordance_enablement_dialog_dismiss_button" msgid="629754625264422508">"Τέλος"</string>
- <string name="keyguard_quick_affordance_title" msgid="4242813186995735584">"Συντομεύσεις"</string>
- <string name="keyguard_quick_affordance_section_title" msgid="2806304242671717309">"Συντομεύσεις"</string>
- <string name="keyguard_quick_affordance_two_selected_template" msgid="1757099194522296363">"<xliff:g id="FIRST">%1$s</xliff:g>, <xliff:g id="SECOND">%2$s</xliff:g>"</string>
- <string name="keyguard_quick_affordance_none_selected" msgid="8494127020144112003">"Καμία"</string>
</resources>
diff --git a/res/values-en-rAU/strings.xml b/res/values-en-rAU/strings.xml
index 7a8b69a..1d78ca0 100644
--- a/res/values-en-rAU/strings.xml
+++ b/res/values-en-rAU/strings.xml
@@ -17,11 +17,9 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="1647136562008520313">"Wallpaper and style"</string>
+ <string name="app_name" msgid="1647136562008520313">"Wallpaper & style"</string>
<string name="theme_title" msgid="2144932106319405101">"Style"</string>
- <string name="clock_title" msgid="1974314575211361352">"Custom clock"</string>
- <string name="clock_description" msgid="3563839327378948">"Pick a custom clock"</string>
- <string name="clock_picker_entry_content_description" msgid="8377139273468595734">"Change a custom clock"</string>
+ <string name="clock_title" msgid="2126046720254613991">"Clock"</string>
<string name="grid_title" msgid="1688173478777254123">"App grid"</string>
<string name="apply_theme_btn" msgid="6293081192321303991">"Apply"</string>
<string name="edit_custom_theme_lbl" msgid="5211377705710775224">"Tap to edit"</string>
@@ -91,15 +89,4 @@
<string name="preset_color_tab" msgid="3133391839341329314">"Basic colours"</string>
<string name="color_changed" msgid="7029571720331641235">"Colour changed"</string>
<string name="adaptive_color_title" msgid="1336508599235896205">"Dynamic"</string>
- <string name="keyguard_slot_name_bottom_start" msgid="6717374042663171860">"Left button"</string>
- <string name="keyguard_slot_name_bottom_end" msgid="7636885379738905151">"Right button"</string>
- <string name="keyguard_affordance_none" msgid="1751643933430782312">"None"</string>
- <string name="keyguard_affordance_enablement_dialog_title" msgid="3389730825561696493">"To select \'<xliff:g id="APPNAME">%1$s</xliff:g>\' check the following"</string>
- <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8117011931337357438">"Open <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
- <string name="keyguard_affordance_enablement_dialog_message" msgid="6136286758939253570">"To add the <xliff:g id="APPNAME">%1$s</xliff:g> app as a shortcut, make sure"</string>
- <string name="keyguard_affordance_enablement_dialog_dismiss_button" msgid="629754625264422508">"Done"</string>
- <string name="keyguard_quick_affordance_title" msgid="4242813186995735584">"Shortcuts"</string>
- <string name="keyguard_quick_affordance_section_title" msgid="2806304242671717309">"Shortcuts"</string>
- <string name="keyguard_quick_affordance_two_selected_template" msgid="1757099194522296363">"<xliff:g id="FIRST">%1$s</xliff:g>, <xliff:g id="SECOND">%2$s</xliff:g>"</string>
- <string name="keyguard_quick_affordance_none_selected" msgid="8494127020144112003">"None"</string>
</resources>
diff --git a/res/values-en-rCA/strings.xml b/res/values-en-rCA/strings.xml
index 5025853..1d78ca0 100644
--- a/res/values-en-rCA/strings.xml
+++ b/res/values-en-rCA/strings.xml
@@ -17,11 +17,9 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="1647136562008520313">"Wallpaper and style"</string>
+ <string name="app_name" msgid="1647136562008520313">"Wallpaper & style"</string>
<string name="theme_title" msgid="2144932106319405101">"Style"</string>
- <string name="clock_title" msgid="1974314575211361352">"Custom clock"</string>
- <string name="clock_description" msgid="3563839327378948">"Pick a custom clock"</string>
- <string name="clock_picker_entry_content_description" msgid="8377139273468595734">"Change a custom clock"</string>
+ <string name="clock_title" msgid="2126046720254613991">"Clock"</string>
<string name="grid_title" msgid="1688173478777254123">"App grid"</string>
<string name="apply_theme_btn" msgid="6293081192321303991">"Apply"</string>
<string name="edit_custom_theme_lbl" msgid="5211377705710775224">"Tap to edit"</string>
@@ -91,26 +89,4 @@
<string name="preset_color_tab" msgid="3133391839341329314">"Basic colours"</string>
<string name="color_changed" msgid="7029571720331641235">"Colour changed"</string>
<string name="adaptive_color_title" msgid="1336508599235896205">"Dynamic"</string>
- <!-- no translation found for keyguard_slot_name_bottom_start (6717374042663171860) -->
- <skip />
- <!-- no translation found for keyguard_slot_name_bottom_end (7636885379738905151) -->
- <skip />
- <!-- no translation found for keyguard_affordance_none (1751643933430782312) -->
- <skip />
- <!-- no translation found for keyguard_affordance_enablement_dialog_title (3389730825561696493) -->
- <skip />
- <!-- no translation found for keyguard_affordance_enablement_dialog_action_template (8117011931337357438) -->
- <skip />
- <!-- no translation found for keyguard_affordance_enablement_dialog_message (6136286758939253570) -->
- <skip />
- <!-- no translation found for keyguard_affordance_enablement_dialog_dismiss_button (629754625264422508) -->
- <skip />
- <!-- no translation found for keyguard_quick_affordance_title (4242813186995735584) -->
- <skip />
- <!-- no translation found for keyguard_quick_affordance_section_title (2806304242671717309) -->
- <skip />
- <!-- no translation found for keyguard_quick_affordance_two_selected_template (1757099194522296363) -->
- <skip />
- <!-- no translation found for keyguard_quick_affordance_none_selected (8494127020144112003) -->
- <skip />
</resources>
diff --git a/res/values-en-rGB/strings.xml b/res/values-en-rGB/strings.xml
index 7a8b69a..1d78ca0 100644
--- a/res/values-en-rGB/strings.xml
+++ b/res/values-en-rGB/strings.xml
@@ -17,11 +17,9 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="1647136562008520313">"Wallpaper and style"</string>
+ <string name="app_name" msgid="1647136562008520313">"Wallpaper & style"</string>
<string name="theme_title" msgid="2144932106319405101">"Style"</string>
- <string name="clock_title" msgid="1974314575211361352">"Custom clock"</string>
- <string name="clock_description" msgid="3563839327378948">"Pick a custom clock"</string>
- <string name="clock_picker_entry_content_description" msgid="8377139273468595734">"Change a custom clock"</string>
+ <string name="clock_title" msgid="2126046720254613991">"Clock"</string>
<string name="grid_title" msgid="1688173478777254123">"App grid"</string>
<string name="apply_theme_btn" msgid="6293081192321303991">"Apply"</string>
<string name="edit_custom_theme_lbl" msgid="5211377705710775224">"Tap to edit"</string>
@@ -91,15 +89,4 @@
<string name="preset_color_tab" msgid="3133391839341329314">"Basic colours"</string>
<string name="color_changed" msgid="7029571720331641235">"Colour changed"</string>
<string name="adaptive_color_title" msgid="1336508599235896205">"Dynamic"</string>
- <string name="keyguard_slot_name_bottom_start" msgid="6717374042663171860">"Left button"</string>
- <string name="keyguard_slot_name_bottom_end" msgid="7636885379738905151">"Right button"</string>
- <string name="keyguard_affordance_none" msgid="1751643933430782312">"None"</string>
- <string name="keyguard_affordance_enablement_dialog_title" msgid="3389730825561696493">"To select \'<xliff:g id="APPNAME">%1$s</xliff:g>\' check the following"</string>
- <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8117011931337357438">"Open <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
- <string name="keyguard_affordance_enablement_dialog_message" msgid="6136286758939253570">"To add the <xliff:g id="APPNAME">%1$s</xliff:g> app as a shortcut, make sure"</string>
- <string name="keyguard_affordance_enablement_dialog_dismiss_button" msgid="629754625264422508">"Done"</string>
- <string name="keyguard_quick_affordance_title" msgid="4242813186995735584">"Shortcuts"</string>
- <string name="keyguard_quick_affordance_section_title" msgid="2806304242671717309">"Shortcuts"</string>
- <string name="keyguard_quick_affordance_two_selected_template" msgid="1757099194522296363">"<xliff:g id="FIRST">%1$s</xliff:g>, <xliff:g id="SECOND">%2$s</xliff:g>"</string>
- <string name="keyguard_quick_affordance_none_selected" msgid="8494127020144112003">"None"</string>
</resources>
diff --git a/res/values-en-rIN/strings.xml b/res/values-en-rIN/strings.xml
index 7a8b69a..1d78ca0 100644
--- a/res/values-en-rIN/strings.xml
+++ b/res/values-en-rIN/strings.xml
@@ -17,11 +17,9 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="1647136562008520313">"Wallpaper and style"</string>
+ <string name="app_name" msgid="1647136562008520313">"Wallpaper & style"</string>
<string name="theme_title" msgid="2144932106319405101">"Style"</string>
- <string name="clock_title" msgid="1974314575211361352">"Custom clock"</string>
- <string name="clock_description" msgid="3563839327378948">"Pick a custom clock"</string>
- <string name="clock_picker_entry_content_description" msgid="8377139273468595734">"Change a custom clock"</string>
+ <string name="clock_title" msgid="2126046720254613991">"Clock"</string>
<string name="grid_title" msgid="1688173478777254123">"App grid"</string>
<string name="apply_theme_btn" msgid="6293081192321303991">"Apply"</string>
<string name="edit_custom_theme_lbl" msgid="5211377705710775224">"Tap to edit"</string>
@@ -91,15 +89,4 @@
<string name="preset_color_tab" msgid="3133391839341329314">"Basic colours"</string>
<string name="color_changed" msgid="7029571720331641235">"Colour changed"</string>
<string name="adaptive_color_title" msgid="1336508599235896205">"Dynamic"</string>
- <string name="keyguard_slot_name_bottom_start" msgid="6717374042663171860">"Left button"</string>
- <string name="keyguard_slot_name_bottom_end" msgid="7636885379738905151">"Right button"</string>
- <string name="keyguard_affordance_none" msgid="1751643933430782312">"None"</string>
- <string name="keyguard_affordance_enablement_dialog_title" msgid="3389730825561696493">"To select \'<xliff:g id="APPNAME">%1$s</xliff:g>\' check the following"</string>
- <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8117011931337357438">"Open <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
- <string name="keyguard_affordance_enablement_dialog_message" msgid="6136286758939253570">"To add the <xliff:g id="APPNAME">%1$s</xliff:g> app as a shortcut, make sure"</string>
- <string name="keyguard_affordance_enablement_dialog_dismiss_button" msgid="629754625264422508">"Done"</string>
- <string name="keyguard_quick_affordance_title" msgid="4242813186995735584">"Shortcuts"</string>
- <string name="keyguard_quick_affordance_section_title" msgid="2806304242671717309">"Shortcuts"</string>
- <string name="keyguard_quick_affordance_two_selected_template" msgid="1757099194522296363">"<xliff:g id="FIRST">%1$s</xliff:g>, <xliff:g id="SECOND">%2$s</xliff:g>"</string>
- <string name="keyguard_quick_affordance_none_selected" msgid="8494127020144112003">"None"</string>
</resources>
diff --git a/res/values-en-rXC/strings.xml b/res/values-en-rXC/strings.xml
index a009b89..8ed71cd 100644
--- a/res/values-en-rXC/strings.xml
+++ b/res/values-en-rXC/strings.xml
@@ -19,9 +19,7 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_name" msgid="1647136562008520313">"Wallpaper & style"</string>
<string name="theme_title" msgid="2144932106319405101">"Style"</string>
- <string name="clock_title" msgid="1974314575211361352">"Custom Clock"</string>
- <string name="clock_description" msgid="3563839327378948">"Pick a custom clock"</string>
- <string name="clock_picker_entry_content_description" msgid="8377139273468595734">"Change a custom clock"</string>
+ <string name="clock_title" msgid="2126046720254613991">"Clock"</string>
<string name="grid_title" msgid="1688173478777254123">"App grid"</string>
<string name="apply_theme_btn" msgid="6293081192321303991">"Apply"</string>
<string name="edit_custom_theme_lbl" msgid="5211377705710775224">"Tap to edit"</string>
@@ -91,15 +89,4 @@
<string name="preset_color_tab" msgid="3133391839341329314">"Basic colors"</string>
<string name="color_changed" msgid="7029571720331641235">"Color changed"</string>
<string name="adaptive_color_title" msgid="1336508599235896205">"Dynamic"</string>
- <string name="keyguard_slot_name_bottom_start" msgid="6717374042663171860">"Left button"</string>
- <string name="keyguard_slot_name_bottom_end" msgid="7636885379738905151">"Right button"</string>
- <string name="keyguard_affordance_none" msgid="1751643933430782312">"None"</string>
- <string name="keyguard_affordance_enablement_dialog_title" msgid="3389730825561696493">"To select `<xliff:g id="APPNAME">%1$s</xliff:g>` check the following"</string>
- <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8117011931337357438">"Open <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
- <string name="keyguard_affordance_enablement_dialog_message" msgid="6136286758939253570">"To add the <xliff:g id="APPNAME">%1$s</xliff:g> app as a shortcut, make sure"</string>
- <string name="keyguard_affordance_enablement_dialog_dismiss_button" msgid="629754625264422508">"Done"</string>
- <string name="keyguard_quick_affordance_title" msgid="4242813186995735584">"Shortcuts"</string>
- <string name="keyguard_quick_affordance_section_title" msgid="2806304242671717309">"Shortcuts"</string>
- <string name="keyguard_quick_affordance_two_selected_template" msgid="1757099194522296363">"<xliff:g id="FIRST">%1$s</xliff:g>, <xliff:g id="SECOND">%2$s</xliff:g>"</string>
- <string name="keyguard_quick_affordance_none_selected" msgid="8494127020144112003">"None"</string>
</resources>
diff --git a/res/values-es-rUS/strings.xml b/res/values-es-rUS/strings.xml
index 1f6dace..0eb30c7 100644
--- a/res/values-es-rUS/strings.xml
+++ b/res/values-es-rUS/strings.xml
@@ -19,9 +19,7 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_name" msgid="1647136562008520313">"Fondo de pantalla y estilo"</string>
<string name="theme_title" msgid="2144932106319405101">"Estilo"</string>
- <string name="clock_title" msgid="1974314575211361352">"Reloj person."</string>
- <string name="clock_description" msgid="3563839327378948">"Elige un reloj"</string>
- <string name="clock_picker_entry_content_description" msgid="8377139273468595734">"Cambia el reloj personalizado"</string>
+ <string name="clock_title" msgid="2126046720254613991">"Reloj"</string>
<string name="grid_title" msgid="1688173478777254123">"Cuadr. de apps"</string>
<string name="apply_theme_btn" msgid="6293081192321303991">"Aplicar"</string>
<string name="edit_custom_theme_lbl" msgid="5211377705710775224">"Presiona para editar"</string>
@@ -91,15 +89,4 @@
<string name="preset_color_tab" msgid="3133391839341329314">"Colores básicos"</string>
<string name="color_changed" msgid="7029571720331641235">"Se cambió el color"</string>
<string name="adaptive_color_title" msgid="1336508599235896205">"Dinámico"</string>
- <string name="keyguard_slot_name_bottom_start" msgid="6717374042663171860">"Botón izquierdo"</string>
- <string name="keyguard_slot_name_bottom_end" msgid="7636885379738905151">"Botón derecho"</string>
- <string name="keyguard_affordance_none" msgid="1751643933430782312">"Ninguno"</string>
- <string name="keyguard_affordance_enablement_dialog_title" msgid="3389730825561696493">"Para seleccionar \"<xliff:g id="APPNAME">%1$s</xliff:g>\", verifica lo siguiente"</string>
- <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8117011931337357438">"Abrir <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
- <string name="keyguard_affordance_enablement_dialog_message" msgid="6136286758939253570">"Para agregar la app <xliff:g id="APPNAME">%1$s</xliff:g> como acceso directo, asegúrate que se cumplan los siguientes requisitos:"</string>
- <string name="keyguard_affordance_enablement_dialog_dismiss_button" msgid="629754625264422508">"Listo"</string>
- <string name="keyguard_quick_affordance_title" msgid="4242813186995735584">"Comb. de teclas"</string>
- <string name="keyguard_quick_affordance_section_title" msgid="2806304242671717309">"Comb. de teclas"</string>
- <string name="keyguard_quick_affordance_two_selected_template" msgid="1757099194522296363">"<xliff:g id="FIRST">%1$s</xliff:g>, <xliff:g id="SECOND">%2$s</xliff:g>"</string>
- <string name="keyguard_quick_affordance_none_selected" msgid="8494127020144112003">"Ninguno"</string>
</resources>
diff --git a/res/values-es/strings.xml b/res/values-es/strings.xml
index ad64ee2..c45e390 100644
--- a/res/values-es/strings.xml
+++ b/res/values-es/strings.xml
@@ -19,9 +19,7 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_name" msgid="1647136562008520313">"Fondo de pantalla y estilo"</string>
<string name="theme_title" msgid="2144932106319405101">"Estilo"</string>
- <string name="clock_title" msgid="1974314575211361352">"Reloj personalizado"</string>
- <string name="clock_description" msgid="3563839327378948">"Elige un reloj personalizado"</string>
- <string name="clock_picker_entry_content_description" msgid="8377139273468595734">"Cambiar reloj personalizado"</string>
+ <string name="clock_title" msgid="2126046720254613991">"Reloj"</string>
<string name="grid_title" msgid="1688173478777254123">"Cuadrícula de apps"</string>
<string name="apply_theme_btn" msgid="6293081192321303991">"Aplicar"</string>
<string name="edit_custom_theme_lbl" msgid="5211377705710775224">"Toca para editar"</string>
@@ -91,15 +89,4 @@
<string name="preset_color_tab" msgid="3133391839341329314">"Colores básicos"</string>
<string name="color_changed" msgid="7029571720331641235">"Color cambiado"</string>
<string name="adaptive_color_title" msgid="1336508599235896205">"Dinámico"</string>
- <string name="keyguard_slot_name_bottom_start" msgid="6717374042663171860">"Botón izquierdo"</string>
- <string name="keyguard_slot_name_bottom_end" msgid="7636885379738905151">"Botón derecho"</string>
- <string name="keyguard_affordance_none" msgid="1751643933430782312">"Ninguno"</string>
- <string name="keyguard_affordance_enablement_dialog_title" msgid="3389730825561696493">"Para seleccionar <xliff:g id="APPNAME">%1$s</xliff:g>, comprueba lo siguiente"</string>
- <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8117011931337357438">"Abrir <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
- <string name="keyguard_affordance_enablement_dialog_message" msgid="6136286758939253570">"Para añadir la aplicación <xliff:g id="APPNAME">%1$s</xliff:g> como acceso directo:"</string>
- <string name="keyguard_affordance_enablement_dialog_dismiss_button" msgid="629754625264422508">"Hecho"</string>
- <string name="keyguard_quick_affordance_title" msgid="4242813186995735584">"Accesos directos"</string>
- <string name="keyguard_quick_affordance_section_title" msgid="2806304242671717309">"Accesos directos"</string>
- <string name="keyguard_quick_affordance_two_selected_template" msgid="1757099194522296363">"<xliff:g id="FIRST">%1$s</xliff:g>, <xliff:g id="SECOND">%2$s</xliff:g>"</string>
- <string name="keyguard_quick_affordance_none_selected" msgid="8494127020144112003">"Ninguno"</string>
</resources>
diff --git a/res/values-et/strings.xml b/res/values-et/strings.xml
index 210dbc7..2a6e051 100644
--- a/res/values-et/strings.xml
+++ b/res/values-et/strings.xml
@@ -19,9 +19,7 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_name" msgid="1647136562008520313">"Taustapilt ja stiil"</string>
<string name="theme_title" msgid="2144932106319405101">"Stiil"</string>
- <string name="clock_title" msgid="1974314575211361352">"Kohandatud kell"</string>
- <string name="clock_description" msgid="3563839327378948">"Kohandatud kell"</string>
- <string name="clock_picker_entry_content_description" msgid="8377139273468595734">"Kohandatud kella muutmine"</string>
+ <string name="clock_title" msgid="2126046720254613991">"Kell"</string>
<string name="grid_title" msgid="1688173478777254123">"Rak. ruudustik"</string>
<string name="apply_theme_btn" msgid="6293081192321303991">"Rakenda"</string>
<string name="edit_custom_theme_lbl" msgid="5211377705710775224">"Puudutage muutmiseks"</string>
@@ -91,15 +89,4 @@
<string name="preset_color_tab" msgid="3133391839341329314">"Põhivärvid"</string>
<string name="color_changed" msgid="7029571720331641235">"Värvi muudeti"</string>
<string name="adaptive_color_title" msgid="1336508599235896205">"Dünaamiline"</string>
- <string name="keyguard_slot_name_bottom_start" msgid="6717374042663171860">"Vasak nupp"</string>
- <string name="keyguard_slot_name_bottom_end" msgid="7636885379738905151">"Parem nupp"</string>
- <string name="keyguard_affordance_none" msgid="1751643933430782312">"Puudub"</string>
- <string name="keyguard_affordance_enablement_dialog_title" msgid="3389730825561696493">"Rakenduse „<xliff:g id="APPNAME">%1$s</xliff:g>“ valimiseks veenduge järgmises"</string>
- <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8117011931337357438">"Ava <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
- <string name="keyguard_affordance_enablement_dialog_message" msgid="6136286758939253570">"Rakenduse <xliff:g id="APPNAME">%1$s</xliff:g> otsetee lisamiseks veenduge järgmises."</string>
- <string name="keyguard_affordance_enablement_dialog_dismiss_button" msgid="629754625264422508">"Valmis"</string>
- <string name="keyguard_quick_affordance_title" msgid="4242813186995735584">"Otseteed"</string>
- <string name="keyguard_quick_affordance_section_title" msgid="2806304242671717309">"Otseteed"</string>
- <string name="keyguard_quick_affordance_two_selected_template" msgid="1757099194522296363">"<xliff:g id="FIRST">%1$s</xliff:g>, <xliff:g id="SECOND">%2$s</xliff:g>"</string>
- <string name="keyguard_quick_affordance_none_selected" msgid="8494127020144112003">"Pole"</string>
</resources>
diff --git a/res/values-eu/strings.xml b/res/values-eu/strings.xml
index 0c36cb4..7944b93 100644
--- a/res/values-eu/strings.xml
+++ b/res/values-eu/strings.xml
@@ -19,9 +19,7 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_name" msgid="1647136562008520313">"Horma-papera eta estiloa"</string>
<string name="theme_title" msgid="2144932106319405101">"Estiloa"</string>
- <string name="clock_title" msgid="1974314575211361352">"Esfera pertsonalizatuak"</string>
- <string name="clock_description" msgid="3563839327378948">"Hautatu esfera pertsonalizatu bat"</string>
- <string name="clock_picker_entry_content_description" msgid="8377139273468595734">"Aldatu esfera pertsonalizatua"</string>
+ <string name="clock_title" msgid="2126046720254613991">"Erlojua"</string>
<string name="grid_title" msgid="1688173478777254123">"Aplikazioen sareta"</string>
<string name="apply_theme_btn" msgid="6293081192321303991">"Aplikatu"</string>
<string name="edit_custom_theme_lbl" msgid="5211377705710775224">"Sakatu editatzeko"</string>
@@ -81,7 +79,7 @@
<string name="accessibility_custom_shape_title" msgid="7708408259374643129">"Forma pertsonalizatua"</string>
<string name="accessibility_custom_name_title" msgid="5494460518085463262">"Estilo pertsonalizatuaren izena"</string>
<string name="mode_title" msgid="2394873501427436055">"Gai iluna"</string>
- <string name="mode_disabled_msg" msgid="9196245518435936512">"Aldi baterako desgaituta, bateria-aurreztailea dela eta"</string>
+ <string name="mode_disabled_msg" msgid="9196245518435936512">"Aldi baterako desgaituta, bateria-aurrezlea dela eta"</string>
<string name="mode_changed" msgid="2243581369395418584">"Aldatu da gaia"</string>
<string name="themed_icon_title" msgid="7312460430471956558">"Ikono gaidunak"</string>
<string name="beta_title" msgid="8703819523760746458">"Beta"</string>
@@ -91,15 +89,4 @@
<string name="preset_color_tab" msgid="3133391839341329314">"Oinarrizko koloreak"</string>
<string name="color_changed" msgid="7029571720331641235">"Aldatu da kolorea"</string>
<string name="adaptive_color_title" msgid="1336508599235896205">"Dinamikoa"</string>
- <string name="keyguard_slot_name_bottom_start" msgid="6717374042663171860">"Ezkerreko botoia"</string>
- <string name="keyguard_slot_name_bottom_end" msgid="7636885379738905151">"Eskuineko botoia"</string>
- <string name="keyguard_affordance_none" msgid="1751643933430782312">"Bat ere ez"</string>
- <string name="keyguard_affordance_enablement_dialog_title" msgid="3389730825561696493">"<xliff:g id="APPNAME">%1$s</xliff:g> hautatzeko, egin hauek:"</string>
- <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8117011931337357438">"Ireki <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
- <string name="keyguard_affordance_enablement_dialog_message" msgid="6136286758939253570">"<xliff:g id="APPNAME">%1$s</xliff:g> aplikazioa lasterbide gisa gehitzeko, ziurtatu hauek betetzen direla:"</string>
- <string name="keyguard_affordance_enablement_dialog_dismiss_button" msgid="629754625264422508">"Eginda"</string>
- <string name="keyguard_quick_affordance_title" msgid="4242813186995735584">"Lasterbideak"</string>
- <string name="keyguard_quick_affordance_section_title" msgid="2806304242671717309">"Lasterbideak"</string>
- <string name="keyguard_quick_affordance_two_selected_template" msgid="1757099194522296363">"<xliff:g id="FIRST">%1$s</xliff:g> eta <xliff:g id="SECOND">%2$s</xliff:g>"</string>
- <string name="keyguard_quick_affordance_none_selected" msgid="8494127020144112003">"Bat ere ez"</string>
</resources>
diff --git a/res/values-fa/strings.xml b/res/values-fa/strings.xml
index 5f38e44..4a5f763 100644
--- a/res/values-fa/strings.xml
+++ b/res/values-fa/strings.xml
@@ -19,9 +19,7 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_name" msgid="1647136562008520313">"کاغذدیواری و سبک"</string>
<string name="theme_title" msgid="2144932106319405101">"سبک"</string>
- <string name="clock_title" msgid="1974314575211361352">"ساعت سفارشی"</string>
- <string name="clock_description" msgid="3563839327378948">"انتخاب ساعت سفارشی"</string>
- <string name="clock_picker_entry_content_description" msgid="8377139273468595734">"تغییر ساعت سفارشی"</string>
+ <string name="clock_title" msgid="2126046720254613991">"ساعت"</string>
<string name="grid_title" msgid="1688173478777254123">"جدول برنامه"</string>
<string name="apply_theme_btn" msgid="6293081192321303991">"اعمال"</string>
<string name="edit_custom_theme_lbl" msgid="5211377705710775224">"برای ویرایش ضربه بزنید"</string>
@@ -91,15 +89,4 @@
<string name="preset_color_tab" msgid="3133391839341329314">"رنگهای اصلی"</string>
<string name="color_changed" msgid="7029571720331641235">"رنگ تغییر کرد"</string>
<string name="adaptive_color_title" msgid="1336508599235896205">"پویا"</string>
- <string name="keyguard_slot_name_bottom_start" msgid="6717374042663171860">"دکمه چپ"</string>
- <string name="keyguard_slot_name_bottom_end" msgid="7636885379738905151">"دکمه راست"</string>
- <string name="keyguard_affordance_none" msgid="1751643933430782312">"هیچکدام"</string>
- <string name="keyguard_affordance_enablement_dialog_title" msgid="3389730825561696493">"برای انتخاب «<xliff:g id="APPNAME">%1$s</xliff:g>»، مورد زیر را بررسی کنید"</string>
- <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8117011931337357438">"باز کردن <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
- <string name="keyguard_affordance_enablement_dialog_message" msgid="6136286758939253570">"برای افزودن برنامه <xliff:g id="APPNAME">%1$s</xliff:g> بهعنوان میانبر، مطمئن شوید"</string>
- <string name="keyguard_affordance_enablement_dialog_dismiss_button" msgid="629754625264422508">"تمام"</string>
- <string name="keyguard_quick_affordance_title" msgid="4242813186995735584">"میانبرها"</string>
- <string name="keyguard_quick_affordance_section_title" msgid="2806304242671717309">"میانبرها"</string>
- <string name="keyguard_quick_affordance_two_selected_template" msgid="1757099194522296363">"<xliff:g id="FIRST">%1$s</xliff:g>، <xliff:g id="SECOND">%2$s</xliff:g>"</string>
- <string name="keyguard_quick_affordance_none_selected" msgid="8494127020144112003">"هیچکدام"</string>
</resources>
diff --git a/res/values-fi/strings.xml b/res/values-fi/strings.xml
index 2459a6f..37f57b8 100644
--- a/res/values-fi/strings.xml
+++ b/res/values-fi/strings.xml
@@ -19,9 +19,7 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_name" msgid="1647136562008520313">"Taustakuva ja tyyli"</string>
<string name="theme_title" msgid="2144932106319405101">"Tyyli"</string>
- <string name="clock_title" msgid="1974314575211361352">"Oma kello"</string>
- <string name="clock_description" msgid="3563839327378948">"Valitse kello"</string>
- <string name="clock_picker_entry_content_description" msgid="8377139273468595734">"Muuta omaa kelloa"</string>
+ <string name="clock_title" msgid="2126046720254613991">"Kello"</string>
<string name="grid_title" msgid="1688173478777254123">"Ruudukko"</string>
<string name="apply_theme_btn" msgid="6293081192321303991">"Käytä"</string>
<string name="edit_custom_theme_lbl" msgid="5211377705710775224">"Muokkaa napauttamalla"</string>
@@ -91,15 +89,4 @@
<string name="preset_color_tab" msgid="3133391839341329314">"Perusvärit"</string>
<string name="color_changed" msgid="7029571720331641235">"Väri vaihdettu"</string>
<string name="adaptive_color_title" msgid="1336508599235896205">"Dynaaminen"</string>
- <string name="keyguard_slot_name_bottom_start" msgid="6717374042663171860">"Vasen painike"</string>
- <string name="keyguard_slot_name_bottom_end" msgid="7636885379738905151">"Oikea painike"</string>
- <string name="keyguard_affordance_none" msgid="1751643933430782312">"–"</string>
- <string name="keyguard_affordance_enablement_dialog_title" msgid="3389730825561696493">"Tarkista seuraavat, jotta \"<xliff:g id="APPNAME">%1$s</xliff:g>\" on valittavissa"</string>
- <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8117011931337357438">"Avaa <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
- <string name="keyguard_affordance_enablement_dialog_message" msgid="6136286758939253570">"Jos haluat, että <xliff:g id="APPNAME">%1$s</xliff:g> lisätään pikakuvakkeeksi, varmista nämä:"</string>
- <string name="keyguard_affordance_enablement_dialog_dismiss_button" msgid="629754625264422508">"Valmis"</string>
- <string name="keyguard_quick_affordance_title" msgid="4242813186995735584">"Pikakomennot"</string>
- <string name="keyguard_quick_affordance_section_title" msgid="2806304242671717309">"Pikakomennot"</string>
- <string name="keyguard_quick_affordance_two_selected_template" msgid="1757099194522296363">"<xliff:g id="FIRST">%1$s</xliff:g>, <xliff:g id="SECOND">%2$s</xliff:g>"</string>
- <string name="keyguard_quick_affordance_none_selected" msgid="8494127020144112003">"–"</string>
</resources>
diff --git a/res/values-fr-rCA/strings.xml b/res/values-fr-rCA/strings.xml
index 3483dc2..c271e5c 100644
--- a/res/values-fr-rCA/strings.xml
+++ b/res/values-fr-rCA/strings.xml
@@ -19,9 +19,7 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_name" msgid="1647136562008520313">"Fond d\'écran et style"</string>
<string name="theme_title" msgid="2144932106319405101">"Style"</string>
- <string name="clock_title" msgid="1974314575211361352">"Horloge personnalisée"</string>
- <string name="clock_description" msgid="3563839327378948">"Choisissez une horloge personnalisée"</string>
- <string name="clock_picker_entry_content_description" msgid="8377139273468595734">"Modifiez une horloge personnalisée"</string>
+ <string name="clock_title" msgid="2126046720254613991">"Horloge"</string>
<string name="grid_title" msgid="1688173478777254123">"Grille d\'applis"</string>
<string name="apply_theme_btn" msgid="6293081192321303991">"Appliquer"</string>
<string name="edit_custom_theme_lbl" msgid="5211377705710775224">"Toucher pour modifier"</string>
@@ -91,15 +89,4 @@
<string name="preset_color_tab" msgid="3133391839341329314">"Couleurs de base"</string>
<string name="color_changed" msgid="7029571720331641235">"Couleur changée"</string>
<string name="adaptive_color_title" msgid="1336508599235896205">"Dynamique"</string>
- <string name="keyguard_slot_name_bottom_start" msgid="6717374042663171860">"Bouton gauche"</string>
- <string name="keyguard_slot_name_bottom_end" msgid="7636885379738905151">"Bouton droit"</string>
- <string name="keyguard_affordance_none" msgid="1751643933430782312">"Aucune"</string>
- <string name="keyguard_affordance_enablement_dialog_title" msgid="3389730825561696493">"Pour sélectionner « <xliff:g id="APPNAME">%1$s</xliff:g> » vérifiez ce qui suit"</string>
- <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8117011931337357438">"Ouvrir <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
- <string name="keyguard_affordance_enablement_dialog_message" msgid="6136286758939253570">"Pour ajouter l\'application <xliff:g id="APPNAME">%1$s</xliff:g> en tant que raccourci, assurez-vous"</string>
- <string name="keyguard_affordance_enablement_dialog_dismiss_button" msgid="629754625264422508">"OK"</string>
- <string name="keyguard_quick_affordance_title" msgid="4242813186995735584">"Raccourcis"</string>
- <string name="keyguard_quick_affordance_section_title" msgid="2806304242671717309">"Raccourcis"</string>
- <string name="keyguard_quick_affordance_two_selected_template" msgid="1757099194522296363">"<xliff:g id="FIRST">%1$s</xliff:g>, <xliff:g id="SECOND">%2$s</xliff:g>"</string>
- <string name="keyguard_quick_affordance_none_selected" msgid="8494127020144112003">"Aucun"</string>
</resources>
diff --git a/res/values-fr/strings.xml b/res/values-fr/strings.xml
index e7925c9..05dfdfd 100644
--- a/res/values-fr/strings.xml
+++ b/res/values-fr/strings.xml
@@ -19,9 +19,7 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_name" msgid="1647136562008520313">"Fond d\'écran et style"</string>
<string name="theme_title" msgid="2144932106319405101">"Style"</string>
- <string name="clock_title" msgid="1974314575211361352">"Cadran perso."</string>
- <string name="clock_description" msgid="3563839327378948">"Choisir cadran"</string>
- <string name="clock_picker_entry_content_description" msgid="8377139273468595734">"Modifier un cadran personnalisé"</string>
+ <string name="clock_title" msgid="2126046720254613991">"Horloge"</string>
<string name="grid_title" msgid="1688173478777254123">"Grille d\'applis"</string>
<string name="apply_theme_btn" msgid="6293081192321303991">"Appliquer"</string>
<string name="edit_custom_theme_lbl" msgid="5211377705710775224">"Appuyer pour modifier"</string>
@@ -86,20 +84,9 @@
<string name="themed_icon_title" msgid="7312460430471956558">"Icônes à thème"</string>
<string name="beta_title" msgid="8703819523760746458">"Bêta"</string>
<string name="gird_picker_entry_content_description" msgid="9087651470212293439">"Modifier la grille d\'applis"</string>
- <string name="wallpaper_color_tab" msgid="1447926591721403840">"Couleurs fond d\'écran"</string>
+ <string name="wallpaper_color_tab" msgid="1447926591721403840">"Couleurs du fond"</string>
<string name="wallpaper_color_title" msgid="5687965239180986458">"Couleur du fond d\'écran"</string>
<string name="preset_color_tab" msgid="3133391839341329314">"Couleurs de base"</string>
<string name="color_changed" msgid="7029571720331641235">"Couleur modifiée"</string>
<string name="adaptive_color_title" msgid="1336508599235896205">"Dynamique"</string>
- <string name="keyguard_slot_name_bottom_start" msgid="6717374042663171860">"Bouton gauche"</string>
- <string name="keyguard_slot_name_bottom_end" msgid="7636885379738905151">"Bouton droit"</string>
- <string name="keyguard_affordance_none" msgid="1751643933430782312">"Aucun"</string>
- <string name="keyguard_affordance_enablement_dialog_title" msgid="3389730825561696493">"Pour sélectionner <xliff:g id="APPNAME">%1$s</xliff:g>, vérifiez ce qui suit"</string>
- <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8117011931337357438">"Ouvrir <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
- <string name="keyguard_affordance_enablement_dialog_message" msgid="6136286758939253570">"Pour ajouter l\'appli <xliff:g id="APPNAME">%1$s</xliff:g> comme raccourci, procédez aux vérifications suivantes"</string>
- <string name="keyguard_affordance_enablement_dialog_dismiss_button" msgid="629754625264422508">"OK"</string>
- <string name="keyguard_quick_affordance_title" msgid="4242813186995735584">"Raccourcis"</string>
- <string name="keyguard_quick_affordance_section_title" msgid="2806304242671717309">"Raccourcis"</string>
- <string name="keyguard_quick_affordance_two_selected_template" msgid="1757099194522296363">"<xliff:g id="FIRST">%1$s</xliff:g>, <xliff:g id="SECOND">%2$s</xliff:g>"</string>
- <string name="keyguard_quick_affordance_none_selected" msgid="8494127020144112003">"Aucun"</string>
</resources>
diff --git a/res/values-gl/strings.xml b/res/values-gl/strings.xml
index e60fc00..5b90944 100644
--- a/res/values-gl/strings.xml
+++ b/res/values-gl/strings.xml
@@ -19,9 +19,7 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_name" msgid="1647136562008520313">"Estilo e fondo de pantalla"</string>
<string name="theme_title" msgid="2144932106319405101">"Estilo"</string>
- <string name="clock_title" msgid="1974314575211361352">"Reloxo person."</string>
- <string name="clock_description" msgid="3563839327378948">"Elixe reloxo pers."</string>
- <string name="clock_picker_entry_content_description" msgid="8377139273468595734">"Cambiar reloxo personalizado"</string>
+ <string name="clock_title" msgid="2126046720254613991">"Reloxo"</string>
<string name="grid_title" msgid="1688173478777254123">"Grade de apps"</string>
<string name="apply_theme_btn" msgid="6293081192321303991">"Aplicar"</string>
<string name="edit_custom_theme_lbl" msgid="5211377705710775224">"Toca para editar"</string>
@@ -69,10 +67,10 @@
<string name="set_theme_wallpaper_dialog_message" msgid="2179661027350908003">"Definir fondo de pantalla do estilo"</string>
<string name="use_style_instead_title" msgid="1578754995763917502">"Prefires utilizar <xliff:g id="ID_1">%1$s</xliff:g>?"</string>
<string name="use_style_instead_body" msgid="3051937045807471496">"O estilo de <xliff:g id="ID_1">%1$s</xliff:g> concorda cos compoñentes que escolliches. Prefires utilizar <xliff:g id="ID_2">%1$s</xliff:g>?"</string>
- <string name="use_style_button" msgid="1754493078383627019">"Usar <xliff:g id="ID_1">%1$s</xliff:g>"</string>
+ <string name="use_style_button" msgid="1754493078383627019">"Utilizar <xliff:g id="ID_1">%1$s</xliff:g>"</string>
<string name="no_thanks" msgid="7286616980115687627">"Non, grazas"</string>
<string name="clock_preview_content_description" msgid="5460561185905717460">"Vista previa do reloxo <xliff:g id="ID_1">%1$s</xliff:g>"</string>
- <string name="something_went_wrong" msgid="529840112449799117">"Ai, produciuse un erro."</string>
+ <string name="something_went_wrong" msgid="529840112449799117">"Ai! Produciuse un erro."</string>
<string name="theme_preview_icons_section_title" msgid="7064768910744000643">"Cores/iconas"</string>
<string name="style_info_description" msgid="2612473574431003251">"Vista previa de tipo de letra, iconas, forma da aplicación e cor"</string>
<string name="accessibility_custom_font_title" msgid="966867359157303705">"Tipo de letra personalizado"</string>
@@ -91,15 +89,4 @@
<string name="preset_color_tab" msgid="3133391839341329314">"Cores básicas"</string>
<string name="color_changed" msgid="7029571720331641235">"Cor modificada"</string>
<string name="adaptive_color_title" msgid="1336508599235896205">"Dinámica"</string>
- <string name="keyguard_slot_name_bottom_start" msgid="6717374042663171860">"Botón esquerdo"</string>
- <string name="keyguard_slot_name_bottom_end" msgid="7636885379738905151">"Botón dereito"</string>
- <string name="keyguard_affordance_none" msgid="1751643933430782312">"Ningunha"</string>
- <string name="keyguard_affordance_enablement_dialog_title" msgid="3389730825561696493">"Para seleccionar <xliff:g id="APPNAME">%1$s</xliff:g>, comproba o seguinte"</string>
- <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8117011931337357438">"Abrir <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
- <string name="keyguard_affordance_enablement_dialog_message" msgid="6136286758939253570">"Para engadir a aplicación <xliff:g id="APPNAME">%1$s</xliff:g> como atallo, asegúrate de que se cumpra o seguinte:"</string>
- <string name="keyguard_affordance_enablement_dialog_dismiss_button" msgid="629754625264422508">"Feito"</string>
- <string name="keyguard_quick_affordance_title" msgid="4242813186995735584">"Atallos"</string>
- <string name="keyguard_quick_affordance_section_title" msgid="2806304242671717309">"Atallos"</string>
- <string name="keyguard_quick_affordance_two_selected_template" msgid="1757099194522296363">"<xliff:g id="FIRST">%1$s</xliff:g>, <xliff:g id="SECOND">%2$s</xliff:g>"</string>
- <string name="keyguard_quick_affordance_none_selected" msgid="8494127020144112003">"Ningún"</string>
</resources>
diff --git a/res/values-gu/strings.xml b/res/values-gu/strings.xml
index 38d7546..95af51f 100644
--- a/res/values-gu/strings.xml
+++ b/res/values-gu/strings.xml
@@ -17,11 +17,9 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="1647136562008520313">"વૉલપેપર અને સ્ટાઇલ"</string>
+ <string name="app_name" msgid="1647136562008520313">"વૉલપેપર અને શૈલી"</string>
<string name="theme_title" msgid="2144932106319405101">"શૈલી"</string>
- <string name="clock_title" msgid="1974314575211361352">"કસ્ટમ ઘડિયાળ"</string>
- <string name="clock_description" msgid="3563839327378948">"કસ્ટમ ઘડિયાળ ચૂંટો"</string>
- <string name="clock_picker_entry_content_description" msgid="8377139273468595734">"કસ્ટમ ઘડિયાળ બદલો"</string>
+ <string name="clock_title" msgid="2126046720254613991">"ઘડિયાળ"</string>
<string name="grid_title" msgid="1688173478777254123">"ઍપ ગ્રિડ"</string>
<string name="apply_theme_btn" msgid="6293081192321303991">"લાગુ કરો"</string>
<string name="edit_custom_theme_lbl" msgid="5211377705710775224">"ફેરફાર કરવા માટે ટૅપ કરો"</string>
@@ -91,15 +89,4 @@
<string name="preset_color_tab" msgid="3133391839341329314">"મૂળભૂત રંગો"</string>
<string name="color_changed" msgid="7029571720331641235">"રંગ બદલ્યો છે"</string>
<string name="adaptive_color_title" msgid="1336508599235896205">"ડાઇનૅમિક"</string>
- <string name="keyguard_slot_name_bottom_start" msgid="6717374042663171860">"ડાબી બાજુનું બટન"</string>
- <string name="keyguard_slot_name_bottom_end" msgid="7636885379738905151">"જમણી બાજુનું બટન"</string>
- <string name="keyguard_affordance_none" msgid="1751643933430782312">"એકપણ નહીં"</string>
- <string name="keyguard_affordance_enablement_dialog_title" msgid="3389730825561696493">"`<xliff:g id="APPNAME">%1$s</xliff:g>`ને પસંદ કરવા માટે, નીચેની બાબત ચેક કરો"</string>
- <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8117011931337357438">"<xliff:g id="APPNAME">%1$s</xliff:g> ખોલો"</string>
- <string name="keyguard_affordance_enablement_dialog_message" msgid="6136286758939253570">"<xliff:g id="APPNAME">%1$s</xliff:g> ઍપને શૉર્ટકટ તરીકે ઉમેરવા માટે, આ બાબતોની ખાતરી કરો"</string>
- <string name="keyguard_affordance_enablement_dialog_dismiss_button" msgid="629754625264422508">"થઈ ગયું"</string>
- <string name="keyguard_quick_affordance_title" msgid="4242813186995735584">"શૉર્ટકટ"</string>
- <string name="keyguard_quick_affordance_section_title" msgid="2806304242671717309">"શૉર્ટકટ"</string>
- <string name="keyguard_quick_affordance_two_selected_template" msgid="1757099194522296363">"<xliff:g id="FIRST">%1$s</xliff:g>, <xliff:g id="SECOND">%2$s</xliff:g>"</string>
- <string name="keyguard_quick_affordance_none_selected" msgid="8494127020144112003">"એકપણ નહીં"</string>
</resources>
diff --git a/res/values-hi/strings.xml b/res/values-hi/strings.xml
index 5f68098..a207bfe 100644
--- a/res/values-hi/strings.xml
+++ b/res/values-hi/strings.xml
@@ -19,9 +19,7 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_name" msgid="1647136562008520313">"वॉलपेपर और स्टाइल"</string>
<string name="theme_title" msgid="2144932106319405101">"शैली"</string>
- <string name="clock_title" msgid="1974314575211361352">"घड़ी का आइकॉन"</string>
- <string name="clock_description" msgid="3563839327378948">"घड़ी आइकॉन चुनें"</string>
- <string name="clock_picker_entry_content_description" msgid="8377139273468595734">"पसंद के मुताबिक घड़ी का आइकॉन बदलें"</string>
+ <string name="clock_title" msgid="2126046720254613991">"घड़ी"</string>
<string name="grid_title" msgid="1688173478777254123">"ऐप्लिकेशन ग्रिड"</string>
<string name="apply_theme_btn" msgid="6293081192321303991">"लागू करें"</string>
<string name="edit_custom_theme_lbl" msgid="5211377705710775224">"बदलाव करने के लिए टैप करें"</string>
@@ -91,15 +89,4 @@
<string name="preset_color_tab" msgid="3133391839341329314">"सामान्य रंग"</string>
<string name="color_changed" msgid="7029571720331641235">"रंग बदल दिया गया है"</string>
<string name="adaptive_color_title" msgid="1336508599235896205">"डाइनैमिक"</string>
- <string name="keyguard_slot_name_bottom_start" msgid="6717374042663171860">"बायां बटन"</string>
- <string name="keyguard_slot_name_bottom_end" msgid="7636885379738905151">"दायां बटन"</string>
- <string name="keyguard_affordance_none" msgid="1751643933430782312">"कोई नहीं"</string>
- <string name="keyguard_affordance_enablement_dialog_title" msgid="3389730825561696493">"`<xliff:g id="APPNAME">%1$s</xliff:g>` को चुनने के लिए, दिए गए निर्देशों का पालन करें"</string>
- <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8117011931337357438">"<xliff:g id="APPNAME">%1$s</xliff:g> खोलें"</string>
- <string name="keyguard_affordance_enablement_dialog_message" msgid="6136286758939253570">"<xliff:g id="APPNAME">%1$s</xliff:g> ऐप्लिकेशन को शॉर्टकट के तौर पर जोड़ने के लिए, इन बातों का ध्यान रखें"</string>
- <string name="keyguard_affordance_enablement_dialog_dismiss_button" msgid="629754625264422508">"हो गया"</string>
- <string name="keyguard_quick_affordance_title" msgid="4242813186995735584">"शॉर्टकट"</string>
- <string name="keyguard_quick_affordance_section_title" msgid="2806304242671717309">"शॉर्टकट"</string>
- <string name="keyguard_quick_affordance_two_selected_template" msgid="1757099194522296363">"<xliff:g id="FIRST">%1$s</xliff:g>, <xliff:g id="SECOND">%2$s</xliff:g>"</string>
- <string name="keyguard_quick_affordance_none_selected" msgid="8494127020144112003">"कोई नहीं"</string>
</resources>
diff --git a/res/values-hr/strings.xml b/res/values-hr/strings.xml
index 88d0f50..b603fa6 100644
--- a/res/values-hr/strings.xml
+++ b/res/values-hr/strings.xml
@@ -19,9 +19,7 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_name" msgid="1647136562008520313">"Pozadina i stil"</string>
<string name="theme_title" msgid="2144932106319405101">"Stil"</string>
- <string name="clock_title" msgid="1974314575211361352">"Prilagođeni sat"</string>
- <string name="clock_description" msgid="3563839327378948">"Odaberite prilagođeni sat"</string>
- <string name="clock_picker_entry_content_description" msgid="8377139273468595734">"Promijenite prilagođeni sat"</string>
+ <string name="clock_title" msgid="2126046720254613991">"Sat"</string>
<string name="grid_title" msgid="1688173478777254123">"Rešetka aplik."</string>
<string name="apply_theme_btn" msgid="6293081192321303991">"Primijeni"</string>
<string name="edit_custom_theme_lbl" msgid="5211377705710775224">"Dodirnite da biste uredili"</string>
@@ -91,15 +89,4 @@
<string name="preset_color_tab" msgid="3133391839341329314">"Osnovne boje"</string>
<string name="color_changed" msgid="7029571720331641235">"Promijenjena boja"</string>
<string name="adaptive_color_title" msgid="1336508599235896205">"Dinamično"</string>
- <string name="keyguard_slot_name_bottom_start" msgid="6717374042663171860">"Lijevi gumb"</string>
- <string name="keyguard_slot_name_bottom_end" msgid="7636885379738905151">"Desni gumb"</string>
- <string name="keyguard_affordance_none" msgid="1751643933430782312">"Ništa"</string>
- <string name="keyguard_affordance_enablement_dialog_title" msgid="3389730825561696493">"Da biste odabrali <xliff:g id="APPNAME">%1$s</xliff:g>, označite sljedeće"</string>
- <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8117011931337357438">"Otvori <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
- <string name="keyguard_affordance_enablement_dialog_message" msgid="6136286758939253570">"Da biste aplikaciju <xliff:g id="APPNAME">%1$s</xliff:g> dodali kao prečac, učinite sljedeće"</string>
- <string name="keyguard_affordance_enablement_dialog_dismiss_button" msgid="629754625264422508">"Gotovo"</string>
- <string name="keyguard_quick_affordance_title" msgid="4242813186995735584">"Prečaci"</string>
- <string name="keyguard_quick_affordance_section_title" msgid="2806304242671717309">"Prečaci"</string>
- <string name="keyguard_quick_affordance_two_selected_template" msgid="1757099194522296363">"<xliff:g id="FIRST">%1$s</xliff:g>, <xliff:g id="SECOND">%2$s</xliff:g>"</string>
- <string name="keyguard_quick_affordance_none_selected" msgid="8494127020144112003">"Ništa"</string>
</resources>
diff --git a/res/values-hu/strings.xml b/res/values-hu/strings.xml
index 6f52030..620d36c 100644
--- a/res/values-hu/strings.xml
+++ b/res/values-hu/strings.xml
@@ -19,9 +19,7 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_name" msgid="1647136562008520313">"Háttérkép és stílus"</string>
<string name="theme_title" msgid="2144932106319405101">"Stílus"</string>
- <string name="clock_title" msgid="1974314575211361352">"Egyedi óra"</string>
- <string name="clock_description" msgid="3563839327378948">"Egyedi óra választása"</string>
- <string name="clock_picker_entry_content_description" msgid="8377139273468595734">"Egyedi óra módosítása"</string>
+ <string name="clock_title" msgid="2126046720254613991">"Óra"</string>
<string name="grid_title" msgid="1688173478777254123">"Alkalmazásrács"</string>
<string name="apply_theme_btn" msgid="6293081192321303991">"Alkalmaz"</string>
<string name="edit_custom_theme_lbl" msgid="5211377705710775224">"Koppintson a szerkesztéshez"</string>
@@ -91,15 +89,4 @@
<string name="preset_color_tab" msgid="3133391839341329314">"Alapszínek"</string>
<string name="color_changed" msgid="7029571720331641235">"Szín módosítva"</string>
<string name="adaptive_color_title" msgid="1336508599235896205">"Dinamikus"</string>
- <string name="keyguard_slot_name_bottom_start" msgid="6717374042663171860">"Balra gomb"</string>
- <string name="keyguard_slot_name_bottom_end" msgid="7636885379738905151">"Jobbra gomb"</string>
- <string name="keyguard_affordance_none" msgid="1751643933430782312">"Nincs"</string>
- <string name="keyguard_affordance_enablement_dialog_title" msgid="3389730825561696493">"A(z) „<xliff:g id="APPNAME">%1$s</xliff:g>” kiválasztásához el kell végeznie a következőket"</string>
- <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8117011931337357438">"A(z) <xliff:g id="APPNAME">%1$s</xliff:g> megnyitása"</string>
- <string name="keyguard_affordance_enablement_dialog_message" msgid="6136286758939253570">"Ha szeretné felvenni a(z) <xliff:g id="APPNAME">%1$s</xliff:g> alkalmazást parancsikonként, gondoskodjon a következőkről:"</string>
- <string name="keyguard_affordance_enablement_dialog_dismiss_button" msgid="629754625264422508">"Kész"</string>
- <string name="keyguard_quick_affordance_title" msgid="4242813186995735584">"Gyorsparancsok"</string>
- <string name="keyguard_quick_affordance_section_title" msgid="2806304242671717309">"Gyorsparancsok"</string>
- <string name="keyguard_quick_affordance_two_selected_template" msgid="1757099194522296363">"<xliff:g id="FIRST">%1$s</xliff:g>, <xliff:g id="SECOND">%2$s</xliff:g>"</string>
- <string name="keyguard_quick_affordance_none_selected" msgid="8494127020144112003">"Nincs"</string>
</resources>
diff --git a/res/values-hy/strings.xml b/res/values-hy/strings.xml
index d8e3da4..7c7d059 100644
--- a/res/values-hy/strings.xml
+++ b/res/values-hy/strings.xml
@@ -19,9 +19,7 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_name" msgid="1647136562008520313">"Պաստառ և ոճ"</string>
<string name="theme_title" msgid="2144932106319405101">"Ոճ"</string>
- <string name="clock_title" msgid="1974314575211361352">"Հատուկ թվատախտակ"</string>
- <string name="clock_description" msgid="3563839327378948">"Ընտրեք թվատախտակ"</string>
- <string name="clock_picker_entry_content_description" msgid="8377139273468595734">"Փոխեք հատուկ թվատախտակը"</string>
+ <string name="clock_title" msgid="2126046720254613991">"Ժամացույց"</string>
<string name="grid_title" msgid="1688173478777254123">"Հավելվածների ցանց"</string>
<string name="apply_theme_btn" msgid="6293081192321303991">"Կիրառել"</string>
<string name="edit_custom_theme_lbl" msgid="5211377705710775224">"Հպեք՝ փոփոխելու համար"</string>
@@ -91,15 +89,4 @@
<string name="preset_color_tab" msgid="3133391839341329314">"Հիմնական գույներ"</string>
<string name="color_changed" msgid="7029571720331641235">"Գույնը փոխվեց"</string>
<string name="adaptive_color_title" msgid="1336508599235896205">"Դինամիկ"</string>
- <string name="keyguard_slot_name_bottom_start" msgid="6717374042663171860">"«Ձախ» կոճակ"</string>
- <string name="keyguard_slot_name_bottom_end" msgid="7636885379738905151">"«Աջ» կոճակ"</string>
- <string name="keyguard_affordance_none" msgid="1751643933430782312">"Ոչ մեկը"</string>
- <string name="keyguard_affordance_enablement_dialog_title" msgid="3389730825561696493">"«<xliff:g id="APPNAME">%1$s</xliff:g>» հավելվածն ընտրելու համար կատարեք հետևյալը"</string>
- <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8117011931337357438">"Բացել <xliff:g id="APPNAME">%1$s</xliff:g> հավելվածը"</string>
- <string name="keyguard_affordance_enablement_dialog_message" msgid="6136286758939253570">"<xliff:g id="APPNAME">%1$s</xliff:g> հավելվածի դյուրանցումն ավելացնելու համար համոզվեք, որ՝"</string>
- <string name="keyguard_affordance_enablement_dialog_dismiss_button" msgid="629754625264422508">"Պատրաստ է"</string>
- <string name="keyguard_quick_affordance_title" msgid="4242813186995735584">"Դյուրանցումներ"</string>
- <string name="keyguard_quick_affordance_section_title" msgid="2806304242671717309">"Դյուրանցումներ"</string>
- <string name="keyguard_quick_affordance_two_selected_template" msgid="1757099194522296363">"<xliff:g id="FIRST">%1$s</xliff:g>, <xliff:g id="SECOND">%2$s</xliff:g>"</string>
- <string name="keyguard_quick_affordance_none_selected" msgid="8494127020144112003">"Ընտրված չէ"</string>
</resources>
diff --git a/res/values-in/strings.xml b/res/values-in/strings.xml
index 27bd725..7e48536 100644
--- a/res/values-in/strings.xml
+++ b/res/values-in/strings.xml
@@ -19,9 +19,7 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_name" msgid="1647136562008520313">"Wallpaper & gaya"</string>
<string name="theme_title" msgid="2144932106319405101">"Gaya"</string>
- <string name="clock_title" msgid="1974314575211361352">"Jam Kustom"</string>
- <string name="clock_description" msgid="3563839327378948">"Pilih jam kustom"</string>
- <string name="clock_picker_entry_content_description" msgid="8377139273468595734">"Ubah jam kustom"</string>
+ <string name="clock_title" msgid="2126046720254613991">"Jam"</string>
<string name="grid_title" msgid="1688173478777254123">"Petak aplikasi"</string>
<string name="apply_theme_btn" msgid="6293081192321303991">"Terapkan"</string>
<string name="edit_custom_theme_lbl" msgid="5211377705710775224">"Ketuk untuk mengedit"</string>
@@ -50,7 +48,7 @@
<string name="applied_theme_msg" msgid="3749018706366796244">"Gaya berhasil disetel"</string>
<string name="applied_clock_msg" msgid="1303338016701443767">"Jam berhasil disetel"</string>
<string name="applied_grid_msg" msgid="3250499654436933034">"Petak berhasil disetel"</string>
- <string name="apply_theme_error_msg" msgid="791364062636538317">"Terjadi error saat menerapkan gaya"</string>
+ <string name="apply_theme_error_msg" msgid="791364062636538317">"Terjadi masalah saat menerapkan gaya"</string>
<string name="custom_theme_next" msgid="6235420097213197301">"Berikutnya"</string>
<string name="custom_theme_previous" msgid="4941132112640503022">"Sebelumnya"</string>
<string name="custom_theme" msgid="1618351922263478163">"Kustom"</string>
@@ -72,7 +70,7 @@
<string name="use_style_button" msgid="1754493078383627019">"Gunakan <xliff:g id="ID_1">%1$s</xliff:g>"</string>
<string name="no_thanks" msgid="7286616980115687627">"Lain kali"</string>
<string name="clock_preview_content_description" msgid="5460561185905717460">"Pratinjau jam <xliff:g id="ID_1">%1$s</xliff:g>"</string>
- <string name="something_went_wrong" msgid="529840112449799117">"Maaf, terjadi error."</string>
+ <string name="something_went_wrong" msgid="529840112449799117">"Ups! Ada yang tidak beres."</string>
<string name="theme_preview_icons_section_title" msgid="7064768910744000643">"Warna/Ikon"</string>
<string name="style_info_description" msgid="2612473574431003251">"Pratinjau font, ikon, bentuk aplikasi, dan warna"</string>
<string name="accessibility_custom_font_title" msgid="966867359157303705">"Font khusus"</string>
@@ -91,15 +89,4 @@
<string name="preset_color_tab" msgid="3133391839341329314">"Warna dasar"</string>
<string name="color_changed" msgid="7029571720331641235">"Warna diubah"</string>
<string name="adaptive_color_title" msgid="1336508599235896205">"Dinamis"</string>
- <string name="keyguard_slot_name_bottom_start" msgid="6717374042663171860">"Tombol kiri"</string>
- <string name="keyguard_slot_name_bottom_end" msgid="7636885379738905151">"Tombol kanan"</string>
- <string name="keyguard_affordance_none" msgid="1751643933430782312">"Tidak ada"</string>
- <string name="keyguard_affordance_enablement_dialog_title" msgid="3389730825561696493">"Untuk memilih `<xliff:g id="APPNAME">%1$s</xliff:g>`, periksa hal berikut"</string>
- <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8117011931337357438">"Buka <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
- <string name="keyguard_affordance_enablement_dialog_message" msgid="6136286758939253570">"Untuk menambahkan aplikasi <xliff:g id="APPNAME">%1$s</xliff:g> sebagai pintasan, pastikan"</string>
- <string name="keyguard_affordance_enablement_dialog_dismiss_button" msgid="629754625264422508">"Selesai"</string>
- <string name="keyguard_quick_affordance_title" msgid="4242813186995735584">"Pintasan"</string>
- <string name="keyguard_quick_affordance_section_title" msgid="2806304242671717309">"Pintasan"</string>
- <string name="keyguard_quick_affordance_two_selected_template" msgid="1757099194522296363">"<xliff:g id="FIRST">%1$s</xliff:g>, <xliff:g id="SECOND">%2$s</xliff:g>"</string>
- <string name="keyguard_quick_affordance_none_selected" msgid="8494127020144112003">"Tidak ada"</string>
</resources>
diff --git a/res/values-is/strings.xml b/res/values-is/strings.xml
index c0dd203..9312a5c 100644
--- a/res/values-is/strings.xml
+++ b/res/values-is/strings.xml
@@ -19,9 +19,7 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_name" msgid="1647136562008520313">"Veggfóður og stíll"</string>
<string name="theme_title" msgid="2144932106319405101">"Stíll"</string>
- <string name="clock_title" msgid="1974314575211361352">"Sérsniðin klukka"</string>
- <string name="clock_description" msgid="3563839327378948">"Veldu sérsniðna klukku"</string>
- <string name="clock_picker_entry_content_description" msgid="8377139273468595734">"Breyta sérsniðinni klukku"</string>
+ <string name="clock_title" msgid="2126046720254613991">"Klukka"</string>
<string name="grid_title" msgid="1688173478777254123">"Forritatafla"</string>
<string name="apply_theme_btn" msgid="6293081192321303991">"Nota"</string>
<string name="edit_custom_theme_lbl" msgid="5211377705710775224">"Ýttu til að breyta"</string>
@@ -91,15 +89,4 @@
<string name="preset_color_tab" msgid="3133391839341329314">"Grunnlitir"</string>
<string name="color_changed" msgid="7029571720331641235">"Lit breytt"</string>
<string name="adaptive_color_title" msgid="1336508599235896205">"Breytilegt"</string>
- <string name="keyguard_slot_name_bottom_start" msgid="6717374042663171860">"Vinstri hnappur"</string>
- <string name="keyguard_slot_name_bottom_end" msgid="7636885379738905151">"Hægri hnappur"</string>
- <string name="keyguard_affordance_none" msgid="1751643933430782312">"Ekkert"</string>
- <string name="keyguard_affordance_enablement_dialog_title" msgid="3389730825561696493">"Til að velja „<xliff:g id="APPNAME">%1$s</xliff:g>“ skaltu athuga eftirfarandi"</string>
- <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8117011931337357438">"Opna <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
- <string name="keyguard_affordance_enablement_dialog_message" msgid="6136286758939253570">"Til að bæta forritinu <xliff:g id="APPNAME">%1$s</xliff:g> við sem flýtileið skaltu ganga úr skugga um að"</string>
- <string name="keyguard_affordance_enablement_dialog_dismiss_button" msgid="629754625264422508">"Lokið"</string>
- <string name="keyguard_quick_affordance_title" msgid="4242813186995735584">"Flýtileiðir"</string>
- <string name="keyguard_quick_affordance_section_title" msgid="2806304242671717309">"Flýtileiðir"</string>
- <string name="keyguard_quick_affordance_two_selected_template" msgid="1757099194522296363">"<xliff:g id="FIRST">%1$s</xliff:g>, <xliff:g id="SECOND">%2$s</xliff:g>"</string>
- <string name="keyguard_quick_affordance_none_selected" msgid="8494127020144112003">"Ekkert"</string>
</resources>
diff --git a/res/values-it/strings.xml b/res/values-it/strings.xml
index 0403b12..08df999 100644
--- a/res/values-it/strings.xml
+++ b/res/values-it/strings.xml
@@ -19,9 +19,7 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_name" msgid="1647136562008520313">"Sfondo e stile"</string>
<string name="theme_title" msgid="2144932106319405101">"Stile"</string>
- <string name="clock_title" msgid="1974314575211361352">"Orologio personalizzato"</string>
- <string name="clock_description" msgid="3563839327378948">"Scegli un orologio personalizzato"</string>
- <string name="clock_picker_entry_content_description" msgid="8377139273468595734">"Modifica un orologio personalizzato"</string>
+ <string name="clock_title" msgid="2126046720254613991">"Orologio"</string>
<string name="grid_title" msgid="1688173478777254123">"Griglia di app"</string>
<string name="apply_theme_btn" msgid="6293081192321303991">"Applica"</string>
<string name="edit_custom_theme_lbl" msgid="5211377705710775224">"Tocca per modificare"</string>
@@ -91,15 +89,4 @@
<string name="preset_color_tab" msgid="3133391839341329314">"Colori di base"</string>
<string name="color_changed" msgid="7029571720331641235">"Colore modificato"</string>
<string name="adaptive_color_title" msgid="1336508599235896205">"Dinamica"</string>
- <string name="keyguard_slot_name_bottom_start" msgid="6717374042663171860">"Puls. sinistro"</string>
- <string name="keyguard_slot_name_bottom_end" msgid="7636885379738905151">"Puls. destro"</string>
- <string name="keyguard_affordance_none" msgid="1751643933430782312">"Nessuno"</string>
- <string name="keyguard_affordance_enablement_dialog_title" msgid="3389730825561696493">"Per poter selezionare \"<xliff:g id="APPNAME">%1$s</xliff:g>\", devi controllare quanto segue:"</string>
- <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8117011931337357438">"Apri <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
- <string name="keyguard_affordance_enablement_dialog_message" msgid="6136286758939253570">"Per aggiungere l\'app <xliff:g id="APPNAME">%1$s</xliff:g> come scorciatoia, assicurati che:"</string>
- <string name="keyguard_affordance_enablement_dialog_dismiss_button" msgid="629754625264422508">"Fine"</string>
- <string name="keyguard_quick_affordance_title" msgid="4242813186995735584">"Scorciatoie"</string>
- <string name="keyguard_quick_affordance_section_title" msgid="2806304242671717309">"Scorciatoie"</string>
- <string name="keyguard_quick_affordance_two_selected_template" msgid="1757099194522296363">"<xliff:g id="FIRST">%1$s</xliff:g>, <xliff:g id="SECOND">%2$s</xliff:g>"</string>
- <string name="keyguard_quick_affordance_none_selected" msgid="8494127020144112003">"Nessun elemento"</string>
</resources>
diff --git a/res/values-iw/strings.xml b/res/values-iw/strings.xml
index 6cc8e61..5d9e2d9 100644
--- a/res/values-iw/strings.xml
+++ b/res/values-iw/strings.xml
@@ -19,9 +19,7 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_name" msgid="1647136562008520313">"טפט וסגנון"</string>
<string name="theme_title" msgid="2144932106319405101">"סגנון"</string>
- <string name="clock_title" msgid="1974314575211361352">"שעון מותאם אישית"</string>
- <string name="clock_description" msgid="3563839327378948">"בחירת שעון מותאם אישית"</string>
- <string name="clock_picker_entry_content_description" msgid="8377139273468595734">"שינוי שעון מותאם אישית"</string>
+ <string name="clock_title" msgid="2126046720254613991">"שעון"</string>
<string name="grid_title" msgid="1688173478777254123">"תצוגת האפליקציות"</string>
<string name="apply_theme_btn" msgid="6293081192321303991">"אישור"</string>
<string name="edit_custom_theme_lbl" msgid="5211377705710775224">"יש להקיש כדי לערוך"</string>
@@ -91,15 +89,4 @@
<string name="preset_color_tab" msgid="3133391839341329314">"הצבעים הבסיסיים"</string>
<string name="color_changed" msgid="7029571720331641235">"הצבע השתנה"</string>
<string name="adaptive_color_title" msgid="1336508599235896205">"דינמי"</string>
- <string name="keyguard_slot_name_bottom_start" msgid="6717374042663171860">"הלחצן השמאלי"</string>
- <string name="keyguard_slot_name_bottom_end" msgid="7636885379738905151">"הלחצן הימני"</string>
- <string name="keyguard_affordance_none" msgid="1751643933430782312">"ללא"</string>
- <string name="keyguard_affordance_enablement_dialog_title" msgid="3389730825561696493">"כדי לבחור באפליקציה <xliff:g id="APPNAME">%1$s</xliff:g> צריך לסמן את האפשרויות הבאות"</string>
- <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8117011931337357438">"פתיחת <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
- <string name="keyguard_affordance_enablement_dialog_message" msgid="6136286758939253570">"כדי להוסיף את האפליקציה <xliff:g id="APPNAME">%1$s</xliff:g> כקיצור דרך, צריך לוודא"</string>
- <string name="keyguard_affordance_enablement_dialog_dismiss_button" msgid="629754625264422508">"סיום"</string>
- <string name="keyguard_quick_affordance_title" msgid="4242813186995735584">"קיצורי דרך"</string>
- <string name="keyguard_quick_affordance_section_title" msgid="2806304242671717309">"קיצורי דרך"</string>
- <string name="keyguard_quick_affordance_two_selected_template" msgid="1757099194522296363">"<xliff:g id="FIRST">%1$s</xliff:g>, <xliff:g id="SECOND">%2$s</xliff:g>"</string>
- <string name="keyguard_quick_affordance_none_selected" msgid="8494127020144112003">"ללא"</string>
</resources>
diff --git a/res/values-ja/strings.xml b/res/values-ja/strings.xml
index 6ddd7ae..f6a20d3 100644
--- a/res/values-ja/strings.xml
+++ b/res/values-ja/strings.xml
@@ -19,9 +19,7 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_name" msgid="1647136562008520313">"壁紙とスタイル"</string>
<string name="theme_title" msgid="2144932106319405101">"スタイル"</string>
- <string name="clock_title" msgid="1974314575211361352">"カスタム文字盤"</string>
- <string name="clock_description" msgid="3563839327378948">"文字盤の選択"</string>
- <string name="clock_picker_entry_content_description" msgid="8377139273468595734">"文字盤の変更"</string>
+ <string name="clock_title" msgid="2126046720254613991">"時計"</string>
<string name="grid_title" msgid="1688173478777254123">"アプリグリッド"</string>
<string name="apply_theme_btn" msgid="6293081192321303991">"適用"</string>
<string name="edit_custom_theme_lbl" msgid="5211377705710775224">"タップして編集"</string>
@@ -91,15 +89,4 @@
<string name="preset_color_tab" msgid="3133391839341329314">"基本の色"</string>
<string name="color_changed" msgid="7029571720331641235">"色を変更しました"</string>
<string name="adaptive_color_title" msgid="1336508599235896205">"動的"</string>
- <string name="keyguard_slot_name_bottom_start" msgid="6717374042663171860">"左ボタン"</string>
- <string name="keyguard_slot_name_bottom_end" msgid="7636885379738905151">"右ボタン"</string>
- <string name="keyguard_affordance_none" msgid="1751643933430782312">"なし"</string>
- <string name="keyguard_affordance_enablement_dialog_title" msgid="3389730825561696493">"「<xliff:g id="APPNAME">%1$s</xliff:g>」を選択するには、以下を確認します"</string>
- <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8117011931337357438">"<xliff:g id="APPNAME">%1$s</xliff:g> を開きます。"</string>
- <string name="keyguard_affordance_enablement_dialog_message" msgid="6136286758939253570">"<xliff:g id="APPNAME">%1$s</xliff:g> アプリをショートカットとして追加するための手順"</string>
- <string name="keyguard_affordance_enablement_dialog_dismiss_button" msgid="629754625264422508">"完了"</string>
- <string name="keyguard_quick_affordance_title" msgid="4242813186995735584">"ショートカット"</string>
- <string name="keyguard_quick_affordance_section_title" msgid="2806304242671717309">"ショートカット"</string>
- <string name="keyguard_quick_affordance_two_selected_template" msgid="1757099194522296363">"<xliff:g id="FIRST">%1$s</xliff:g>、<xliff:g id="SECOND">%2$s</xliff:g>"</string>
- <string name="keyguard_quick_affordance_none_selected" msgid="8494127020144112003">"なし"</string>
</resources>
diff --git a/res/values-ka/strings.xml b/res/values-ka/strings.xml
index 892779f..7fb2f96 100644
--- a/res/values-ka/strings.xml
+++ b/res/values-ka/strings.xml
@@ -19,9 +19,7 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_name" msgid="1647136562008520313">"ფონი და სტილი"</string>
<string name="theme_title" msgid="2144932106319405101">"სტილი"</string>
- <string name="clock_title" msgid="1974314575211361352">"მორგებული საათი"</string>
- <string name="clock_description" msgid="3563839327378948">"აირჩიეთ მორგებული საათი"</string>
- <string name="clock_picker_entry_content_description" msgid="8377139273468595734">"შეცვალეთ მორგებული საათი"</string>
+ <string name="clock_title" msgid="2126046720254613991">"საათი"</string>
<string name="grid_title" msgid="1688173478777254123">"აპების ბადე"</string>
<string name="apply_theme_btn" msgid="6293081192321303991">"მისადაგება"</string>
<string name="edit_custom_theme_lbl" msgid="5211377705710775224">"შეეხეთ რედაქტირებისთვის"</string>
@@ -91,15 +89,4 @@
<string name="preset_color_tab" msgid="3133391839341329314">"ძირითადი ფერები"</string>
<string name="color_changed" msgid="7029571720331641235">"ფერი შეიცვალა"</string>
<string name="adaptive_color_title" msgid="1336508599235896205">"დინამიკური"</string>
- <string name="keyguard_slot_name_bottom_start" msgid="6717374042663171860">"მარცხენა ღილაკი"</string>
- <string name="keyguard_slot_name_bottom_end" msgid="7636885379738905151">"მარჯვენა ღილაკი"</string>
- <string name="keyguard_affordance_none" msgid="1751643933430782312">"არცერთი"</string>
- <string name="keyguard_affordance_enablement_dialog_title" msgid="3389730825561696493">"„<xliff:g id="APPNAME">%1$s</xliff:g>“-ის ასარჩევად შეამოწმეთ შემდეგი"</string>
- <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8117011931337357438">"<xliff:g id="APPNAME">%1$s</xliff:g>-ის გახსნა"</string>
- <string name="keyguard_affordance_enablement_dialog_message" msgid="6136286758939253570">"<xliff:g id="APPNAME">%1$s</xliff:g> აპი რომ მალსახმობის სახით დაამატოთ, დარწმუნდით, რომ"</string>
- <string name="keyguard_affordance_enablement_dialog_dismiss_button" msgid="629754625264422508">"მზადაა"</string>
- <string name="keyguard_quick_affordance_title" msgid="4242813186995735584">"მალსახმობები"</string>
- <string name="keyguard_quick_affordance_section_title" msgid="2806304242671717309">"მალსახმობები"</string>
- <string name="keyguard_quick_affordance_two_selected_template" msgid="1757099194522296363">"<xliff:g id="FIRST">%1$s</xliff:g>, <xliff:g id="SECOND">%2$s</xliff:g>"</string>
- <string name="keyguard_quick_affordance_none_selected" msgid="8494127020144112003">"არცერთი"</string>
</resources>
diff --git a/res/values-kk/strings.xml b/res/values-kk/strings.xml
index 7e85152..c62d6a0 100644
--- a/res/values-kk/strings.xml
+++ b/res/values-kk/strings.xml
@@ -19,19 +19,17 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_name" msgid="1647136562008520313">"Тұсқағаз және стиль"</string>
<string name="theme_title" msgid="2144932106319405101">"Стиль"</string>
- <string name="clock_title" msgid="1974314575211361352">"Арнаулы сағат"</string>
- <string name="clock_description" msgid="3563839327378948">"Арнаулы сағатты таңдау"</string>
- <string name="clock_picker_entry_content_description" msgid="8377139273468595734">"Арнаулы сағатты өзгерту"</string>
+ <string name="clock_title" msgid="2126046720254613991">"Cағат"</string>
<string name="grid_title" msgid="1688173478777254123">"Қолданба торы"</string>
<string name="apply_theme_btn" msgid="6293081192321303991">"Қолдану"</string>
<string name="edit_custom_theme_lbl" msgid="5211377705710775224">"Өзгерту үшін түртіңіз"</string>
<string name="keep_my_wallpaper" msgid="8012385376769568517">"Қазіргі тұсқағазды қалдыру"</string>
- <string name="theme_preview_card_content_description" msgid="5989222908619535533">"Стильді алдын ала көру"</string>
- <string name="grid_preview_card_content_description" msgid="8449383777584714842">"Торды алдын ала көру"</string>
- <string name="font_preview_content_description" msgid="128230439293337891">"Қаріпті алдын ала көру"</string>
- <string name="icon_preview_content_description" msgid="7761101284351952890">"Белгішені алдын ала көру"</string>
- <string name="color_preview_content_description" msgid="4879120462082058124">"Түсті алдын ала көру"</string>
- <string name="shape_preview_content_description" msgid="6479487796176550432">"Пішінді алдын ала көру"</string>
+ <string name="theme_preview_card_content_description" msgid="5989222908619535533">"Стильді алдын ала қарау"</string>
+ <string name="grid_preview_card_content_description" msgid="8449383777584714842">"Торды алдын ала қарау"</string>
+ <string name="font_preview_content_description" msgid="128230439293337891">"Қаріпті алдын ала қарау"</string>
+ <string name="icon_preview_content_description" msgid="7761101284351952890">"Белгішені алдын ала қарау"</string>
+ <string name="color_preview_content_description" msgid="4879120462082058124">"Түсті алдын ала қарау"</string>
+ <string name="shape_preview_content_description" msgid="6479487796176550432">"Пішінді алдын ала қарау"</string>
<string name="option_applied_description" msgid="5022305212078053534">"<xliff:g id="ID_1">%1$s</xliff:g>, қазір қосулы"</string>
<string name="option_applied_previewed_description" msgid="5269654286638446858">"<xliff:g id="ID_1">%1$s</xliff:g>, қазір қолданылды және алдын ала қаралды"</string>
<string name="option_previewed_description" msgid="3467217598865047661">"<xliff:g id="ID_1">%1$s</xliff:g>, қазір алдын ала қаралды"</string>
@@ -71,10 +69,10 @@
<string name="use_style_instead_body" msgid="3051937045807471496">"Таңдаған компоненттеріңіз <xliff:g id="ID_1">%1$s</xliff:g> стиліне сәйкес келеді. Орнына <xliff:g id="ID_2">%1$s</xliff:g> стилін пайдаланғыңыз келе ме?"</string>
<string name="use_style_button" msgid="1754493078383627019">"<xliff:g id="ID_1">%1$s</xliff:g> таңдалсын"</string>
<string name="no_thanks" msgid="7286616980115687627">"Жоқ, рақмет"</string>
- <string name="clock_preview_content_description" msgid="5460561185905717460">"<xliff:g id="ID_1">%1$s</xliff:g> сағатын алдын ала көру"</string>
+ <string name="clock_preview_content_description" msgid="5460561185905717460">"<xliff:g id="ID_1">%1$s</xliff:g> сағатын алдын ала қарау"</string>
<string name="something_went_wrong" msgid="529840112449799117">"Қап! Бірдеңе дұрыс болмады."</string>
<string name="theme_preview_icons_section_title" msgid="7064768910744000643">"Түс/Белгішелер"</string>
- <string name="style_info_description" msgid="2612473574431003251">"Қаріпті, белгішелерді, қолданба пішінін алдын ала көру"</string>
+ <string name="style_info_description" msgid="2612473574431003251">"Қаріпті, белгішелерді, қолданба пішінін алдын ала қарау"</string>
<string name="accessibility_custom_font_title" msgid="966867359157303705">"Арнаулы қаріп"</string>
<string name="accessibility_custom_icon_title" msgid="5753297905849062296">"Арнаулы белгіше"</string>
<string name="accessibility_custom_color_title" msgid="4124246598886320663">"Арнаулы түс"</string>
@@ -91,15 +89,4 @@
<string name="preset_color_tab" msgid="3133391839341329314">"Негізгі түстер"</string>
<string name="color_changed" msgid="7029571720331641235">"Түс өзгертілді."</string>
<string name="adaptive_color_title" msgid="1336508599235896205">"Динамикалық"</string>
- <string name="keyguard_slot_name_bottom_start" msgid="6717374042663171860">"Сол жақ түйме"</string>
- <string name="keyguard_slot_name_bottom_end" msgid="7636885379738905151">"Оң жақ түйме"</string>
- <string name="keyguard_affordance_none" msgid="1751643933430782312">"Жоқ"</string>
- <string name="keyguard_affordance_enablement_dialog_title" msgid="3389730825561696493">"\"<xliff:g id="APPNAME">%1$s</xliff:g>\" қолданбасын таңдау үшін мынаны орындаңыз:"</string>
- <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8117011931337357438">"<xliff:g id="APPNAME">%1$s</xliff:g> қолданбасын ашу"</string>
- <string name="keyguard_affordance_enablement_dialog_message" msgid="6136286758939253570">"<xliff:g id="APPNAME">%1$s</xliff:g> қолданбасын таңбаша ретінде қосу үшін келесі әрекеттерді орындауды ұмытпаңыз:"</string>
- <string name="keyguard_affordance_enablement_dialog_dismiss_button" msgid="629754625264422508">"Дайын"</string>
- <string name="keyguard_quick_affordance_title" msgid="4242813186995735584">"Жылдам пәрмендер"</string>
- <string name="keyguard_quick_affordance_section_title" msgid="2806304242671717309">"Жылдам пәрмендер"</string>
- <string name="keyguard_quick_affordance_two_selected_template" msgid="1757099194522296363">"<xliff:g id="FIRST">%1$s</xliff:g>, <xliff:g id="SECOND">%2$s</xliff:g>"</string>
- <string name="keyguard_quick_affordance_none_selected" msgid="8494127020144112003">"Ешқандай"</string>
</resources>
diff --git a/res/values-km/strings.xml b/res/values-km/strings.xml
index 7c6d39b..02080a7 100644
--- a/res/values-km/strings.xml
+++ b/res/values-km/strings.xml
@@ -19,9 +19,7 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_name" msgid="1647136562008520313">"ផ្ទាំងរូបភាព និងរចនាប័ទ្ម"</string>
<string name="theme_title" msgid="2144932106319405101">"រចនាប័ទ្ម"</string>
- <string name="clock_title" msgid="1974314575211361352">"នាឡិកាផ្ទាល់ខ្លួន"</string>
- <string name="clock_description" msgid="3563839327378948">"ជ្រើសរើសនាឡិកាផ្ទាល់ខ្លួន"</string>
- <string name="clock_picker_entry_content_description" msgid="8377139273468595734">"ប្ដូរនាឡិកាផ្ទាល់ខ្លួន"</string>
+ <string name="clock_title" msgid="2126046720254613991">"នាឡិកា"</string>
<string name="grid_title" msgid="1688173478777254123">"ក្រឡាកម្មវិធី"</string>
<string name="apply_theme_btn" msgid="6293081192321303991">"ប្រើ"</string>
<string name="edit_custom_theme_lbl" msgid="5211377705710775224">"ចុច ដើម្បីកែ"</string>
@@ -83,7 +81,7 @@
<string name="mode_title" msgid="2394873501427436055">"រចនាប័ទ្មងងឹត"</string>
<string name="mode_disabled_msg" msgid="9196245518435936512">"បានបិទជាបណ្តោះអាសន្ន ដោយសារមុខងារសន្សំថ្ម"</string>
<string name="mode_changed" msgid="2243581369395418584">"បានផ្លាស់ប្ដូររចនាប័ទ្ម"</string>
- <string name="themed_icon_title" msgid="7312460430471956558">"រូបតំណាងប្ដូរតាមទម្រង់រចនា"</string>
+ <string name="themed_icon_title" msgid="7312460430471956558">"រូបតំណាងប្ដូររចនាប័ទ្ម"</string>
<string name="beta_title" msgid="8703819523760746458">"បេតា"</string>
<string name="gird_picker_entry_content_description" msgid="9087651470212293439">"ប្ដូរក្រឡាកម្មវិធី"</string>
<string name="wallpaper_color_tab" msgid="1447926591721403840">"ពណ៌ផ្ទាំងរូបភាព"</string>
@@ -91,15 +89,4 @@
<string name="preset_color_tab" msgid="3133391839341329314">"ពណ៌លំនាំដើម"</string>
<string name="color_changed" msgid="7029571720331641235">"បានផ្លាស់ប្ដូរពណ៌"</string>
<string name="adaptive_color_title" msgid="1336508599235896205">"ឌីណាមិក"</string>
- <string name="keyguard_slot_name_bottom_start" msgid="6717374042663171860">"ប៊ូតុងឆ្វេង"</string>
- <string name="keyguard_slot_name_bottom_end" msgid="7636885379738905151">"ប៊ូតុងស្ដាំ"</string>
- <string name="keyguard_affordance_none" msgid="1751643933430782312">"គ្មាន"</string>
- <string name="keyguard_affordance_enablement_dialog_title" msgid="3389730825561696493">"ដើម្បីជ្រើសរើស `<xliff:g id="APPNAME">%1$s</xliff:g>` សូមពិនិត្យមើលខាងក្រោម"</string>
- <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8117011931337357438">"បើក <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
- <string name="keyguard_affordance_enablement_dialog_message" msgid="6136286758939253570">"ដើម្បីបញ្ចូលកម្មវិធី <xliff:g id="APPNAME">%1$s</xliff:g> ជាផ្លូវកាត់ សូមប្រាកដថា"</string>
- <string name="keyguard_affordance_enablement_dialog_dismiss_button" msgid="629754625264422508">"រួចរាល់"</string>
- <string name="keyguard_quick_affordance_title" msgid="4242813186995735584">"ផ្លូវកាត់"</string>
- <string name="keyguard_quick_affordance_section_title" msgid="2806304242671717309">"ផ្លូវកាត់"</string>
- <string name="keyguard_quick_affordance_two_selected_template" msgid="1757099194522296363">"<xliff:g id="FIRST">%1$s</xliff:g>, <xliff:g id="SECOND">%2$s</xliff:g>"</string>
- <string name="keyguard_quick_affordance_none_selected" msgid="8494127020144112003">"គ្មាន"</string>
</resources>
diff --git a/res/values-kn/strings.xml b/res/values-kn/strings.xml
index c5ddca1..95d8df3 100644
--- a/res/values-kn/strings.xml
+++ b/res/values-kn/strings.xml
@@ -19,9 +19,7 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_name" msgid="1647136562008520313">"ವಾಲ್ಪೇಪರ್ ಮತ್ತು ಶೈಲಿ"</string>
<string name="theme_title" msgid="2144932106319405101">"ಶೈಲಿ"</string>
- <string name="clock_title" msgid="1974314575211361352">"ಕಸ್ಟಮ್ ಗಡಿಯಾರ"</string>
- <string name="clock_description" msgid="3563839327378948">"ಕಸ್ಟಮ್ ವಾಚ್ ಪಿಕ್"</string>
- <string name="clock_picker_entry_content_description" msgid="8377139273468595734">"ಕಸ್ಟಮ್ ಗಡಿಯಾರ ಬದಲಿಸಿ"</string>
+ <string name="clock_title" msgid="2126046720254613991">"ಗಡಿಯಾರ"</string>
<string name="grid_title" msgid="1688173478777254123">"ಆ್ಯಪ್ ಗ್ರಿಡ್"</string>
<string name="apply_theme_btn" msgid="6293081192321303991">"ಅನ್ವಯಿಸಿ"</string>
<string name="edit_custom_theme_lbl" msgid="5211377705710775224">"ಎಡಿಟ್ ಮಾಡಲು ಟ್ಯಾಪ್ ಮಾಡಿ"</string>
@@ -91,15 +89,4 @@
<string name="preset_color_tab" msgid="3133391839341329314">"ಮೂಲ ಬಣ್ಣಗಳು"</string>
<string name="color_changed" msgid="7029571720331641235">"ಬಣ್ಣ ಬದಲಾಗಿದೆ"</string>
<string name="adaptive_color_title" msgid="1336508599235896205">"ಡೈನಾಮಿಕ್"</string>
- <string name="keyguard_slot_name_bottom_start" msgid="6717374042663171860">"ಎಡಗಡೆಯ ಬಟನ್"</string>
- <string name="keyguard_slot_name_bottom_end" msgid="7636885379738905151">"ಬಲಗಡೆಯ ಬಟನ್"</string>
- <string name="keyguard_affordance_none" msgid="1751643933430782312">"ಯಾವುದೂ ಅಲ್ಲ"</string>
- <string name="keyguard_affordance_enablement_dialog_title" msgid="3389730825561696493">"`<xliff:g id="APPNAME">%1$s</xliff:g>` ಅನ್ನು ಆಯ್ಕೆಮಾಡಲು ಈ ಕೆಳಗಿನವುಗಳನ್ನು ಗುರುತು ಮಾಡಿ"</string>
- <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8117011931337357438">"<xliff:g id="APPNAME">%1$s</xliff:g> ಅನ್ನು ತೆರೆಯಿರಿ"</string>
- <string name="keyguard_affordance_enablement_dialog_message" msgid="6136286758939253570">"<xliff:g id="APPNAME">%1$s</xliff:g> ಆ್ಯಪ್ ಅನ್ನು ಶಾರ್ಟ್ಕಟ್ ಆಗಿ ಸೇರಿಸಲು ಕೆಳಗಿನವುಗಳನ್ನು ಖಚಿತಪಡಿಸಿಕೊಳ್ಳಿ"</string>
- <string name="keyguard_affordance_enablement_dialog_dismiss_button" msgid="629754625264422508">"ಮುಗಿದಿದೆ"</string>
- <string name="keyguard_quick_affordance_title" msgid="4242813186995735584">"ಶಾರ್ಟ್ಕಟ್ಗಳು"</string>
- <string name="keyguard_quick_affordance_section_title" msgid="2806304242671717309">"ಶಾರ್ಟ್ಕಟ್ಗಳು"</string>
- <string name="keyguard_quick_affordance_two_selected_template" msgid="1757099194522296363">"<xliff:g id="FIRST">%1$s</xliff:g>, <xliff:g id="SECOND">%2$s</xliff:g>"</string>
- <string name="keyguard_quick_affordance_none_selected" msgid="8494127020144112003">"ಯಾವುದೂ ಅಲ್ಲ"</string>
</resources>
diff --git a/res/values-ko/strings.xml b/res/values-ko/strings.xml
index d154cbf..25e7d43 100644
--- a/res/values-ko/strings.xml
+++ b/res/values-ko/strings.xml
@@ -19,9 +19,7 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_name" msgid="1647136562008520313">"배경화면 및 스타일"</string>
<string name="theme_title" msgid="2144932106319405101">"스타일"</string>
- <string name="clock_title" msgid="1974314575211361352">"맞춤 시계"</string>
- <string name="clock_description" msgid="3563839327378948">"맞춤 시계 선택"</string>
- <string name="clock_picker_entry_content_description" msgid="8377139273468595734">"맞춤 시계 변경"</string>
+ <string name="clock_title" msgid="2126046720254613991">"시계"</string>
<string name="grid_title" msgid="1688173478777254123">"앱 그리드"</string>
<string name="apply_theme_btn" msgid="6293081192321303991">"적용"</string>
<string name="edit_custom_theme_lbl" msgid="5211377705710775224">"탭하여 수정"</string>
@@ -91,15 +89,4 @@
<string name="preset_color_tab" msgid="3133391839341329314">"기본 색상"</string>
<string name="color_changed" msgid="7029571720331641235">"색상 변경됨"</string>
<string name="adaptive_color_title" msgid="1336508599235896205">"동적"</string>
- <string name="keyguard_slot_name_bottom_start" msgid="6717374042663171860">"왼쪽 버튼"</string>
- <string name="keyguard_slot_name_bottom_end" msgid="7636885379738905151">"오른쪽 버튼"</string>
- <string name="keyguard_affordance_none" msgid="1751643933430782312">"없음"</string>
- <string name="keyguard_affordance_enablement_dialog_title" msgid="3389730825561696493">"`<xliff:g id="APPNAME">%1$s</xliff:g>` 앱을 선택하려면 다음을 선택하세요"</string>
- <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8117011931337357438">"<xliff:g id="APPNAME">%1$s</xliff:g> 열기"</string>
- <string name="keyguard_affordance_enablement_dialog_message" msgid="6136286758939253570">"<xliff:g id="APPNAME">%1$s</xliff:g> 앱을 바로가기로 추가하려면 다음을 확인하세요."</string>
- <string name="keyguard_affordance_enablement_dialog_dismiss_button" msgid="629754625264422508">"완료"</string>
- <string name="keyguard_quick_affordance_title" msgid="4242813186995735584">"단축키"</string>
- <string name="keyguard_quick_affordance_section_title" msgid="2806304242671717309">"단축키"</string>
- <string name="keyguard_quick_affordance_two_selected_template" msgid="1757099194522296363">"<xliff:g id="FIRST">%1$s</xliff:g>, <xliff:g id="SECOND">%2$s</xliff:g>"</string>
- <string name="keyguard_quick_affordance_none_selected" msgid="8494127020144112003">"없음"</string>
</resources>
diff --git a/res/values-ky/strings.xml b/res/values-ky/strings.xml
index 5dcfa46..f7b60ef 100644
--- a/res/values-ky/strings.xml
+++ b/res/values-ky/strings.xml
@@ -19,9 +19,7 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_name" msgid="1647136562008520313">"Тушкагаз жана стиль"</string>
<string name="theme_title" msgid="2144932106319405101">"Стиль"</string>
- <string name="clock_title" msgid="1974314575211361352">"Жеке саат"</string>
- <string name="clock_description" msgid="3563839327378948">"Жеке саатты тандоо"</string>
- <string name="clock_picker_entry_content_description" msgid="8377139273468595734">"Жеке саатты өзгөртүү"</string>
+ <string name="clock_title" msgid="2126046720254613991">"Саат"</string>
<string name="grid_title" msgid="1688173478777254123">"Колдонмонун торчосу"</string>
<string name="apply_theme_btn" msgid="6293081192321303991">"Колдонуу"</string>
<string name="edit_custom_theme_lbl" msgid="5211377705710775224">"Өзгөртүү үчүн таптап коюңуз"</string>
@@ -91,15 +89,4 @@
<string name="preset_color_tab" msgid="3133391839341329314">"Негизги түстөр"</string>
<string name="color_changed" msgid="7029571720331641235">"Түс өзгөртүлдү"</string>
<string name="adaptive_color_title" msgid="1336508599235896205">"Динамикалык"</string>
- <string name="keyguard_slot_name_bottom_start" msgid="6717374042663171860">"Сол баскыч"</string>
- <string name="keyguard_slot_name_bottom_end" msgid="7636885379738905151">"Оң баскыч"</string>
- <string name="keyguard_affordance_none" msgid="1751643933430782312">"Жок"</string>
- <string name="keyguard_affordance_enablement_dialog_title" msgid="3389730825561696493">"\"<xliff:g id="APPNAME">%1$s</xliff:g>\" колдонмосун тандоо үчүн төмөнкүлөрдү аткарыңыз:"</string>
- <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8117011931337357438">"<xliff:g id="APPNAME">%1$s</xliff:g> ачуу"</string>
- <string name="keyguard_affordance_enablement_dialog_message" msgid="6136286758939253570">"<xliff:g id="APPNAME">%1$s</xliff:g> колдонмосун ыкчам баскыч катары кошуу үчүн төмөнкүлөрдү аткарыңыз:"</string>
- <string name="keyguard_affordance_enablement_dialog_dismiss_button" msgid="629754625264422508">"Бүттү"</string>
- <string name="keyguard_quick_affordance_title" msgid="4242813186995735584">"Ыкчам баскычтар"</string>
- <string name="keyguard_quick_affordance_section_title" msgid="2806304242671717309">"Ыкчам баскычтар"</string>
- <string name="keyguard_quick_affordance_two_selected_template" msgid="1757099194522296363">"<xliff:g id="FIRST">%1$s</xliff:g>, <xliff:g id="SECOND">%2$s</xliff:g>"</string>
- <string name="keyguard_quick_affordance_none_selected" msgid="8494127020144112003">"Жок"</string>
</resources>
diff --git a/res/values-lo/strings.xml b/res/values-lo/strings.xml
index 63235c9..8fe51ba 100644
--- a/res/values-lo/strings.xml
+++ b/res/values-lo/strings.xml
@@ -19,9 +19,7 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_name" msgid="1647136562008520313">"ຮູບພື້ນຫຼັງ ແລະ ຮູບແບບ"</string>
<string name="theme_title" msgid="2144932106319405101">"ຮູບແບບ"</string>
- <string name="clock_title" msgid="1974314575211361352">"ໂມງທີ່ກຳນົດເອງ"</string>
- <string name="clock_description" msgid="3563839327378948">"ເລືອກໂມງກຳນົດເອງ"</string>
- <string name="clock_picker_entry_content_description" msgid="8377139273468595734">"ປ່ຽນໂມງກຳນົດເອງ"</string>
+ <string name="clock_title" msgid="2126046720254613991">"ໂມງ"</string>
<string name="grid_title" msgid="1688173478777254123">"ຕາຕະລາງແອັບ"</string>
<string name="apply_theme_btn" msgid="6293081192321303991">"ນຳໃຊ້"</string>
<string name="edit_custom_theme_lbl" msgid="5211377705710775224">"ແຕະເພື່ອແກ້ໄຂ"</string>
@@ -91,15 +89,4 @@
<string name="preset_color_tab" msgid="3133391839341329314">"ສີພື້ນຖານ"</string>
<string name="color_changed" msgid="7029571720331641235">"ປ່ຽນສີແລ້ວ"</string>
<string name="adaptive_color_title" msgid="1336508599235896205">"ໄດນາມິກ"</string>
- <string name="keyguard_slot_name_bottom_start" msgid="6717374042663171860">"ປຸ່ມຊ້າຍ"</string>
- <string name="keyguard_slot_name_bottom_end" msgid="7636885379738905151">"ປຸ່ມຂວາ"</string>
- <string name="keyguard_affordance_none" msgid="1751643933430782312">"ບໍ່ມີ"</string>
- <string name="keyguard_affordance_enablement_dialog_title" msgid="3389730825561696493">"ເພື່ອເລືອກ `<xliff:g id="APPNAME">%1$s</xliff:g>` ກະລຸນາກວດສອບສິ່ງຕໍ່ໄປນີ້"</string>
- <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8117011931337357438">"ເປີດ <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
- <string name="keyguard_affordance_enablement_dialog_message" msgid="6136286758939253570">"ເພື່ອເພີ່ມແອັບ <xliff:g id="APPNAME">%1$s</xliff:g> ເປັນທາງລັດ, ກະລຸນາກວດສອບໃຫ້ແນ່ໃຈວ່າ"</string>
- <string name="keyguard_affordance_enablement_dialog_dismiss_button" msgid="629754625264422508">"ແລ້ວໆ"</string>
- <string name="keyguard_quick_affordance_title" msgid="4242813186995735584">"ທາງລັດ"</string>
- <string name="keyguard_quick_affordance_section_title" msgid="2806304242671717309">"ທາງລັດ"</string>
- <string name="keyguard_quick_affordance_two_selected_template" msgid="1757099194522296363">"<xliff:g id="FIRST">%1$s</xliff:g>, <xliff:g id="SECOND">%2$s</xliff:g>"</string>
- <string name="keyguard_quick_affordance_none_selected" msgid="8494127020144112003">"ບໍ່ມີ"</string>
</resources>
diff --git a/res/values-lt/strings.xml b/res/values-lt/strings.xml
index 5722acd..02b289b 100644
--- a/res/values-lt/strings.xml
+++ b/res/values-lt/strings.xml
@@ -19,9 +19,7 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_name" msgid="1647136562008520313">"Ekrano fonas ir stilius"</string>
<string name="theme_title" msgid="2144932106319405101">"Stilius"</string>
- <string name="clock_title" msgid="1974314575211361352">"Tink. laikrodis"</string>
- <string name="clock_description" msgid="3563839327378948">"Pasir. tink. laikr."</string>
- <string name="clock_picker_entry_content_description" msgid="8377139273468595734">"Keiskite tinkintą laikrodį"</string>
+ <string name="clock_title" msgid="2126046720254613991">"Laikrodis"</string>
<string name="grid_title" msgid="1688173478777254123">"Pr. tinklelis"</string>
<string name="apply_theme_btn" msgid="6293081192321303991">"Taikyti"</string>
<string name="edit_custom_theme_lbl" msgid="5211377705710775224">"Palieskite ir redaguokite"</string>
@@ -91,15 +89,4 @@
<string name="preset_color_tab" msgid="3133391839341329314">"Pagrindinės spalvos"</string>
<string name="color_changed" msgid="7029571720331641235">"Spalva pakeista"</string>
<string name="adaptive_color_title" msgid="1336508599235896205">"Dinaminės"</string>
- <string name="keyguard_slot_name_bottom_start" msgid="6717374042663171860">"Mygtukas kairėn"</string>
- <string name="keyguard_slot_name_bottom_end" msgid="7636885379738905151">"Mygtukas dešinėn"</string>
- <string name="keyguard_affordance_none" msgid="1751643933430782312">"Nėra"</string>
- <string name="keyguard_affordance_enablement_dialog_title" msgid="3389730825561696493">"Jei norite pasirinkti „<xliff:g id="APPNAME">%1$s</xliff:g>“, patikrinkite toliau nurodytus dalykus."</string>
- <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8117011931337357438">"Atidaryti „<xliff:g id="APPNAME">%1$s</xliff:g>“"</string>
- <string name="keyguard_affordance_enablement_dialog_message" msgid="6136286758939253570">"Jei norite pridėti programą „<xliff:g id="APPNAME">%1$s</xliff:g>“ kaip šaukinį, įsitikinkite, kad atitinkate reikalavimus."</string>
- <string name="keyguard_affordance_enablement_dialog_dismiss_button" msgid="629754625264422508">"Atlikta"</string>
- <string name="keyguard_quick_affordance_title" msgid="4242813186995735584">"Šaukiniai"</string>
- <string name="keyguard_quick_affordance_section_title" msgid="2806304242671717309">"Šaukiniai"</string>
- <string name="keyguard_quick_affordance_two_selected_template" msgid="1757099194522296363">"<xliff:g id="FIRST">%1$s</xliff:g>, <xliff:g id="SECOND">%2$s</xliff:g>"</string>
- <string name="keyguard_quick_affordance_none_selected" msgid="8494127020144112003">"Nėra"</string>
</resources>
diff --git a/res/values-lv/strings.xml b/res/values-lv/strings.xml
index b30a850..f8fb310 100644
--- a/res/values-lv/strings.xml
+++ b/res/values-lv/strings.xml
@@ -19,9 +19,7 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_name" msgid="1647136562008520313">"Fona tapete un stils"</string>
<string name="theme_title" msgid="2144932106319405101">"Stils"</string>
- <string name="clock_title" msgid="1974314575211361352">"Pielāgots ekrāns"</string>
- <string name="clock_description" msgid="3563839327378948">"Pielāgota ekrāna izvēle"</string>
- <string name="clock_picker_entry_content_description" msgid="8377139273468595734">"Mainiet pielāgotu pulksteņa ekrānu."</string>
+ <string name="clock_title" msgid="2126046720254613991">"Pulkstenis"</string>
<string name="grid_title" msgid="1688173478777254123">"Lietotņu režģis"</string>
<string name="apply_theme_btn" msgid="6293081192321303991">"Lietot"</string>
<string name="edit_custom_theme_lbl" msgid="5211377705710775224">"Pieskarieties, lai rediģētu"</string>
@@ -91,15 +89,4 @@
<string name="preset_color_tab" msgid="3133391839341329314">"Pamatkrāsas"</string>
<string name="color_changed" msgid="7029571720331641235">"Krāsa mainīta"</string>
<string name="adaptive_color_title" msgid="1336508599235896205">"Dinamiska"</string>
- <string name="keyguard_slot_name_bottom_start" msgid="6717374042663171860">"Kreisā poga"</string>
- <string name="keyguard_slot_name_bottom_end" msgid="7636885379738905151">"Labā poga"</string>
- <string name="keyguard_affordance_none" msgid="1751643933430782312">"Nav"</string>
- <string name="keyguard_affordance_enablement_dialog_title" msgid="3389730825561696493">"Lai atlasītu lietotni <xliff:g id="APPNAME">%1$s</xliff:g>, pārbaudiet tālāk minēto"</string>
- <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8117011931337357438">"Atvērt lietotni <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
- <string name="keyguard_affordance_enablement_dialog_message" msgid="6136286758939253570">"Lai pievienotu lietotni <xliff:g id="APPNAME">%1$s</xliff:g> kā saīsni, jābūt izpildītiem tālāk minētajiem nosacījumiem."</string>
- <string name="keyguard_affordance_enablement_dialog_dismiss_button" msgid="629754625264422508">"Gatavs"</string>
- <string name="keyguard_quick_affordance_title" msgid="4242813186995735584">"Saīsnes"</string>
- <string name="keyguard_quick_affordance_section_title" msgid="2806304242671717309">"Saīsnes"</string>
- <string name="keyguard_quick_affordance_two_selected_template" msgid="1757099194522296363">"<xliff:g id="FIRST">%1$s</xliff:g>, <xliff:g id="SECOND">%2$s</xliff:g>"</string>
- <string name="keyguard_quick_affordance_none_selected" msgid="8494127020144112003">"Nav"</string>
</resources>
diff --git a/res/values-mk/strings.xml b/res/values-mk/strings.xml
index ffac0f4..197058c 100644
--- a/res/values-mk/strings.xml
+++ b/res/values-mk/strings.xml
@@ -19,9 +19,7 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_name" msgid="1647136562008520313">"Тапет и стил"</string>
<string name="theme_title" msgid="2144932106319405101">"Стил"</string>
- <string name="clock_title" msgid="1974314575211361352">"Приспособен часовник"</string>
- <string name="clock_description" msgid="3563839327378948">"Изберете приспособен часовник"</string>
- <string name="clock_picker_entry_content_description" msgid="8377139273468595734">"Променете го приспособениот часовник"</string>
+ <string name="clock_title" msgid="2126046720254613991">"Часовник"</string>
<string name="grid_title" msgid="1688173478777254123">"Мрежа"</string>
<string name="apply_theme_btn" msgid="6293081192321303991">"Примени"</string>
<string name="edit_custom_theme_lbl" msgid="5211377705710775224">"Допрете за да измените"</string>
@@ -91,15 +89,4 @@
<string name="preset_color_tab" msgid="3133391839341329314">"Основни бои"</string>
<string name="color_changed" msgid="7029571720331641235">"Бојата е променета"</string>
<string name="adaptive_color_title" msgid="1336508599235896205">"Динамично"</string>
- <string name="keyguard_slot_name_bottom_start" msgid="6717374042663171860">"Лево копче"</string>
- <string name="keyguard_slot_name_bottom_end" msgid="7636885379738905151">"Десно копче"</string>
- <string name="keyguard_affordance_none" msgid="1751643933430782312">"Нема"</string>
- <string name="keyguard_affordance_enablement_dialog_title" msgid="3389730825561696493">"За да изберете „<xliff:g id="APPNAME">%1$s</xliff:g>“, проверете го следново"</string>
- <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8117011931337357438">"Отворете ја <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
- <string name="keyguard_affordance_enablement_dialog_message" msgid="6136286758939253570">"За да ја додадете апликацијата <xliff:g id="APPNAME">%1$s</xliff:g> како кратенка, треба да бидат исполнети следниве услови"</string>
- <string name="keyguard_affordance_enablement_dialog_dismiss_button" msgid="629754625264422508">"Готово"</string>
- <string name="keyguard_quick_affordance_title" msgid="4242813186995735584">"Кратенки"</string>
- <string name="keyguard_quick_affordance_section_title" msgid="2806304242671717309">"Кратенки"</string>
- <string name="keyguard_quick_affordance_two_selected_template" msgid="1757099194522296363">"<xliff:g id="FIRST">%1$s</xliff:g>, <xliff:g id="SECOND">%2$s</xliff:g>"</string>
- <string name="keyguard_quick_affordance_none_selected" msgid="8494127020144112003">"Нема"</string>
</resources>
diff --git a/res/values-ml/strings.xml b/res/values-ml/strings.xml
index 60e4404..91ae2dc 100644
--- a/res/values-ml/strings.xml
+++ b/res/values-ml/strings.xml
@@ -19,9 +19,7 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_name" msgid="1647136562008520313">"വാൾപേപ്പറും സ്റ്റൈലും"</string>
<string name="theme_title" msgid="2144932106319405101">"സ്റ്റൈൽ"</string>
- <string name="clock_title" msgid="1974314575211361352">"കസ്റ്റം ക്ലോക്ക്"</string>
- <string name="clock_description" msgid="3563839327378948">"കസ്റ്റം ക്ലോക്ക് തിരഞ്ഞെടുക്കൂ"</string>
- <string name="clock_picker_entry_content_description" msgid="8377139273468595734">"ഇഷ്ടാനുസൃത ക്ലോക്ക് മാറ്റൂ"</string>
+ <string name="clock_title" msgid="2126046720254613991">"ക്ലോക്ക്"</string>
<string name="grid_title" msgid="1688173478777254123">"ആപ്പ് ഗ്രിഡ്"</string>
<string name="apply_theme_btn" msgid="6293081192321303991">"പ്രയോഗിക്കുക"</string>
<string name="edit_custom_theme_lbl" msgid="5211377705710775224">"എഡിറ്റ് ചെയ്യാൻ ടാപ്പ് ചെയ്യുക"</string>
@@ -91,15 +89,4 @@
<string name="preset_color_tab" msgid="3133391839341329314">"അടിസ്ഥാന നിറങ്ങൾ"</string>
<string name="color_changed" msgid="7029571720331641235">"നിറം മാറ്റി"</string>
<string name="adaptive_color_title" msgid="1336508599235896205">"ഡൈനാമിക്"</string>
- <string name="keyguard_slot_name_bottom_start" msgid="6717374042663171860">"ഇടതുവശത്തെ ബട്ടൺ"</string>
- <string name="keyguard_slot_name_bottom_end" msgid="7636885379738905151">"വലതുവശത്തെ ബട്ടൺ"</string>
- <string name="keyguard_affordance_none" msgid="1751643933430782312">"ഒന്നുമില്ല"</string>
- <string name="keyguard_affordance_enablement_dialog_title" msgid="3389730825561696493">"`<xliff:g id="APPNAME">%1$s</xliff:g>` തിരഞ്ഞെടുക്കാൻ, ഇനിപ്പറയുന്നവ പരിശോധിക്കുക"</string>
- <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8117011931337357438">"<xliff:g id="APPNAME">%1$s</xliff:g> തുറക്കുക"</string>
- <string name="keyguard_affordance_enablement_dialog_message" msgid="6136286758939253570">"കുറുക്കുവഴിയായി <xliff:g id="APPNAME">%1$s</xliff:g> ആപ്പ് ചേർക്കാൻ, ഇനിപ്പറയുന്ന കാര്യങ്ങൾ ഉറപ്പാക്കുക"</string>
- <string name="keyguard_affordance_enablement_dialog_dismiss_button" msgid="629754625264422508">"പൂർത്തിയായി"</string>
- <string name="keyguard_quick_affordance_title" msgid="4242813186995735584">"കുറുക്കുവഴികൾ"</string>
- <string name="keyguard_quick_affordance_section_title" msgid="2806304242671717309">"കുറുക്കുവഴികൾ"</string>
- <string name="keyguard_quick_affordance_two_selected_template" msgid="1757099194522296363">"<xliff:g id="FIRST">%1$s</xliff:g>, <xliff:g id="SECOND">%2$s</xliff:g>"</string>
- <string name="keyguard_quick_affordance_none_selected" msgid="8494127020144112003">"ഒന്നുമില്ല"</string>
</resources>
diff --git a/res/values-mn/strings.xml b/res/values-mn/strings.xml
index 29c7341..6fc45b5 100644
--- a/res/values-mn/strings.xml
+++ b/res/values-mn/strings.xml
@@ -19,9 +19,7 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_name" msgid="1647136562008520313">"Дэлгэцийн зураг, загвар"</string>
<string name="theme_title" msgid="2144932106319405101">"Загвар"</string>
- <string name="clock_title" msgid="1974314575211361352">"Захиалгат цаг"</string>
- <string name="clock_description" msgid="3563839327378948">"Захиалгат цаг сонгох"</string>
- <string name="clock_picker_entry_content_description" msgid="8377139273468595734">"Захиалгат цагийг өөрчлөх"</string>
+ <string name="clock_title" msgid="2126046720254613991">"Цаг"</string>
<string name="grid_title" msgid="1688173478777254123">"Аппын хүснэгт"</string>
<string name="apply_theme_btn" msgid="6293081192321303991">"Ашиглах"</string>
<string name="edit_custom_theme_lbl" msgid="5211377705710775224">"Засахын тулд товшино уу"</string>
@@ -91,15 +89,4 @@
<string name="preset_color_tab" msgid="3133391839341329314">"Суурь өнгөнүүд"</string>
<string name="color_changed" msgid="7029571720331641235">"Өнгийг өөрчилсөн"</string>
<string name="adaptive_color_title" msgid="1336508599235896205">"Динамик"</string>
- <string name="keyguard_slot_name_bottom_start" msgid="6717374042663171860">"Зүүн товчлуур"</string>
- <string name="keyguard_slot_name_bottom_end" msgid="7636885379738905151">"Баруун товчлуур"</string>
- <string name="keyguard_affordance_none" msgid="1751643933430782312">"Байхгүй"</string>
- <string name="keyguard_affordance_enablement_dialog_title" msgid="3389730825561696493">"`<xliff:g id="APPNAME">%1$s</xliff:g>`-г сонгохын тулд дараахыг шалгана уу"</string>
- <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8117011931337357438">"<xliff:g id="APPNAME">%1$s</xliff:g>-г нээх"</string>
- <string name="keyguard_affordance_enablement_dialog_message" msgid="6136286758939253570">"<xliff:g id="APPNAME">%1$s</xliff:g> аппыг товчлолоор нэмэхийн тулд дараахыг баталгаажуулна уу"</string>
- <string name="keyguard_affordance_enablement_dialog_dismiss_button" msgid="629754625264422508">"Болсон"</string>
- <string name="keyguard_quick_affordance_title" msgid="4242813186995735584">"Товчлол"</string>
- <string name="keyguard_quick_affordance_section_title" msgid="2806304242671717309">"Товчлол"</string>
- <string name="keyguard_quick_affordance_two_selected_template" msgid="1757099194522296363">"<xliff:g id="FIRST">%1$s</xliff:g>, <xliff:g id="SECOND">%2$s</xliff:g>"</string>
- <string name="keyguard_quick_affordance_none_selected" msgid="8494127020144112003">"Байхгүй"</string>
</resources>
diff --git a/res/values-mr/strings.xml b/res/values-mr/strings.xml
index 298bcbc..0eba26e 100644
--- a/res/values-mr/strings.xml
+++ b/res/values-mr/strings.xml
@@ -19,9 +19,7 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_name" msgid="1647136562008520313">"वॉलपेपर आणि शैली"</string>
<string name="theme_title" msgid="2144932106319405101">"शैली"</string>
- <string name="clock_title" msgid="1974314575211361352">"कस्टम क्लॉक"</string>
- <string name="clock_description" msgid="3563839327378948">"कस्टम क्लॉक निवडा"</string>
- <string name="clock_picker_entry_content_description" msgid="8377139273468595734">"कस्टम क्लॉक बदला"</string>
+ <string name="clock_title" msgid="2126046720254613991">"घड्याळ"</string>
<string name="grid_title" msgid="1688173478777254123">"ॲप ग्रिड"</string>
<string name="apply_theme_btn" msgid="6293081192321303991">"लागू करा"</string>
<string name="edit_custom_theme_lbl" msgid="5211377705710775224">"संपादित करण्यासाठी टॅप करा"</string>
@@ -91,15 +89,4 @@
<string name="preset_color_tab" msgid="3133391839341329314">"डीफॉल्ट रंग"</string>
<string name="color_changed" msgid="7029571720331641235">"रंग बदलला आहे"</string>
<string name="adaptive_color_title" msgid="1336508599235896205">"सतत बदलणारे"</string>
- <string name="keyguard_slot_name_bottom_start" msgid="6717374042663171860">"डावीकडील बटण"</string>
- <string name="keyguard_slot_name_bottom_end" msgid="7636885379738905151">"उजवीकडील बटण"</string>
- <string name="keyguard_affordance_none" msgid="1751643933430782312">"काहीही नाही"</string>
- <string name="keyguard_affordance_enablement_dialog_title" msgid="3389730825561696493">"`<xliff:g id="APPNAME">%1$s</xliff:g>` निवडण्यासाठी पुढील गोष्टी तपासा"</string>
- <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8117011931337357438">"<xliff:g id="APPNAME">%1$s</xliff:g> उघडा"</string>
- <string name="keyguard_affordance_enablement_dialog_message" msgid="6136286758939253570">"<xliff:g id="APPNAME">%1$s</xliff:g> हे अॅप शॉर्टकट म्हणून जोडण्यासाठी, पुढील गोष्टींची खात्री करा"</string>
- <string name="keyguard_affordance_enablement_dialog_dismiss_button" msgid="629754625264422508">"पूर्ण झाले"</string>
- <string name="keyguard_quick_affordance_title" msgid="4242813186995735584">"शॉर्टकट"</string>
- <string name="keyguard_quick_affordance_section_title" msgid="2806304242671717309">"शॉर्टकट"</string>
- <string name="keyguard_quick_affordance_two_selected_template" msgid="1757099194522296363">"<xliff:g id="FIRST">%1$s</xliff:g>, <xliff:g id="SECOND">%2$s</xliff:g>"</string>
- <string name="keyguard_quick_affordance_none_selected" msgid="8494127020144112003">"काहीही नाही"</string>
</resources>
diff --git a/res/values-ms/strings.xml b/res/values-ms/strings.xml
index 96c5bc8..a241339 100644
--- a/res/values-ms/strings.xml
+++ b/res/values-ms/strings.xml
@@ -19,9 +19,7 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_name" msgid="1647136562008520313">"Kertas dinding & gaya"</string>
<string name="theme_title" msgid="2144932106319405101">"Gaya"</string>
- <string name="clock_title" msgid="1974314575211361352">"Jam Tersuai"</string>
- <string name="clock_description" msgid="3563839327378948">"Pilih jam tersuai"</string>
- <string name="clock_picker_entry_content_description" msgid="8377139273468595734">"Tukar jam tersuai"</string>
+ <string name="clock_title" msgid="2126046720254613991">"Jam"</string>
<string name="grid_title" msgid="1688173478777254123">"Grid apl"</string>
<string name="apply_theme_btn" msgid="6293081192321303991">"Gunakan"</string>
<string name="edit_custom_theme_lbl" msgid="5211377705710775224">"Ketik untuk edit"</string>
@@ -91,15 +89,4 @@
<string name="preset_color_tab" msgid="3133391839341329314">"Warna asas"</string>
<string name="color_changed" msgid="7029571720331641235">"Warna ditukar"</string>
<string name="adaptive_color_title" msgid="1336508599235896205">"Dinamik"</string>
- <string name="keyguard_slot_name_bottom_start" msgid="6717374042663171860">"Butang kiri"</string>
- <string name="keyguard_slot_name_bottom_end" msgid="7636885379738905151">"Butang kanan"</string>
- <string name="keyguard_affordance_none" msgid="1751643933430782312">"Tiada"</string>
- <string name="keyguard_affordance_enablement_dialog_title" msgid="3389730825561696493">"Untuk memilih `<xliff:g id="APPNAME">%1$s</xliff:g>` semak perkara berikut"</string>
- <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8117011931337357438">"Buka <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
- <string name="keyguard_affordance_enablement_dialog_message" msgid="6136286758939253570">"Untuk menambahkan apl <xliff:g id="APPNAME">%1$s</xliff:g> sebagai pintasan, pastikan"</string>
- <string name="keyguard_affordance_enablement_dialog_dismiss_button" msgid="629754625264422508">"Selesai"</string>
- <string name="keyguard_quick_affordance_title" msgid="4242813186995735584">"Pintasan"</string>
- <string name="keyguard_quick_affordance_section_title" msgid="2806304242671717309">"Pintasan"</string>
- <string name="keyguard_quick_affordance_two_selected_template" msgid="1757099194522296363">"<xliff:g id="FIRST">%1$s</xliff:g>, <xliff:g id="SECOND">%2$s</xliff:g>"</string>
- <string name="keyguard_quick_affordance_none_selected" msgid="8494127020144112003">"Tiada"</string>
</resources>
diff --git a/res/values-my/strings.xml b/res/values-my/strings.xml
index 000d598..1f63a7a 100644
--- a/res/values-my/strings.xml
+++ b/res/values-my/strings.xml
@@ -19,9 +19,7 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_name" msgid="1647136562008520313">"နောက်ခံနှင့် ပုံစံ"</string>
<string name="theme_title" msgid="2144932106319405101">"ပုံစံ"</string>
- <string name="clock_title" msgid="1974314575211361352">"စိတ်ကြိုက်နာရီ"</string>
- <string name="clock_description" msgid="3563839327378948">"စိတ်ကြိုက်နာရီရွေးပါ"</string>
- <string name="clock_picker_entry_content_description" msgid="8377139273468595734">"စိတ်ကြိုက်နာရီ ပြောင်းနိုင်သည်"</string>
+ <string name="clock_title" msgid="2126046720254613991">"နာရီ"</string>
<string name="grid_title" msgid="1688173478777254123">"အက်ပ်ဇယား"</string>
<string name="apply_theme_btn" msgid="6293081192321303991">"အသုံးပြုရန်"</string>
<string name="edit_custom_theme_lbl" msgid="5211377705710775224">"တည်းဖြတ်ရန် တို့ပါ"</string>
@@ -80,26 +78,15 @@
<string name="accessibility_custom_color_title" msgid="4124246598886320663">"စိတ်ကြိုက်အရောင်"</string>
<string name="accessibility_custom_shape_title" msgid="7708408259374643129">"စိတ်ကြိုက်ပုံသဏ္ဌာန်"</string>
<string name="accessibility_custom_name_title" msgid="5494460518085463262">"စိတ်ကြိုက်ပုံစံအမည်"</string>
- <string name="mode_title" msgid="2394873501427436055">"အမှောင်နောက်ခံ"</string>
+ <string name="mode_title" msgid="2394873501427436055">"မှောင်သည့် အပြင်အဆင်"</string>
<string name="mode_disabled_msg" msgid="9196245518435936512">"‘ဘက်ထရီ အားထိန်း’ ကြောင့် ယာယီပိတ်ထားသည်"</string>
<string name="mode_changed" msgid="2243581369395418584">"အပြင်အဆင် ပြောင်းလိုက်ပါပြီ"</string>
<string name="themed_icon_title" msgid="7312460430471956558">"အပြင်အဆင်သုံး သင်္ကေတများ"</string>
- <string name="beta_title" msgid="8703819523760746458">"စမ်းသပ်"</string>
+ <string name="beta_title" msgid="8703819523760746458">"စမ်းသပ်ဆော့ဖ်ဝဲ"</string>
<string name="gird_picker_entry_content_description" msgid="9087651470212293439">"အက်ပ်ဇယား ပြောင်းရန်"</string>
<string name="wallpaper_color_tab" msgid="1447926591721403840">"နောက်ခံအရောင်များ"</string>
<string name="wallpaper_color_title" msgid="5687965239180986458">"နောက်ခံအရောင်"</string>
- <string name="preset_color_tab" msgid="3133391839341329314">"အခြေခံအရောင်များ"</string>
+ <string name="preset_color_tab" msgid="3133391839341329314">"မူရင်းအရောင်များ"</string>
<string name="color_changed" msgid="7029571720331641235">"အရောင် ပြောင်းလိုက်ပါပြီ"</string>
<string name="adaptive_color_title" msgid="1336508599235896205">"ပြောင်းနိုင်သော"</string>
- <string name="keyguard_slot_name_bottom_start" msgid="6717374042663171860">"ဘယ်ခလုတ်"</string>
- <string name="keyguard_slot_name_bottom_end" msgid="7636885379738905151">"ညာခလုတ်"</string>
- <string name="keyguard_affordance_none" msgid="1751643933430782312">"မရှိ"</string>
- <string name="keyguard_affordance_enablement_dialog_title" msgid="3389730825561696493">"`<xliff:g id="APPNAME">%1$s</xliff:g>` ရွေးချယ်ရန် အောက်ပါတို့ကို ကြည့်ပါ"</string>
- <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8117011931337357438">"<xliff:g id="APPNAME">%1$s</xliff:g> ဖွင့်ရန်"</string>
- <string name="keyguard_affordance_enablement_dialog_message" msgid="6136286758939253570">"<xliff:g id="APPNAME">%1$s</xliff:g> အက်ပ်ကို ဖြတ်လမ်းလင့်ခ်အဖြစ် ထည့်ရန် အောက်ပါတို့နှင့်ကိုက်ညီရမည်"</string>
- <string name="keyguard_affordance_enablement_dialog_dismiss_button" msgid="629754625264422508">"ပြီးပြီ"</string>
- <string name="keyguard_quick_affordance_title" msgid="4242813186995735584">"ဖြတ်လမ်းလင့်ခ်"</string>
- <string name="keyguard_quick_affordance_section_title" msgid="2806304242671717309">"ဖြတ်လမ်းလင့်ခ်"</string>
- <string name="keyguard_quick_affordance_two_selected_template" msgid="1757099194522296363">"<xliff:g id="FIRST">%1$s</xliff:g>၊ <xliff:g id="SECOND">%2$s</xliff:g>"</string>
- <string name="keyguard_quick_affordance_none_selected" msgid="8494127020144112003">"မရှိ"</string>
</resources>
diff --git a/res/values-nb/strings.xml b/res/values-nb/strings.xml
index 9ba98f8..a82f28b 100644
--- a/res/values-nb/strings.xml
+++ b/res/values-nb/strings.xml
@@ -19,9 +19,7 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_name" msgid="1647136562008520313">"Bakgrunn og stil"</string>
<string name="theme_title" msgid="2144932106319405101">"Stil"</string>
- <string name="clock_title" msgid="1974314575211361352">"Tilpasset klokke"</string>
- <string name="clock_description" msgid="3563839327378948">"Velg en tilpasset klokke"</string>
- <string name="clock_picker_entry_content_description" msgid="8377139273468595734">"Endre en tilpasset klokke"</string>
+ <string name="clock_title" msgid="2126046720254613991">"Klokke"</string>
<string name="grid_title" msgid="1688173478777254123">"Apprutenett"</string>
<string name="apply_theme_btn" msgid="6293081192321303991">"Bruk"</string>
<string name="edit_custom_theme_lbl" msgid="5211377705710775224">"Trykk for å endre"</string>
@@ -91,15 +89,4 @@
<string name="preset_color_tab" msgid="3133391839341329314">"Grunnleggende farger"</string>
<string name="color_changed" msgid="7029571720331641235">"Fargen er endret"</string>
<string name="adaptive_color_title" msgid="1336508599235896205">"Dynamisk"</string>
- <string name="keyguard_slot_name_bottom_start" msgid="6717374042663171860">"Venstreknapp"</string>
- <string name="keyguard_slot_name_bottom_end" msgid="7636885379738905151">"Høyreknapp"</string>
- <string name="keyguard_affordance_none" msgid="1751643933430782312">"Ingen"</string>
- <string name="keyguard_affordance_enablement_dialog_title" msgid="3389730825561696493">"For å velge «<xliff:g id="APPNAME">%1$s</xliff:g>», sjekk det følgende"</string>
- <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8117011931337357438">"Åpne <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
- <string name="keyguard_affordance_enablement_dialog_message" msgid="6136286758939253570">"For å legge til <xliff:g id="APPNAME">%1$s</xliff:g>-appen som en snarvei må du sørge for at"</string>
- <string name="keyguard_affordance_enablement_dialog_dismiss_button" msgid="629754625264422508">"Ferdig"</string>
- <string name="keyguard_quick_affordance_title" msgid="4242813186995735584">"Snarveier"</string>
- <string name="keyguard_quick_affordance_section_title" msgid="2806304242671717309">"Snarveier"</string>
- <string name="keyguard_quick_affordance_two_selected_template" msgid="1757099194522296363">"<xliff:g id="FIRST">%1$s</xliff:g>, <xliff:g id="SECOND">%2$s</xliff:g>"</string>
- <string name="keyguard_quick_affordance_none_selected" msgid="8494127020144112003">"Ingen"</string>
</resources>
diff --git a/res/values-ne/strings.xml b/res/values-ne/strings.xml
index e8862fe..a29a975 100644
--- a/res/values-ne/strings.xml
+++ b/res/values-ne/strings.xml
@@ -19,9 +19,7 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_name" msgid="1647136562008520313">"वालपेपर तथा शैली"</string>
<string name="theme_title" msgid="2144932106319405101">"शैली"</string>
- <string name="clock_title" msgid="1974314575211361352">"कस्टम घडी"</string>
- <string name="clock_description" msgid="3563839327378948">"कस्टम घडी छान्नु…"</string>
- <string name="clock_picker_entry_content_description" msgid="8377139273468595734">"कुनै कस्टम घडी परिवर्तन गर्नुहोस्"</string>
+ <string name="clock_title" msgid="2126046720254613991">"घडी"</string>
<string name="grid_title" msgid="1688173478777254123">"एप ग्रिड"</string>
<string name="apply_theme_btn" msgid="6293081192321303991">"लागू गर्नुहोस्"</string>
<string name="edit_custom_theme_lbl" msgid="5211377705710775224">"सम्पादन गर्न ट्याप गर्नुहोस्"</string>
@@ -91,15 +89,4 @@
<string name="preset_color_tab" msgid="3133391839341329314">"आधारभूत रङहरू"</string>
<string name="color_changed" msgid="7029571720331641235">"रङ बदलियो"</string>
<string name="adaptive_color_title" msgid="1336508599235896205">"गतिशील"</string>
- <string name="keyguard_slot_name_bottom_start" msgid="6717374042663171860">"बायाँतिरको बटन"</string>
- <string name="keyguard_slot_name_bottom_end" msgid="7636885379738905151">"दायाँतिरको बटन"</string>
- <string name="keyguard_affordance_none" msgid="1751643933430782312">"कुनै पनि होइन"</string>
- <string name="keyguard_affordance_enablement_dialog_title" msgid="3389730825561696493">"\"<xliff:g id="APPNAME">%1$s</xliff:g>\" चयन गर्न तल दिइएका निर्देशनहरू पालना गर्नुहोस्"</string>
- <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8117011931337357438">"<xliff:g id="APPNAME">%1$s</xliff:g> खोल्नुहोस्"</string>
- <string name="keyguard_affordance_enablement_dialog_message" msgid="6136286758939253570">"<xliff:g id="APPNAME">%1$s</xliff:g> एपलाई सर्टकटका रूपमा हाल्न, निम्न कुरा सुनिश्चित गर्नुहोस्:"</string>
- <string name="keyguard_affordance_enablement_dialog_dismiss_button" msgid="629754625264422508">"पूरा भयो"</string>
- <string name="keyguard_quick_affordance_title" msgid="4242813186995735584">"सर्टकटहरू"</string>
- <string name="keyguard_quick_affordance_section_title" msgid="2806304242671717309">"सर्टकटहरू"</string>
- <string name="keyguard_quick_affordance_two_selected_template" msgid="1757099194522296363">"<xliff:g id="FIRST">%1$s</xliff:g>, <xliff:g id="SECOND">%2$s</xliff:g>"</string>
- <string name="keyguard_quick_affordance_none_selected" msgid="8494127020144112003">"कुनै पनि होइन"</string>
</resources>
diff --git a/res/values-nl/strings.xml b/res/values-nl/strings.xml
index 27397ec..6210372 100644
--- a/res/values-nl/strings.xml
+++ b/res/values-nl/strings.xml
@@ -19,9 +19,7 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_name" msgid="1647136562008520313">"Achtergrond en stijl"</string>
<string name="theme_title" msgid="2144932106319405101">"Stijl"</string>
- <string name="clock_title" msgid="1974314575211361352">"Aangepaste klok"</string>
- <string name="clock_description" msgid="3563839327378948">"Klok kiezen"</string>
- <string name="clock_picker_entry_content_description" msgid="8377139273468595734">"Aangepaste klok wijzigen"</string>
+ <string name="clock_title" msgid="2126046720254613991">"Klok"</string>
<string name="grid_title" msgid="1688173478777254123">"App-raster"</string>
<string name="apply_theme_btn" msgid="6293081192321303991">"Toepassen"</string>
<string name="edit_custom_theme_lbl" msgid="5211377705710775224">"Tik om te bewerken"</string>
@@ -91,15 +89,4 @@
<string name="preset_color_tab" msgid="3133391839341329314">"Basiskleuren"</string>
<string name="color_changed" msgid="7029571720331641235">"Kleur gewijzigd"</string>
<string name="adaptive_color_title" msgid="1336508599235896205">"Dynamisch"</string>
- <string name="keyguard_slot_name_bottom_start" msgid="6717374042663171860">"Linkerknop"</string>
- <string name="keyguard_slot_name_bottom_end" msgid="7636885379738905151">"Rechterknop"</string>
- <string name="keyguard_affordance_none" msgid="1751643933430782312">"Geen"</string>
- <string name="keyguard_affordance_enablement_dialog_title" msgid="3389730825561696493">"Check het volgende als je <xliff:g id="APPNAME">%1$s</xliff:g> wilt selecteren"</string>
- <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8117011931337357438">"<xliff:g id="APPNAME">%1$s</xliff:g> openen"</string>
- <string name="keyguard_affordance_enablement_dialog_message" msgid="6136286758939253570">"Zorg voor het volgende om de <xliff:g id="APPNAME">%1$s</xliff:g>-app toe te voegen als snelkoppeling:"</string>
- <string name="keyguard_affordance_enablement_dialog_dismiss_button" msgid="629754625264422508">"Klaar"</string>
- <string name="keyguard_quick_affordance_title" msgid="4242813186995735584">"Snelkoppelingen"</string>
- <string name="keyguard_quick_affordance_section_title" msgid="2806304242671717309">"Snelkoppelingen"</string>
- <string name="keyguard_quick_affordance_two_selected_template" msgid="1757099194522296363">"<xliff:g id="FIRST">%1$s</xliff:g>, <xliff:g id="SECOND">%2$s</xliff:g>"</string>
- <string name="keyguard_quick_affordance_none_selected" msgid="8494127020144112003">"Geen"</string>
</resources>
diff --git a/res/values-or/strings.xml b/res/values-or/strings.xml
index 9ce4e96..8df3d48 100644
--- a/res/values-or/strings.xml
+++ b/res/values-or/strings.xml
@@ -19,12 +19,10 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_name" msgid="1647136562008520313">"ୱାଲପେପର୍ ଏବଂ ଷ୍ଟାଇଲ୍"</string>
<string name="theme_title" msgid="2144932106319405101">"ଷ୍ଟାଇଲ୍"</string>
- <string name="clock_title" msgid="1974314575211361352">"କଷ୍ଟମ ଘଣ୍ଟା"</string>
- <string name="clock_description" msgid="3563839327378948">"କଷ୍ଟମ ଘଣ୍ଟା ବାଛ"</string>
- <string name="clock_picker_entry_content_description" msgid="8377139273468595734">"ଏକ କଷ୍ଟମ ଘଣ୍ଟାକୁ ପରିବର୍ତ୍ତନ କରନ୍ତୁ"</string>
+ <string name="clock_title" msgid="2126046720254613991">"ଘଣ୍ଟା"</string>
<string name="grid_title" msgid="1688173478777254123">"ଆପ୍ ଗ୍ରିଡ୍"</string>
<string name="apply_theme_btn" msgid="6293081192321303991">"ପ୍ରୟୋଗ କରନ୍ତୁ"</string>
- <string name="edit_custom_theme_lbl" msgid="5211377705710775224">"ଏଡିଟ କରିବା ପାଇଁ ଟାପ କରନ୍ତୁ"</string>
+ <string name="edit_custom_theme_lbl" msgid="5211377705710775224">"ଏଡିଟ୍ କରିବା ପାଇଁ ଟାପ୍ କରନ୍ତୁ"</string>
<string name="keep_my_wallpaper" msgid="8012385376769568517">"ବର୍ତ୍ତମାନର ୱାଲ୍ପେପର୍କୁ ରଖନ୍ତୁ"</string>
<string name="theme_preview_card_content_description" msgid="5989222908619535533">"ଷ୍ଟାଇଲ୍ ପ୍ରିଭ୍ୟୁ"</string>
<string name="grid_preview_card_content_description" msgid="8449383777584714842">"ଗ୍ରିଡ୍ ପ୍ରିଭ୍ୟୁ"</string>
@@ -65,7 +63,7 @@
<string name="icon_component_label" msgid="2625784884001407944">"ଆଇକନ୍ <xliff:g id="ID_1">%1$d</xliff:g>"</string>
<string name="delete_custom_theme_confirmation" msgid="4452137183628769394">"କଷ୍ଟମ୍ ଶୈଳୀ ଡିଲିଟ୍ କରିବେ?"</string>
<string name="delete_custom_theme_button" msgid="5102462988130208824">"ଡିଲିଟ୍ କରନ୍ତୁ"</string>
- <string name="cancel" msgid="4651030493668562067">"ବାତିଲ କରନ୍ତୁ"</string>
+ <string name="cancel" msgid="4651030493668562067">"ବାତିଲ୍ କରନ୍ତୁ"</string>
<string name="set_theme_wallpaper_dialog_message" msgid="2179661027350908003">"ଶୈଳୀ ଯୁକ୍ତ ୱାଲ୍ପେପର୍କୁ ସେଟ୍ କରନ୍ତୁ"</string>
<string name="use_style_instead_title" msgid="1578754995763917502">"ଏହା ପରିବର୍ତ୍ତେ <xliff:g id="ID_1">%1$s</xliff:g> ବ୍ୟବହାର କରିବେ?"</string>
<string name="use_style_instead_body" msgid="3051937045807471496">"ଆପଣ ବଛିଥିବା ଉପାଦାନଗୁଡ଼ିକ <xliff:g id="ID_1">%1$s</xliff:g> ଶୈଳୀ ସହ ମେଳ ହେଉଛି। ଏହା ପରିବର୍ତ୍ତେ ଆପଣ <xliff:g id="ID_2">%1$s</xliff:g>କୁ ବ୍ୟବହାର କରିବାକୁ ଚାହୁଁଛନ୍ତି କି?"</string>
@@ -88,18 +86,7 @@
<string name="gird_picker_entry_content_description" msgid="9087651470212293439">"ଆପ୍ ଗ୍ରିଡ୍ ପରିବର୍ତ୍ତନ କରନ୍ତୁ"</string>
<string name="wallpaper_color_tab" msgid="1447926591721403840">"ୱାଲପେପର ରଙ୍ଗଗୁଡ଼ିକ"</string>
<string name="wallpaper_color_title" msgid="5687965239180986458">"ୱାଲପେପର ରଙ୍ଗ"</string>
- <string name="preset_color_tab" msgid="3133391839341329314">"ମୌଳିକ ରଙ୍ଗଗୁଡ଼ିକ"</string>
+ <string name="preset_color_tab" msgid="3133391839341329314">"ବେସିକ ରଙ୍ଗଗୁଡ଼ିକ"</string>
<string name="color_changed" msgid="7029571720331641235">"ରଙ୍ଗ ପରିବର୍ତ୍ତନ କରାଯାଇଛି"</string>
<string name="adaptive_color_title" msgid="1336508599235896205">"ଡାଇନାମିକ"</string>
- <string name="keyguard_slot_name_bottom_start" msgid="6717374042663171860">"ବାମପଟ ବଟନ"</string>
- <string name="keyguard_slot_name_bottom_end" msgid="7636885379738905151">"ଡାହାଣପଟ ବଟନ"</string>
- <string name="keyguard_affordance_none" msgid="1751643933430782312">"କିଛି ନାହିଁ"</string>
- <string name="keyguard_affordance_enablement_dialog_title" msgid="3389730825561696493">"`<xliff:g id="APPNAME">%1$s</xliff:g>`କୁ ଚୟନ କରିବା ପାଇଁ ନିମ୍ନୋକ୍ତକୁ ଯାଞ୍ଚ କରନ୍ତୁ"</string>
- <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8117011931337357438">"<xliff:g id="APPNAME">%1$s</xliff:g> ଖୋଲନ୍ତୁ"</string>
- <string name="keyguard_affordance_enablement_dialog_message" msgid="6136286758939253570">"ଏକ ସର୍ଟକଟ ଭାବେ <xliff:g id="APPNAME">%1$s</xliff:g> ଆପ ଯୋଗ କରିବାକୁ, ଏହା ସୁନିଶ୍ଚିତ କରନ୍ତୁ"</string>
- <string name="keyguard_affordance_enablement_dialog_dismiss_button" msgid="629754625264422508">"ହୋଇଗଲା"</string>
- <string name="keyguard_quick_affordance_title" msgid="4242813186995735584">"ସର୍ଟକଟଗୁଡ଼ିକ"</string>
- <string name="keyguard_quick_affordance_section_title" msgid="2806304242671717309">"ସର୍ଟକଟଗୁଡ଼ିକ"</string>
- <string name="keyguard_quick_affordance_two_selected_template" msgid="1757099194522296363">"<xliff:g id="FIRST">%1$s</xliff:g>, <xliff:g id="SECOND">%2$s</xliff:g>"</string>
- <string name="keyguard_quick_affordance_none_selected" msgid="8494127020144112003">"କିଛି ନାହିଁ"</string>
</resources>
diff --git a/res/values-pa/strings.xml b/res/values-pa/strings.xml
index 393e4cf..1d9d119 100644
--- a/res/values-pa/strings.xml
+++ b/res/values-pa/strings.xml
@@ -19,9 +19,7 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_name" msgid="1647136562008520313">"ਵਾਲਪੇਪਰ ਅਤੇ ਸਟਾਈਲ"</string>
<string name="theme_title" msgid="2144932106319405101">"ਸ਼ੈਲੀ"</string>
- <string name="clock_title" msgid="1974314575211361352">"ਵਿਉਂਤੀ ਘੜੀ"</string>
- <string name="clock_description" msgid="3563839327378948">"ਵਿਉਂਤੀ ਘੜੀ ਚੁਣੋ"</string>
- <string name="clock_picker_entry_content_description" msgid="8377139273468595734">"ਵਿਉਂਤੀ ਘੜੀ ਬਦਲੋ"</string>
+ <string name="clock_title" msgid="2126046720254613991">"ਘੜੀ"</string>
<string name="grid_title" msgid="1688173478777254123">"ਐਪ ਗ੍ਰਿਡ"</string>
<string name="apply_theme_btn" msgid="6293081192321303991">"ਲਾਗੂ ਕਰੋ"</string>
<string name="edit_custom_theme_lbl" msgid="5211377705710775224">"ਸੰਪਾਦਨ ਕਰਨ ਲਈ ਟੈਪ ਕਰੋ"</string>
@@ -91,15 +89,4 @@
<string name="preset_color_tab" msgid="3133391839341329314">"ਮੂਲ ਰੰਗ"</string>
<string name="color_changed" msgid="7029571720331641235">"ਰੰਗ ਬਦਲਿਆ ਗਿਆ"</string>
<string name="adaptive_color_title" msgid="1336508599235896205">"ਪਰਿਵਰਤਨਸ਼ੀਲ"</string>
- <string name="keyguard_slot_name_bottom_start" msgid="6717374042663171860">"ਖੱਬਾ ਬਟਨ"</string>
- <string name="keyguard_slot_name_bottom_end" msgid="7636885379738905151">"ਸੱਜਾ ਬਟਨ"</string>
- <string name="keyguard_affordance_none" msgid="1751643933430782312">"ਕੋਈ ਨਹੀਂ"</string>
- <string name="keyguard_affordance_enablement_dialog_title" msgid="3389730825561696493">"`<xliff:g id="APPNAME">%1$s</xliff:g>` ਨੂੰ ਚੁਣਨ ਲਈ, ਹੇਠਾਂ ਦਿੱਤੀਆਂ ਹਿਦਾਇਤਾਂ ਦੀ ਪਾਲਣਾ ਕਰੋ"</string>
- <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8117011931337357438">"<xliff:g id="APPNAME">%1$s</xliff:g> ਖੋਲ੍ਹੋ"</string>
- <string name="keyguard_affordance_enablement_dialog_message" msgid="6136286758939253570">"<xliff:g id="APPNAME">%1$s</xliff:g> ਐਪ ਨੂੰ ਸ਼ਾਰਟਕੱਟ ਵਜੋਂ ਸ਼ਾਮਲ ਕਰਨ ਲਈ, ਪੱਕਾ ਕਰੋ ਕਿ"</string>
- <string name="keyguard_affordance_enablement_dialog_dismiss_button" msgid="629754625264422508">"ਹੋ ਗਿਆ"</string>
- <string name="keyguard_quick_affordance_title" msgid="4242813186995735584">"ਸ਼ਾਰਟਕੱਟ"</string>
- <string name="keyguard_quick_affordance_section_title" msgid="2806304242671717309">"ਸ਼ਾਰਟਕੱਟ"</string>
- <string name="keyguard_quick_affordance_two_selected_template" msgid="1757099194522296363">"<xliff:g id="FIRST">%1$s</xliff:g>, <xliff:g id="SECOND">%2$s</xliff:g>"</string>
- <string name="keyguard_quick_affordance_none_selected" msgid="8494127020144112003">"ਕੋਈ ਨਹੀਂ"</string>
</resources>
diff --git a/res/values-pl/strings.xml b/res/values-pl/strings.xml
index 7496cd4..b3140dc 100644
--- a/res/values-pl/strings.xml
+++ b/res/values-pl/strings.xml
@@ -19,9 +19,7 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_name" msgid="1647136562008520313">"Tapeta i styl"</string>
<string name="theme_title" msgid="2144932106319405101">"Styl"</string>
- <string name="clock_title" msgid="1974314575211361352">"Własny zegar"</string>
- <string name="clock_description" msgid="3563839327378948">"Wybierz własny zegar"</string>
- <string name="clock_picker_entry_content_description" msgid="8377139273468595734">"Zmień własny zegar"</string>
+ <string name="clock_title" msgid="2126046720254613991">"Zegar"</string>
<string name="grid_title" msgid="1688173478777254123">"Siatka aplikacji"</string>
<string name="apply_theme_btn" msgid="6293081192321303991">"Zastosuj"</string>
<string name="edit_custom_theme_lbl" msgid="5211377705710775224">"Kliknij, by edytować"</string>
@@ -91,15 +89,4 @@
<string name="preset_color_tab" msgid="3133391839341329314">"Kolory podstawowe"</string>
<string name="color_changed" msgid="7029571720331641235">"Kolor został zmieniony"</string>
<string name="adaptive_color_title" msgid="1336508599235896205">"Dynamicznie"</string>
- <string name="keyguard_slot_name_bottom_start" msgid="6717374042663171860">"Lewy przycisk"</string>
- <string name="keyguard_slot_name_bottom_end" msgid="7636885379738905151">"Prawy przycisk"</string>
- <string name="keyguard_affordance_none" msgid="1751643933430782312">"Brak"</string>
- <string name="keyguard_affordance_enablement_dialog_title" msgid="3389730825561696493">"Aby wybrać opcję „<xliff:g id="APPNAME">%1$s</xliff:g>”, wykonaj te czynności"</string>
- <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8117011931337357438">"Otwórz: <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
- <string name="keyguard_affordance_enablement_dialog_message" msgid="6136286758939253570">"Aby dodać aplikację <xliff:g id="APPNAME">%1$s</xliff:g> jako skrót, upewnij się, że spełnione zostały te warunki:"</string>
- <string name="keyguard_affordance_enablement_dialog_dismiss_button" msgid="629754625264422508">"Gotowe"</string>
- <string name="keyguard_quick_affordance_title" msgid="4242813186995735584">"Skróty"</string>
- <string name="keyguard_quick_affordance_section_title" msgid="2806304242671717309">"Skróty"</string>
- <string name="keyguard_quick_affordance_two_selected_template" msgid="1757099194522296363">"<xliff:g id="FIRST">%1$s</xliff:g>, <xliff:g id="SECOND">%2$s</xliff:g>"</string>
- <string name="keyguard_quick_affordance_none_selected" msgid="8494127020144112003">"Brak"</string>
</resources>
diff --git a/res/values-pt-rPT/strings.xml b/res/values-pt-rPT/strings.xml
index 1966564..a9a4fe3 100644
--- a/res/values-pt-rPT/strings.xml
+++ b/res/values-pt-rPT/strings.xml
@@ -19,9 +19,7 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_name" msgid="1647136562008520313">"Imagem de fundo e estilo"</string>
<string name="theme_title" msgid="2144932106319405101">"Estilo"</string>
- <string name="clock_title" msgid="1974314575211361352">"Relógio person."</string>
- <string name="clock_description" msgid="3563839327378948">"Escolha rel. pers."</string>
- <string name="clock_picker_entry_content_description" msgid="8377139273468595734">"Altere um relógio personalizado"</string>
+ <string name="clock_title" msgid="2126046720254613991">"Relógio"</string>
<string name="grid_title" msgid="1688173478777254123">"Grelha de apps"</string>
<string name="apply_theme_btn" msgid="6293081192321303991">"Aplicar"</string>
<string name="edit_custom_theme_lbl" msgid="5211377705710775224">"Toque para editar"</string>
@@ -91,15 +89,4 @@
<string name="preset_color_tab" msgid="3133391839341329314">"Cores básicas"</string>
<string name="color_changed" msgid="7029571720331641235">"Cor alterada"</string>
<string name="adaptive_color_title" msgid="1336508599235896205">"Dinâmico"</string>
- <string name="keyguard_slot_name_bottom_start" msgid="6717374042663171860">"Botão esquerdo"</string>
- <string name="keyguard_slot_name_bottom_end" msgid="7636885379738905151">"Botão direito"</string>
- <string name="keyguard_affordance_none" msgid="1751643933430782312">"Nenhum"</string>
- <string name="keyguard_affordance_enablement_dialog_title" msgid="3389730825561696493">"Para selecionar \"<xliff:g id="APPNAME">%1$s</xliff:g>\", verifique o seguinte"</string>
- <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8117011931337357438">"Abrir <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
- <string name="keyguard_affordance_enablement_dialog_message" msgid="6136286758939253570">"Para adicionar a app <xliff:g id="APPNAME">%1$s</xliff:g> como um atalho, garanta"</string>
- <string name="keyguard_affordance_enablement_dialog_dismiss_button" msgid="629754625264422508">"Concluído"</string>
- <string name="keyguard_quick_affordance_title" msgid="4242813186995735584">"Atalhos"</string>
- <string name="keyguard_quick_affordance_section_title" msgid="2806304242671717309">"Atalhos"</string>
- <string name="keyguard_quick_affordance_two_selected_template" msgid="1757099194522296363">"<xliff:g id="FIRST">%1$s</xliff:g>, <xliff:g id="SECOND">%2$s</xliff:g>"</string>
- <string name="keyguard_quick_affordance_none_selected" msgid="8494127020144112003">"Nenhum"</string>
</resources>
diff --git a/res/values-pt/strings.xml b/res/values-pt/strings.xml
index e977269..c858265 100644
--- a/res/values-pt/strings.xml
+++ b/res/values-pt/strings.xml
@@ -19,9 +19,7 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_name" msgid="1647136562008520313">"Plano de fundo e estilo"</string>
<string name="theme_title" msgid="2144932106319405101">"Estilo"</string>
- <string name="clock_title" msgid="1974314575211361352">"Relógio personalizado"</string>
- <string name="clock_description" msgid="3563839327378948">"Escolha um relógio personalizado"</string>
- <string name="clock_picker_entry_content_description" msgid="8377139273468595734">"Edite um relógio personalizado"</string>
+ <string name="clock_title" msgid="2126046720254613991">"Relógio"</string>
<string name="grid_title" msgid="1688173478777254123">"Grade de apps"</string>
<string name="apply_theme_btn" msgid="6293081192321303991">"Aplicar"</string>
<string name="edit_custom_theme_lbl" msgid="5211377705710775224">"Toque para editar"</string>
@@ -91,15 +89,4 @@
<string name="preset_color_tab" msgid="3133391839341329314">"Cores básicas"</string>
<string name="color_changed" msgid="7029571720331641235">"Cor trocada"</string>
<string name="adaptive_color_title" msgid="1336508599235896205">"Dinâmica"</string>
- <string name="keyguard_slot_name_bottom_start" msgid="6717374042663171860">"Botão esquerdo"</string>
- <string name="keyguard_slot_name_bottom_end" msgid="7636885379738905151">"Botão direito"</string>
- <string name="keyguard_affordance_none" msgid="1751643933430782312">"Nenhum"</string>
- <string name="keyguard_affordance_enablement_dialog_title" msgid="3389730825561696493">"Para selecionar o app <xliff:g id="APPNAME">%1$s</xliff:g>, marque a opção a seguir"</string>
- <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8117011931337357438">"Abrir <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
- <string name="keyguard_affordance_enablement_dialog_message" msgid="6136286758939253570">"Para adicionar o app <xliff:g id="APPNAME">%1$s</xliff:g> como um atalho, confira se"</string>
- <string name="keyguard_affordance_enablement_dialog_dismiss_button" msgid="629754625264422508">"Concluído"</string>
- <string name="keyguard_quick_affordance_title" msgid="4242813186995735584">"Atalhos"</string>
- <string name="keyguard_quick_affordance_section_title" msgid="2806304242671717309">"Atalhos"</string>
- <string name="keyguard_quick_affordance_two_selected_template" msgid="1757099194522296363">"<xliff:g id="FIRST">%1$s</xliff:g>, <xliff:g id="SECOND">%2$s</xliff:g>"</string>
- <string name="keyguard_quick_affordance_none_selected" msgid="8494127020144112003">"Nenhum"</string>
</resources>
diff --git a/res/values-ro/strings.xml b/res/values-ro/strings.xml
index 6ccbbca..7389836 100644
--- a/res/values-ro/strings.xml
+++ b/res/values-ro/strings.xml
@@ -19,13 +19,11 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_name" msgid="1647136562008520313">"Imagine de fundal și stil"</string>
<string name="theme_title" msgid="2144932106319405101">"Stil"</string>
- <string name="clock_title" msgid="1974314575211361352">"Ecran personalizat"</string>
- <string name="clock_description" msgid="3563839327378948">"Alege un ecran personalizat"</string>
- <string name="clock_picker_entry_content_description" msgid="8377139273468595734">"Modifică un ecran personalizat"</string>
+ <string name="clock_title" msgid="2126046720254613991">"Ceas"</string>
<string name="grid_title" msgid="1688173478777254123">"Grilă aplicații"</string>
- <string name="apply_theme_btn" msgid="6293081192321303991">"Aplică"</string>
- <string name="edit_custom_theme_lbl" msgid="5211377705710775224">"Atinge pentru a modifica"</string>
- <string name="keep_my_wallpaper" msgid="8012385376769568517">"Păstrează imaginea de fundal actuală"</string>
+ <string name="apply_theme_btn" msgid="6293081192321303991">"Aplicați"</string>
+ <string name="edit_custom_theme_lbl" msgid="5211377705710775224">"Atingeți pentru a modifica"</string>
+ <string name="keep_my_wallpaper" msgid="8012385376769568517">"Păstrați imaginea de fundal actuală"</string>
<string name="theme_preview_card_content_description" msgid="5989222908619535533">"Previzualizarea stilului"</string>
<string name="grid_preview_card_content_description" msgid="8449383777584714842">"Previzualizarea grilei"</string>
<string name="font_preview_content_description" msgid="128230439293337891">"Previzualizarea fontului"</string>
@@ -35,7 +33,7 @@
<string name="option_applied_description" msgid="5022305212078053534">"S-a aplicat <xliff:g id="ID_1">%1$s</xliff:g> acum"</string>
<string name="option_applied_previewed_description" msgid="5269654286638446858">"<xliff:g id="ID_1">%1$s</xliff:g>, aplicată și previzualizată acum"</string>
<string name="option_previewed_description" msgid="3467217598865047661">"<xliff:g id="ID_1">%1$s</xliff:g>, previzualizată acum"</string>
- <string name="option_change_applied_previewed_description" msgid="9197311327728570816">"<xliff:g id="ID_1">%1$s</xliff:g>, modifică opțiunea selectată și previzualizată"</string>
+ <string name="option_change_applied_previewed_description" msgid="9197311327728570816">"<xliff:g id="ID_1">%1$s</xliff:g>, modificați opțiunea selectată și previzualizată"</string>
<string name="theme_description" msgid="3697012391785254635">"Font: <xliff:g id="ID_1">%1$s</xliff:g>, pictograme: <xliff:g id="ID_2">%2$s</xliff:g>, formă: <xliff:g id="ID_3">%3$s</xliff:g>, culoare: <xliff:g id="ID_4">%4$s</xliff:g>"</string>
<string name="default_theme_title" msgid="2555741736622366797">"Standard"</string>
<string name="preview_name_font" msgid="4465423899630037038">"Font"</string>
@@ -44,8 +42,8 @@
<string name="preview_name_shape" msgid="5676971146080968721">"Formă"</string>
<string name="preview_name_wallpaper" msgid="1738652462949531828">"Imagine de fundal"</string>
<string name="font_card_title" msgid="2343292653502548685">"ABC • abc • 123"</string>
- <string name="font_card_body" msgid="6790525594503904468">"Adaugă fonturile preferate pe fiecare ecran"</string>
- <string name="grid_options_title" msgid="7071930966989877023">"Alege o dimensiune de grilă"</string>
+ <string name="font_card_body" msgid="6790525594503904468">"Adăugați fonturile preferate pe fiecare ecran"</string>
+ <string name="grid_options_title" msgid="7071930966989877023">"Alegeți o dimensiune de grilă"</string>
<string name="grid_title_pattern" msgid="9188866567612607806">"<xliff:g id="ID_1">%1$d</xliff:g> x <xliff:g id="ID_2">%2$d</xliff:g>"</string>
<string name="applied_theme_msg" msgid="3749018706366796244">"Stilul a fost setat"</string>
<string name="applied_clock_msg" msgid="1303338016701443767">"Ceasul a fost setat"</string>
@@ -56,25 +54,25 @@
<string name="custom_theme" msgid="1618351922263478163">"Personalizat"</string>
<string name="custom_theme_title" msgid="2192300350332693631">"<xliff:g id="ID_1">%1$d</xliff:g> personalizat"</string>
<string name="custom_theme_fragment_title" msgid="6615547284702040280">"Stil personalizat"</string>
- <string name="custom_theme_delete" msgid="4744494663184126202">"Șterge"</string>
- <string name="font_component_title" msgid="8800340833695292049">"Alege fontul"</string>
- <string name="icon_component_title" msgid="5779787138399083903">"Alege pictogramele"</string>
- <string name="color_component_title" msgid="1194089273921078816">"Alege culoarea"</string>
- <string name="shape_component_title" msgid="8366847436022025538">"Alege o formă"</string>
- <string name="name_component_title" msgid="532425087968663437">"Denumește stilul"</string>
+ <string name="custom_theme_delete" msgid="4744494663184126202">"Ștergeți"</string>
+ <string name="font_component_title" msgid="8800340833695292049">"Alegeți fontul"</string>
+ <string name="icon_component_title" msgid="5779787138399083903">"Alegeți pictogramele"</string>
+ <string name="color_component_title" msgid="1194089273921078816">"Alegeți culoarea"</string>
+ <string name="shape_component_title" msgid="8366847436022025538">"Alegeți o formă"</string>
+ <string name="name_component_title" msgid="532425087968663437">"Denumiți stilul"</string>
<string name="icon_component_label" msgid="2625784884001407944">"Pictogramele <xliff:g id="ID_1">%1$d</xliff:g>"</string>
- <string name="delete_custom_theme_confirmation" msgid="4452137183628769394">"Ștergi stilul personalizat?"</string>
- <string name="delete_custom_theme_button" msgid="5102462988130208824">"Șterge"</string>
- <string name="cancel" msgid="4651030493668562067">"Anulează"</string>
- <string name="set_theme_wallpaper_dialog_message" msgid="2179661027350908003">"Setează imaginea de fundal pentru stil"</string>
- <string name="use_style_instead_title" msgid="1578754995763917502">"Folosești <xliff:g id="ID_1">%1$s</xliff:g> în schimb?"</string>
- <string name="use_style_instead_body" msgid="3051937045807471496">"Componentele pe care le-ai ales se potrivesc stilului <xliff:g id="ID_1">%1$s</xliff:g>. Dorești să folosești <xliff:g id="ID_2">%1$s</xliff:g> în schimb?"</string>
- <string name="use_style_button" msgid="1754493078383627019">"Folosește <xliff:g id="ID_1">%1$s</xliff:g>"</string>
+ <string name="delete_custom_theme_confirmation" msgid="4452137183628769394">"Ștergeți stilul personalizat?"</string>
+ <string name="delete_custom_theme_button" msgid="5102462988130208824">"Ștergeți"</string>
+ <string name="cancel" msgid="4651030493668562067">"Anulați"</string>
+ <string name="set_theme_wallpaper_dialog_message" msgid="2179661027350908003">"Setați imaginea de fundal pentru stil"</string>
+ <string name="use_style_instead_title" msgid="1578754995763917502">"Folosiți <xliff:g id="ID_1">%1$s</xliff:g> în schimb?"</string>
+ <string name="use_style_instead_body" msgid="3051937045807471496">"Componentele pe care le-ați ales se potrivesc stilului <xliff:g id="ID_1">%1$s</xliff:g>. Doriți să folosiți <xliff:g id="ID_2">%1$s</xliff:g> în schimb?"</string>
+ <string name="use_style_button" msgid="1754493078383627019">"Folosiți <xliff:g id="ID_1">%1$s</xliff:g>"</string>
<string name="no_thanks" msgid="7286616980115687627">"Nu, mulțumesc"</string>
<string name="clock_preview_content_description" msgid="5460561185905717460">"Previzualizarea ceasului <xliff:g id="ID_1">%1$s</xliff:g>"</string>
<string name="something_went_wrong" msgid="529840112449799117">"Hopa! Ceva nu a funcționat cum trebuie."</string>
<string name="theme_preview_icons_section_title" msgid="7064768910744000643">"Culoare/pictograme"</string>
- <string name="style_info_description" msgid="2612473574431003251">"Previzualizează fontul, pictogramele, forma aplicației și culoarea"</string>
+ <string name="style_info_description" msgid="2612473574431003251">"Previzualizați fontul, pictogramele, forma aplicației și culoarea"</string>
<string name="accessibility_custom_font_title" msgid="966867359157303705">"Font personalizat"</string>
<string name="accessibility_custom_icon_title" msgid="5753297905849062296">"Pictogramă personalizată"</string>
<string name="accessibility_custom_color_title" msgid="4124246598886320663">"Culoare personalizată"</string>
@@ -85,21 +83,10 @@
<string name="mode_changed" msgid="2243581369395418584">"Tema a fost schimbată"</string>
<string name="themed_icon_title" msgid="7312460430471956558">"Pictograme tematice"</string>
<string name="beta_title" msgid="8703819523760746458">"Beta"</string>
- <string name="gird_picker_entry_content_description" msgid="9087651470212293439">"Schimbă grila de aplicații"</string>
+ <string name="gird_picker_entry_content_description" msgid="9087651470212293439">"Schimbați grila de aplicații"</string>
<string name="wallpaper_color_tab" msgid="1447926591721403840">"Culori de fundal"</string>
<string name="wallpaper_color_title" msgid="5687965239180986458">"Culoarea imaginii de fundal"</string>
<string name="preset_color_tab" msgid="3133391839341329314">"Culori de bază"</string>
<string name="color_changed" msgid="7029571720331641235">"Culoare modificată"</string>
<string name="adaptive_color_title" msgid="1336508599235896205">"Dinamic"</string>
- <string name="keyguard_slot_name_bottom_start" msgid="6717374042663171860">"Butonul stâng"</string>
- <string name="keyguard_slot_name_bottom_end" msgid="7636885379738905151">"Butonul drept"</string>
- <string name="keyguard_affordance_none" msgid="1751643933430782312">"Fără"</string>
- <string name="keyguard_affordance_enablement_dialog_title" msgid="3389730825561696493">"Ca să selectezi <xliff:g id="APPNAME">%1$s</xliff:g>, urmează aceste instrucțiuni"</string>
- <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8117011931337357438">"Deschide <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
- <string name="keyguard_affordance_enablement_dialog_message" msgid="6136286758939253570">"Pentru a adăuga aplicația <xliff:g id="APPNAME">%1$s</xliff:g> drept comandă rapidă, asigură-te"</string>
- <string name="keyguard_affordance_enablement_dialog_dismiss_button" msgid="629754625264422508">"Gata"</string>
- <string name="keyguard_quick_affordance_title" msgid="4242813186995735584">"Comenzi rapide"</string>
- <string name="keyguard_quick_affordance_section_title" msgid="2806304242671717309">"Comenzi rapide"</string>
- <string name="keyguard_quick_affordance_two_selected_template" msgid="1757099194522296363">"<xliff:g id="FIRST">%1$s</xliff:g>, <xliff:g id="SECOND">%2$s</xliff:g>"</string>
- <string name="keyguard_quick_affordance_none_selected" msgid="8494127020144112003">"Niciunul"</string>
</resources>
diff --git a/res/values-ru/strings.xml b/res/values-ru/strings.xml
index 16567be..1a674ff 100644
--- a/res/values-ru/strings.xml
+++ b/res/values-ru/strings.xml
@@ -19,9 +19,7 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_name" msgid="1647136562008520313">"Обои и стиль"</string>
<string name="theme_title" msgid="2144932106319405101">"Стиль"</string>
- <string name="clock_title" msgid="1974314575211361352">"Настр. цифербл."</string>
- <string name="clock_description" msgid="3563839327378948">"Выбер. цифербл."</string>
- <string name="clock_picker_entry_content_description" msgid="8377139273468595734">"Выберите настраиваемый циферблат."</string>
+ <string name="clock_title" msgid="2126046720254613991">"Часы"</string>
<string name="grid_title" msgid="1688173478777254123">"Сетка приложений"</string>
<string name="apply_theme_btn" msgid="6293081192321303991">"Применить"</string>
<string name="edit_custom_theme_lbl" msgid="5211377705710775224">"Нажмите, чтобы изменить"</string>
@@ -91,15 +89,4 @@
<string name="preset_color_tab" msgid="3133391839341329314">"Основные цвета"</string>
<string name="color_changed" msgid="7029571720331641235">"Цвет изменен"</string>
<string name="adaptive_color_title" msgid="1336508599235896205">"Динамически"</string>
- <string name="keyguard_slot_name_bottom_start" msgid="6717374042663171860">"Левая кнопка"</string>
- <string name="keyguard_slot_name_bottom_end" msgid="7636885379738905151">"Правая кнопка"</string>
- <string name="keyguard_affordance_none" msgid="1751643933430782312">"Нет"</string>
- <string name="keyguard_affordance_enablement_dialog_title" msgid="3389730825561696493">"Чтобы выбрать приложение \"<xliff:g id="APPNAME">%1$s</xliff:g>\", сделайте следующее:"</string>
- <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8117011931337357438">"Открыть: <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
- <string name="keyguard_affordance_enablement_dialog_message" msgid="6136286758939253570">"Для добавления ярлыка приложения \"<xliff:g id="APPNAME">%1$s</xliff:g>\" должны выполняться следующие условия:"</string>
- <string name="keyguard_affordance_enablement_dialog_dismiss_button" msgid="629754625264422508">"ОК"</string>
- <string name="keyguard_quick_affordance_title" msgid="4242813186995735584">"Быстрые действия"</string>
- <string name="keyguard_quick_affordance_section_title" msgid="2806304242671717309">"Быстрые действия"</string>
- <string name="keyguard_quick_affordance_two_selected_template" msgid="1757099194522296363">"<xliff:g id="FIRST">%1$s</xliff:g>, <xliff:g id="SECOND">%2$s</xliff:g>"</string>
- <string name="keyguard_quick_affordance_none_selected" msgid="8494127020144112003">"Нет"</string>
</resources>
diff --git a/res/values-si/strings.xml b/res/values-si/strings.xml
index 05c1840..2e85b26 100644
--- a/res/values-si/strings.xml
+++ b/res/values-si/strings.xml
@@ -19,9 +19,7 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_name" msgid="1647136562008520313">"වෝල්පේපරය සහ මෝස්තරය"</string>
<string name="theme_title" msgid="2144932106319405101">"විලාසය"</string>
- <string name="clock_title" msgid="1974314575211361352">"අභිරුචි ඔරලෝසුව"</string>
- <string name="clock_description" msgid="3563839327378948">"අභිරුචි ඔරලෝසුවක් තෝරන්න"</string>
- <string name="clock_picker_entry_content_description" msgid="8377139273468595734">"අභිරුචි ඔරලෝසුවක් වෙනස් කරන්න"</string>
+ <string name="clock_title" msgid="2126046720254613991">"ඔරලෝසුව"</string>
<string name="grid_title" msgid="1688173478777254123">"යෙදුම් ජාලකය"</string>
<string name="apply_theme_btn" msgid="6293081192321303991">"යොදන්න"</string>
<string name="edit_custom_theme_lbl" msgid="5211377705710775224">"සංස්කරණයට තට්ටු කරන්න"</string>
@@ -91,15 +89,4 @@
<string name="preset_color_tab" msgid="3133391839341329314">"මූලික වර්ණ"</string>
<string name="color_changed" msgid="7029571720331641235">"වර්ණය වෙනස් විය"</string>
<string name="adaptive_color_title" msgid="1336508599235896205">"ගතික"</string>
- <string name="keyguard_slot_name_bottom_start" msgid="6717374042663171860">"වම් බොත්තම"</string>
- <string name="keyguard_slot_name_bottom_end" msgid="7636885379738905151">"දකුණු බොත්තම"</string>
- <string name="keyguard_affordance_none" msgid="1751643933430782312">"කිසිත් නැත"</string>
- <string name="keyguard_affordance_enablement_dialog_title" msgid="3389730825561696493">"`<xliff:g id="APPNAME">%1$s</xliff:g>` තේරීම සඳහා පහත දේ පරීක්ෂා කරන්න"</string>
- <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8117011931337357438">"<xliff:g id="APPNAME">%1$s</xliff:g> විවෘත කරන්න"</string>
- <string name="keyguard_affordance_enablement_dialog_message" msgid="6136286758939253570">"කෙටිමඟක් ලෙස <xliff:g id="APPNAME">%1$s</xliff:g> එක් කිරීමට, තහවුරු කර ගන්න"</string>
- <string name="keyguard_affordance_enablement_dialog_dismiss_button" msgid="629754625264422508">"නිමයි"</string>
- <string name="keyguard_quick_affordance_title" msgid="4242813186995735584">"කෙටිමං"</string>
- <string name="keyguard_quick_affordance_section_title" msgid="2806304242671717309">"කෙටිමං"</string>
- <string name="keyguard_quick_affordance_two_selected_template" msgid="1757099194522296363">"<xliff:g id="FIRST">%1$s</xliff:g>, <xliff:g id="SECOND">%2$s</xliff:g>"</string>
- <string name="keyguard_quick_affordance_none_selected" msgid="8494127020144112003">"කිසිවක් නැත"</string>
</resources>
diff --git a/res/values-sk/strings.xml b/res/values-sk/strings.xml
index 9deb70e..7431dec 100644
--- a/res/values-sk/strings.xml
+++ b/res/values-sk/strings.xml
@@ -19,9 +19,7 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_name" msgid="1647136562008520313">"Tapeta a štýl"</string>
<string name="theme_title" msgid="2144932106319405101">"Štýl"</string>
- <string name="clock_title" msgid="1974314575211361352">"Vlastné hodiny"</string>
- <string name="clock_description" msgid="3563839327378948">"Vyberte vlastné hodiny"</string>
- <string name="clock_picker_entry_content_description" msgid="8377139273468595734">"Zmeňte vlastné hodiny"</string>
+ <string name="clock_title" msgid="2126046720254613991">"Hodiny"</string>
<string name="grid_title" msgid="1688173478777254123">"Mriežka aplik."</string>
<string name="apply_theme_btn" msgid="6293081192321303991">"Použiť"</string>
<string name="edit_custom_theme_lbl" msgid="5211377705710775224">"Klepnutím upravte"</string>
@@ -91,15 +89,4 @@
<string name="preset_color_tab" msgid="3133391839341329314">"Základné farby"</string>
<string name="color_changed" msgid="7029571720331641235">"Farba bola zmenená"</string>
<string name="adaptive_color_title" msgid="1336508599235896205">"Dynamické"</string>
- <string name="keyguard_slot_name_bottom_start" msgid="6717374042663171860">"Ľavé tlačidlo"</string>
- <string name="keyguard_slot_name_bottom_end" msgid="7636885379738905151">"Pravé tlačidlo"</string>
- <string name="keyguard_affordance_none" msgid="1751643933430782312">"Žiadne"</string>
- <string name="keyguard_affordance_enablement_dialog_title" msgid="3389730825561696493">"Ak chcete vybrať aplikáciu <xliff:g id="APPNAME">%1$s</xliff:g>, skontrolujte nasledovné"</string>
- <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8117011931337357438">"Otvoriť <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
- <string name="keyguard_affordance_enablement_dialog_message" msgid="6136286758939253570">"Ak chcete aplikáciu <xliff:g id="APPNAME">%1$s</xliff:g> pridať ako odkaz, uistite sa, že"</string>
- <string name="keyguard_affordance_enablement_dialog_dismiss_button" msgid="629754625264422508">"Hotovo"</string>
- <string name="keyguard_quick_affordance_title" msgid="4242813186995735584">"Skratky"</string>
- <string name="keyguard_quick_affordance_section_title" msgid="2806304242671717309">"Skratky"</string>
- <string name="keyguard_quick_affordance_two_selected_template" msgid="1757099194522296363">"<xliff:g id="FIRST">%1$s</xliff:g>, <xliff:g id="SECOND">%2$s</xliff:g>"</string>
- <string name="keyguard_quick_affordance_none_selected" msgid="8494127020144112003">"Žiadne"</string>
</resources>
diff --git a/res/values-sl/strings.xml b/res/values-sl/strings.xml
index 218605a..a637d4f 100644
--- a/res/values-sl/strings.xml
+++ b/res/values-sl/strings.xml
@@ -19,9 +19,7 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_name" msgid="1647136562008520313">"Zaslonsko ozadje in slog"</string>
<string name="theme_title" msgid="2144932106319405101">"Slog"</string>
- <string name="clock_title" msgid="1974314575211361352">"Ura po meri"</string>
- <string name="clock_description" msgid="3563839327378948">"Izberite uro po meri"</string>
- <string name="clock_picker_entry_content_description" msgid="8377139273468595734">"Spremenite uro po meri"</string>
+ <string name="clock_title" msgid="2126046720254613991">"Ura"</string>
<string name="grid_title" msgid="1688173478777254123">"Mreža aplikacij"</string>
<string name="apply_theme_btn" msgid="6293081192321303991">"Uporabi"</string>
<string name="edit_custom_theme_lbl" msgid="5211377705710775224">"Dotaknite se za urejanje"</string>
@@ -91,15 +89,4 @@
<string name="preset_color_tab" msgid="3133391839341329314">"Osnovne barve"</string>
<string name="color_changed" msgid="7029571720331641235">"Barva je spremenjena."</string>
<string name="adaptive_color_title" msgid="1336508599235896205">"Dinamično"</string>
- <string name="keyguard_slot_name_bottom_start" msgid="6717374042663171860">"Levi gumb"</string>
- <string name="keyguard_slot_name_bottom_end" msgid="7636885379738905151">"Desni gumb"</string>
- <string name="keyguard_affordance_none" msgid="1751643933430782312">"Brez"</string>
- <string name="keyguard_affordance_enablement_dialog_title" msgid="3389730825561696493">"Če želite izbrati aplikacijo »<xliff:g id="APPNAME">%1$s</xliff:g>«, potrdite naslednje:"</string>
- <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8117011931337357438">"Odpri <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
- <string name="keyguard_affordance_enablement_dialog_message" msgid="6136286758939253570">"Če želite aplikacijo <xliff:g id="APPNAME">%1$s</xliff:g> dodati kot bližnjico, zagotovite naslednje:"</string>
- <string name="keyguard_affordance_enablement_dialog_dismiss_button" msgid="629754625264422508">"Končano"</string>
- <string name="keyguard_quick_affordance_title" msgid="4242813186995735584">"Bližnjice"</string>
- <string name="keyguard_quick_affordance_section_title" msgid="2806304242671717309">"Bližnjice"</string>
- <string name="keyguard_quick_affordance_two_selected_template" msgid="1757099194522296363">"<xliff:g id="FIRST">%1$s</xliff:g>, <xliff:g id="SECOND">%2$s</xliff:g>"</string>
- <string name="keyguard_quick_affordance_none_selected" msgid="8494127020144112003">"Brez"</string>
</resources>
diff --git a/res/values-sq/strings.xml b/res/values-sq/strings.xml
index 5b8ad1c..8f6259c 100644
--- a/res/values-sq/strings.xml
+++ b/res/values-sq/strings.xml
@@ -19,9 +19,7 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_name" msgid="1647136562008520313">"Imazhi i sfondit dhe stili"</string>
<string name="theme_title" msgid="2144932106319405101">"Stili"</string>
- <string name="clock_title" msgid="1974314575211361352">"Orë e personalizuar"</string>
- <string name="clock_description" msgid="3563839327378948">"Orë e personalizuar"</string>
- <string name="clock_picker_entry_content_description" msgid="8377139273468595734">"Ndrysho orën e personalizuar"</string>
+ <string name="clock_title" msgid="2126046720254613991">"Ora"</string>
<string name="grid_title" msgid="1688173478777254123">"Rrjeta e aplikacioneve"</string>
<string name="apply_theme_btn" msgid="6293081192321303991">"Zbato"</string>
<string name="edit_custom_theme_lbl" msgid="5211377705710775224">"Trokit për të modifikuar"</string>
@@ -91,15 +89,4 @@
<string name="preset_color_tab" msgid="3133391839341329314">"Ngjyra bazë"</string>
<string name="color_changed" msgid="7029571720331641235">"Ngjyra ka ndryshuar"</string>
<string name="adaptive_color_title" msgid="1336508599235896205">"Dinamike"</string>
- <string name="keyguard_slot_name_bottom_start" msgid="6717374042663171860">"Butoni i majtë"</string>
- <string name="keyguard_slot_name_bottom_end" msgid="7636885379738905151">"Butoni i djathtë"</string>
- <string name="keyguard_affordance_none" msgid="1751643933430782312">"Asnjë"</string>
- <string name="keyguard_affordance_enablement_dialog_title" msgid="3389730825561696493">"Për të zgjedhur \"<xliff:g id="APPNAME">%1$s</xliff:g>\", kontrollo si më poshtë"</string>
- <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8117011931337357438">"Hap \"<xliff:g id="APPNAME">%1$s</xliff:g>\""</string>
- <string name="keyguard_affordance_enablement_dialog_message" msgid="6136286758939253570">"Për të shtuar aplikacionin \"<xliff:g id="APPNAME">%1$s</xliff:g>\" si një shkurtore, sigurohu që"</string>
- <string name="keyguard_affordance_enablement_dialog_dismiss_button" msgid="629754625264422508">"U krye"</string>
- <string name="keyguard_quick_affordance_title" msgid="4242813186995735584">"Shkurtoret"</string>
- <string name="keyguard_quick_affordance_section_title" msgid="2806304242671717309">"Shkurtoret"</string>
- <string name="keyguard_quick_affordance_two_selected_template" msgid="1757099194522296363">"<xliff:g id="FIRST">%1$s</xliff:g>, <xliff:g id="SECOND">%2$s</xliff:g>"</string>
- <string name="keyguard_quick_affordance_none_selected" msgid="8494127020144112003">"Asnjë"</string>
</resources>
diff --git a/res/values-sr/strings.xml b/res/values-sr/strings.xml
index 8fbb505..3a7de2b 100644
--- a/res/values-sr/strings.xml
+++ b/res/values-sr/strings.xml
@@ -19,9 +19,7 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_name" msgid="1647136562008520313">"Позадина и стил"</string>
<string name="theme_title" msgid="2144932106319405101">"Стил"</string>
- <string name="clock_title" msgid="1974314575211361352">"Прилагођени сат"</string>
- <string name="clock_description" msgid="3563839327378948">"Прилагођени сат"</string>
- <string name="clock_picker_entry_content_description" msgid="8377139273468595734">"Промените прилагођени сат"</string>
+ <string name="clock_title" msgid="2126046720254613991">"Сат"</string>
<string name="grid_title" msgid="1688173478777254123">"Мрежа апл."</string>
<string name="apply_theme_btn" msgid="6293081192321303991">"Примени"</string>
<string name="edit_custom_theme_lbl" msgid="5211377705710775224">"Додирните да бисте изменили"</string>
@@ -91,15 +89,4 @@
<string name="preset_color_tab" msgid="3133391839341329314">"Основне боје"</string>
<string name="color_changed" msgid="7029571720331641235">"Боја је промењена"</string>
<string name="adaptive_color_title" msgid="1336508599235896205">"Динамички"</string>
- <string name="keyguard_slot_name_bottom_start" msgid="6717374042663171860">"Лево дугме"</string>
- <string name="keyguard_slot_name_bottom_end" msgid="7636885379738905151">"Десно дугме"</string>
- <string name="keyguard_affordance_none" msgid="1751643933430782312">"Ништа"</string>
- <string name="keyguard_affordance_enablement_dialog_title" msgid="3389730825561696493">"Да бисте изабрали „<xliff:g id="APPNAME">%1$s</xliff:g>“, проверите следеће"</string>
- <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8117011931337357438">"Отворите: <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
- <string name="keyguard_affordance_enablement_dialog_message" msgid="6136286758939253570">"Да бисте додали апликацију <xliff:g id="APPNAME">%1$s</xliff:g> као пречицу, уверите се"</string>
- <string name="keyguard_affordance_enablement_dialog_dismiss_button" msgid="629754625264422508">"Готово"</string>
- <string name="keyguard_quick_affordance_title" msgid="4242813186995735584">"Пречице"</string>
- <string name="keyguard_quick_affordance_section_title" msgid="2806304242671717309">"Пречице"</string>
- <string name="keyguard_quick_affordance_two_selected_template" msgid="1757099194522296363">"<xliff:g id="FIRST">%1$s</xliff:g>, <xliff:g id="SECOND">%2$s</xliff:g>"</string>
- <string name="keyguard_quick_affordance_none_selected" msgid="8494127020144112003">"Ништа"</string>
</resources>
diff --git a/res/values-sv/strings.xml b/res/values-sv/strings.xml
index 5395735..d16ff0f 100644
--- a/res/values-sv/strings.xml
+++ b/res/values-sv/strings.xml
@@ -19,9 +19,7 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_name" msgid="1647136562008520313">"Bakgrund och utseende"</string>
<string name="theme_title" msgid="2144932106319405101">"Format"</string>
- <string name="clock_title" msgid="1974314575211361352">"Anpassad klocka"</string>
- <string name="clock_description" msgid="3563839327378948">"Välj anpassad klocka"</string>
- <string name="clock_picker_entry_content_description" msgid="8377139273468595734">"Ändra en anpassad klocka"</string>
+ <string name="clock_title" msgid="2126046720254613991">"Klocka"</string>
<string name="grid_title" msgid="1688173478777254123">"Apprutnät"</string>
<string name="apply_theme_btn" msgid="6293081192321303991">"Använd"</string>
<string name="edit_custom_theme_lbl" msgid="5211377705710775224">"Tryck för att redigera"</string>
@@ -91,15 +89,4 @@
<string name="preset_color_tab" msgid="3133391839341329314">"Standardfärger"</string>
<string name="color_changed" msgid="7029571720331641235">"Färgen har ändrats"</string>
<string name="adaptive_color_title" msgid="1336508599235896205">"Dynamisk"</string>
- <string name="keyguard_slot_name_bottom_start" msgid="6717374042663171860">"Vänsterknapp"</string>
- <string name="keyguard_slot_name_bottom_end" msgid="7636885379738905151">"Högerknapp"</string>
- <string name="keyguard_affordance_none" msgid="1751643933430782312">"Inga"</string>
- <string name="keyguard_affordance_enablement_dialog_title" msgid="3389730825561696493">"Om du vill välja <xliff:g id="APPNAME">%1$s</xliff:g> markerar du följande"</string>
- <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8117011931337357438">"Öppna <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
- <string name="keyguard_affordance_enablement_dialog_message" msgid="6136286758939253570">"Om du vill lägga till <xliff:g id="APPNAME">%1$s</xliff:g>-appen som en genväg ser du till att"</string>
- <string name="keyguard_affordance_enablement_dialog_dismiss_button" msgid="629754625264422508">"Klar"</string>
- <string name="keyguard_quick_affordance_title" msgid="4242813186995735584">"Genvägar"</string>
- <string name="keyguard_quick_affordance_section_title" msgid="2806304242671717309">"Genvägar"</string>
- <string name="keyguard_quick_affordance_two_selected_template" msgid="1757099194522296363">"<xliff:g id="FIRST">%1$s</xliff:g>, <xliff:g id="SECOND">%2$s</xliff:g>"</string>
- <string name="keyguard_quick_affordance_none_selected" msgid="8494127020144112003">"Inga"</string>
</resources>
diff --git a/res/values-sw/strings.xml b/res/values-sw/strings.xml
index 88fca60..1a01433 100644
--- a/res/values-sw/strings.xml
+++ b/res/values-sw/strings.xml
@@ -19,9 +19,7 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_name" msgid="1647136562008520313">"Mandhari na mtindo"</string>
<string name="theme_title" msgid="2144932106319405101">"Mtindo"</string>
- <string name="clock_title" msgid="1974314575211361352">"Saa Maalum"</string>
- <string name="clock_description" msgid="3563839327378948">"Chagua saa maalum"</string>
- <string name="clock_picker_entry_content_description" msgid="8377139273468595734">"Badili saa maalum"</string>
+ <string name="clock_title" msgid="2126046720254613991">"Saa"</string>
<string name="grid_title" msgid="1688173478777254123">"Gridi ya programu"</string>
<string name="apply_theme_btn" msgid="6293081192321303991">"Tumia"</string>
<string name="edit_custom_theme_lbl" msgid="5211377705710775224">"Gusa ili ubadilishe"</string>
@@ -83,7 +81,7 @@
<string name="mode_title" msgid="2394873501427436055">"Mandhari meusi"</string>
<string name="mode_disabled_msg" msgid="9196245518435936512">"Imezimwa kwa muda kwa sababu ya Kiokoa Betri"</string>
<string name="mode_changed" msgid="2243581369395418584">"Mandhari yamebadilishwa"</string>
- <string name="themed_icon_title" msgid="7312460430471956558">"Aikoni zenye mitindo"</string>
+ <string name="themed_icon_title" msgid="7312460430471956558">"Aikoni zenye mada"</string>
<string name="beta_title" msgid="8703819523760746458">"Beta"</string>
<string name="gird_picker_entry_content_description" msgid="9087651470212293439">"Badilisha gridi ya programu"</string>
<string name="wallpaper_color_tab" msgid="1447926591721403840">"Rangi za mandhari"</string>
@@ -91,15 +89,4 @@
<string name="preset_color_tab" msgid="3133391839341329314">"Rangi za msingi"</string>
<string name="color_changed" msgid="7029571720331641235">"Rangi imebadilishwa"</string>
<string name="adaptive_color_title" msgid="1336508599235896205">"Inayobadilika"</string>
- <string name="keyguard_slot_name_bottom_start" msgid="6717374042663171860">"Kitufe cha kushoto"</string>
- <string name="keyguard_slot_name_bottom_end" msgid="7636885379738905151">"Kitufe cha kulia"</string>
- <string name="keyguard_affordance_none" msgid="1751643933430782312">"Hamna"</string>
- <string name="keyguard_affordance_enablement_dialog_title" msgid="3389730825561696493">"Ili uchague `<xliff:g id="APPNAME">%1$s</xliff:g>` zingatia yafuatayo"</string>
- <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8117011931337357438">"Fungua <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
- <string name="keyguard_affordance_enablement_dialog_message" msgid="6136286758939253570">"Ili kuweka programu ya <xliff:g id="APPNAME">%1$s</xliff:g> kuwa njia ya mkato, hakikisha"</string>
- <string name="keyguard_affordance_enablement_dialog_dismiss_button" msgid="629754625264422508">"Nimemaliza"</string>
- <string name="keyguard_quick_affordance_title" msgid="4242813186995735584">"Njia za mkato"</string>
- <string name="keyguard_quick_affordance_section_title" msgid="2806304242671717309">"Njia za mkato"</string>
- <string name="keyguard_quick_affordance_two_selected_template" msgid="1757099194522296363">"<xliff:g id="FIRST">%1$s</xliff:g>, <xliff:g id="SECOND">%2$s</xliff:g>"</string>
- <string name="keyguard_quick_affordance_none_selected" msgid="8494127020144112003">"Hamna"</string>
</resources>
diff --git a/res/values-ta/strings.xml b/res/values-ta/strings.xml
index 2be8940..3a2bffb 100644
--- a/res/values-ta/strings.xml
+++ b/res/values-ta/strings.xml
@@ -19,9 +19,7 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_name" msgid="1647136562008520313">"வால்பேப்பரும் ஸ்டைலும்"</string>
<string name="theme_title" msgid="2144932106319405101">"ஸ்டைல்"</string>
- <string name="clock_title" msgid="1974314575211361352">"பிரத்தியேகக் கடிகாரம்"</string>
- <string name="clock_description" msgid="3563839327378948">"பிரத்தியேகக் கடிகாரத்தைத் தேர்வுசெய்க"</string>
- <string name="clock_picker_entry_content_description" msgid="8377139273468595734">"பிரத்தியேகக் கடிகாரத்தை மாற்றும்"</string>
+ <string name="clock_title" msgid="2126046720254613991">"கடிகாரம்"</string>
<string name="grid_title" msgid="1688173478777254123">"ஆப்ஸ் கட்டம்"</string>
<string name="apply_theme_btn" msgid="6293081192321303991">"பயன்படுத்து"</string>
<string name="edit_custom_theme_lbl" msgid="5211377705710775224">"\'தீமைத்\' திருத்த தட்டவும்"</string>
@@ -91,15 +89,4 @@
<string name="preset_color_tab" msgid="3133391839341329314">"அடிப்படை வண்ணங்கள்"</string>
<string name="color_changed" msgid="7029571720331641235">"வண்ணம் மாற்றப்பட்டது"</string>
<string name="adaptive_color_title" msgid="1336508599235896205">"டைனமிக்"</string>
- <string name="keyguard_slot_name_bottom_start" msgid="6717374042663171860">"இடது பட்டன்"</string>
- <string name="keyguard_slot_name_bottom_end" msgid="7636885379738905151">"வலது பட்டன்"</string>
- <string name="keyguard_affordance_none" msgid="1751643933430782312">"ஏதுமில்லை"</string>
- <string name="keyguard_affordance_enablement_dialog_title" msgid="3389730825561696493">"`<xliff:g id="APPNAME">%1$s</xliff:g>` ஆப்ஸைத் தேர்ந்தெடுக்க பின்வருபவற்றைச் சரிபார்க்கவும்"</string>
- <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8117011931337357438">"<xliff:g id="APPNAME">%1$s</xliff:g> ஐத் திறக்கும்"</string>
- <string name="keyguard_affordance_enablement_dialog_message" msgid="6136286758939253570">"<xliff:g id="APPNAME">%1$s</xliff:g> ஆப்ஸை ஷார்ட்கட்டாகச் சேர்க்க இவற்றைப் பின்பற்றுவதை உறுதிசெய்துகொள்ளவும்:"</string>
- <string name="keyguard_affordance_enablement_dialog_dismiss_button" msgid="629754625264422508">"சரி"</string>
- <string name="keyguard_quick_affordance_title" msgid="4242813186995735584">"ஷார்ட்கட்கள்"</string>
- <string name="keyguard_quick_affordance_section_title" msgid="2806304242671717309">"ஷார்ட்கட்கள்"</string>
- <string name="keyguard_quick_affordance_two_selected_template" msgid="1757099194522296363">"<xliff:g id="FIRST">%1$s</xliff:g>, <xliff:g id="SECOND">%2$s</xliff:g>"</string>
- <string name="keyguard_quick_affordance_none_selected" msgid="8494127020144112003">"ஏதுமில்லை"</string>
</resources>
diff --git a/res/values-te/strings.xml b/res/values-te/strings.xml
index 9e1829d..72fd0c3 100644
--- a/res/values-te/strings.xml
+++ b/res/values-te/strings.xml
@@ -19,9 +19,7 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_name" msgid="1647136562008520313">"వాల్పేపర్ & స్టయిల్"</string>
<string name="theme_title" msgid="2144932106319405101">"శైలి"</string>
- <string name="clock_title" msgid="1974314575211361352">"అనుకూల గడియారం"</string>
- <string name="clock_description" msgid="3563839327378948">"అనుకూల గడియారాన్ని ఎంచుకోండి"</string>
- <string name="clock_picker_entry_content_description" msgid="8377139273468595734">"అనుకూల గడియారాన్ని మార్చండి"</string>
+ <string name="clock_title" msgid="2126046720254613991">"గడియారం"</string>
<string name="grid_title" msgid="1688173478777254123">"యాప్ గ్రిడ్"</string>
<string name="apply_theme_btn" msgid="6293081192321303991">"వర్తింపజేయి"</string>
<string name="edit_custom_theme_lbl" msgid="5211377705710775224">"ఎడిట్ చేయడానికి నొక్కండి"</string>
@@ -56,7 +54,7 @@
<string name="custom_theme" msgid="1618351922263478163">"అనుకూలం"</string>
<string name="custom_theme_title" msgid="2192300350332693631">"అనుకూల <xliff:g id="ID_1">%1$d</xliff:g>"</string>
<string name="custom_theme_fragment_title" msgid="6615547284702040280">"అనుకూల శైలి"</string>
- <string name="custom_theme_delete" msgid="4744494663184126202">"తొలగించండి"</string>
+ <string name="custom_theme_delete" msgid="4744494663184126202">"తొలగించు"</string>
<string name="font_component_title" msgid="8800340833695292049">"ఫాంట్ను ఎంచుకోండి"</string>
<string name="icon_component_title" msgid="5779787138399083903">"చిహ్నాలను ఎంచుకోండి"</string>
<string name="color_component_title" msgid="1194089273921078816">"రంగును ఎంచుకోండి"</string>
@@ -64,12 +62,12 @@
<string name="name_component_title" msgid="532425087968663437">"మీ శైలికి పేరు పెట్టండి"</string>
<string name="icon_component_label" msgid="2625784884001407944">"<xliff:g id="ID_1">%1$d</xliff:g> చిహ్నాలు"</string>
<string name="delete_custom_theme_confirmation" msgid="4452137183628769394">"అనుకూల శైలిని తొలగించాలా?"</string>
- <string name="delete_custom_theme_button" msgid="5102462988130208824">"తొలగించండి"</string>
- <string name="cancel" msgid="4651030493668562067">"రద్దు చేయండి"</string>
+ <string name="delete_custom_theme_button" msgid="5102462988130208824">"తొలగించు"</string>
+ <string name="cancel" msgid="4651030493668562067">"రద్దు చేయి"</string>
<string name="set_theme_wallpaper_dialog_message" msgid="2179661027350908003">"వాల్పేపర్ శైలిని సెట్ చేయండి"</string>
<string name="use_style_instead_title" msgid="1578754995763917502">"బదులుగా <xliff:g id="ID_1">%1$s</xliff:g>ని ఉపయోగించాలా?"</string>
<string name="use_style_instead_body" msgid="3051937045807471496">"మీరు ఎంచుకున్న భాగాలు <xliff:g id="ID_1">%1$s</xliff:g> శైలికి సరిపోతాయి. బదులుగా మీరు <xliff:g id="ID_2">%1$s</xliff:g>ని ఉపయోగించాలనుకుంటున్నారా?"</string>
- <string name="use_style_button" msgid="1754493078383627019">"<xliff:g id="ID_1">%1$s</xliff:g>ని ఉపయోగించండి"</string>
+ <string name="use_style_button" msgid="1754493078383627019">"<xliff:g id="ID_1">%1$s</xliff:g>ని ఉపయోగించు"</string>
<string name="no_thanks" msgid="7286616980115687627">"వద్దు, ధన్యవాదం"</string>
<string name="clock_preview_content_description" msgid="5460561185905717460">"<xliff:g id="ID_1">%1$s</xliff:g> గడియార ప్రివ్యూ"</string>
<string name="something_went_wrong" msgid="529840112449799117">"అయ్యో, ఏదో తప్పు జరిగింది."</string>
@@ -91,15 +89,4 @@
<string name="preset_color_tab" msgid="3133391839341329314">"ప్రాథమిక రంగులు"</string>
<string name="color_changed" msgid="7029571720331641235">"రంగు మార్చబడింది"</string>
<string name="adaptive_color_title" msgid="1336508599235896205">"డైనమిక్"</string>
- <string name="keyguard_slot_name_bottom_start" msgid="6717374042663171860">"ఎడమవైపు బటన్"</string>
- <string name="keyguard_slot_name_bottom_end" msgid="7636885379738905151">"కుడివైపు బటన్"</string>
- <string name="keyguard_affordance_none" msgid="1751643933430782312">"ఏదీ లేదు"</string>
- <string name="keyguard_affordance_enablement_dialog_title" msgid="3389730825561696493">"`<xliff:g id="APPNAME">%1$s</xliff:g>` యాప్ను ఎంచుకోవడానికి దిగువ ఉన్న సూచనలను చూడండి."</string>
- <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8117011931337357438">"<xliff:g id="APPNAME">%1$s</xliff:g>ను తెరవండి"</string>
- <string name="keyguard_affordance_enablement_dialog_message" msgid="6136286758939253570">"<xliff:g id="APPNAME">%1$s</xliff:g> యాప్ను షార్ట్కట్గా జోడించడానికి, వీటిని నిర్ధారించుకోండి"</string>
- <string name="keyguard_affordance_enablement_dialog_dismiss_button" msgid="629754625264422508">"పూర్తయింది"</string>
- <string name="keyguard_quick_affordance_title" msgid="4242813186995735584">"షార్ట్కట్లు"</string>
- <string name="keyguard_quick_affordance_section_title" msgid="2806304242671717309">"షార్ట్కట్లు"</string>
- <string name="keyguard_quick_affordance_two_selected_template" msgid="1757099194522296363">"<xliff:g id="FIRST">%1$s</xliff:g>, <xliff:g id="SECOND">%2$s</xliff:g>"</string>
- <string name="keyguard_quick_affordance_none_selected" msgid="8494127020144112003">"ఏదీ ఎంచుకోలేదు"</string>
</resources>
diff --git a/res/values-th/strings.xml b/res/values-th/strings.xml
index 101675d..3375c30 100644
--- a/res/values-th/strings.xml
+++ b/res/values-th/strings.xml
@@ -19,9 +19,7 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_name" msgid="1647136562008520313">"วอลเปเปอร์และรูปแบบ"</string>
<string name="theme_title" msgid="2144932106319405101">"รูปแบบ"</string>
- <string name="clock_title" msgid="1974314575211361352">"นาฬิกาที่กำหนดเอง"</string>
- <string name="clock_description" msgid="3563839327378948">"เลือกนาฬิกาที่กำหนดเอง"</string>
- <string name="clock_picker_entry_content_description" msgid="8377139273468595734">"เปลี่ยนนาฬิกาที่กำหนดเอง"</string>
+ <string name="clock_title" msgid="2126046720254613991">"นาฬิกา"</string>
<string name="grid_title" msgid="1688173478777254123">"ตารางกริดแอป"</string>
<string name="apply_theme_btn" msgid="6293081192321303991">"ใช้"</string>
<string name="edit_custom_theme_lbl" msgid="5211377705710775224">"แตะเพื่อแก้ไข"</string>
@@ -91,15 +89,4 @@
<string name="preset_color_tab" msgid="3133391839341329314">"สีพื้นฐาน"</string>
<string name="color_changed" msgid="7029571720331641235">"เปลี่ยนสีแล้ว"</string>
<string name="adaptive_color_title" msgid="1336508599235896205">"ไดนามิก"</string>
- <string name="keyguard_slot_name_bottom_start" msgid="6717374042663171860">"ปุ่มซ้าย"</string>
- <string name="keyguard_slot_name_bottom_end" msgid="7636885379738905151">"ปุ่มขวา"</string>
- <string name="keyguard_affordance_none" msgid="1751643933430782312">"ไม่มี"</string>
- <string name="keyguard_affordance_enablement_dialog_title" msgid="3389730825561696493">"หากต้องการเลือก \"<xliff:g id="APPNAME">%1$s</xliff:g>\" โปรดตรวจสอบรายการต่อไปนี้"</string>
- <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8117011931337357438">"เปิด <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
- <string name="keyguard_affordance_enablement_dialog_message" msgid="6136286758939253570">"หากต้องการเพิ่มแอป <xliff:g id="APPNAME">%1$s</xliff:g> เป็นทางลัด โปรดตรวจสอบดังต่อไปนี้"</string>
- <string name="keyguard_affordance_enablement_dialog_dismiss_button" msgid="629754625264422508">"เสร็จสิ้น"</string>
- <string name="keyguard_quick_affordance_title" msgid="4242813186995735584">"ทางลัด"</string>
- <string name="keyguard_quick_affordance_section_title" msgid="2806304242671717309">"ทางลัด"</string>
- <string name="keyguard_quick_affordance_two_selected_template" msgid="1757099194522296363">"<xliff:g id="FIRST">%1$s</xliff:g>, <xliff:g id="SECOND">%2$s</xliff:g>"</string>
- <string name="keyguard_quick_affordance_none_selected" msgid="8494127020144112003">"ไม่มี"</string>
</resources>
diff --git a/res/values-tl/strings.xml b/res/values-tl/strings.xml
index 3413b27..591a107 100644
--- a/res/values-tl/strings.xml
+++ b/res/values-tl/strings.xml
@@ -19,9 +19,7 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_name" msgid="1647136562008520313">"Wallpaper & istilo"</string>
<string name="theme_title" msgid="2144932106319405101">"Istilo"</string>
- <string name="clock_title" msgid="1974314575211361352">"Custom na Orasan"</string>
- <string name="clock_description" msgid="3563839327378948">"Pumili ng custom na orasan"</string>
- <string name="clock_picker_entry_content_description" msgid="8377139273468595734">"Magbago ng custom na orasan"</string>
+ <string name="clock_title" msgid="2126046720254613991">"Orasan"</string>
<string name="grid_title" msgid="1688173478777254123">"Grid ng app"</string>
<string name="apply_theme_btn" msgid="6293081192321303991">"Ilapat"</string>
<string name="edit_custom_theme_lbl" msgid="5211377705710775224">"I-tap para ma-edit"</string>
@@ -91,15 +89,4 @@
<string name="preset_color_tab" msgid="3133391839341329314">"Mga basic na kulay"</string>
<string name="color_changed" msgid="7029571720331641235">"Pinalitan ang kulay"</string>
<string name="adaptive_color_title" msgid="1336508599235896205">"Dynamic"</string>
- <string name="keyguard_slot_name_bottom_start" msgid="6717374042663171860">"Kaliwang button"</string>
- <string name="keyguard_slot_name_bottom_end" msgid="7636885379738905151">"Kanang button"</string>
- <string name="keyguard_affordance_none" msgid="1751643933430782312">"Wala"</string>
- <string name="keyguard_affordance_enablement_dialog_title" msgid="3389730825561696493">"Para piliin ang `<xliff:g id="APPNAME">%1$s</xliff:g>,` tingnan ang sumusunod"</string>
- <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8117011931337357438">"Buksan ang <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
- <string name="keyguard_affordance_enablement_dialog_message" msgid="6136286758939253570">"Para idagdag ang <xliff:g id="APPNAME">%1$s</xliff:g> app bilang shortcut, tiyaking"</string>
- <string name="keyguard_affordance_enablement_dialog_dismiss_button" msgid="629754625264422508">"Tapos na"</string>
- <string name="keyguard_quick_affordance_title" msgid="4242813186995735584">"Mga Shortcut"</string>
- <string name="keyguard_quick_affordance_section_title" msgid="2806304242671717309">"Mga Shortcut"</string>
- <string name="keyguard_quick_affordance_two_selected_template" msgid="1757099194522296363">"<xliff:g id="FIRST">%1$s</xliff:g>, <xliff:g id="SECOND">%2$s</xliff:g>"</string>
- <string name="keyguard_quick_affordance_none_selected" msgid="8494127020144112003">"Wala"</string>
</resources>
diff --git a/res/values-tr/strings.xml b/res/values-tr/strings.xml
index 864a1c2..e90cc22 100644
--- a/res/values-tr/strings.xml
+++ b/res/values-tr/strings.xml
@@ -19,9 +19,7 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_name" msgid="1647136562008520313">"Duvar kağıdı ve stil"</string>
<string name="theme_title" msgid="2144932106319405101">"Stil"</string>
- <string name="clock_title" msgid="1974314575211361352">"Özel Saat"</string>
- <string name="clock_description" msgid="3563839327378948">"Özel saat seçin"</string>
- <string name="clock_picker_entry_content_description" msgid="8377139273468595734">"Özel saati değiştirin"</string>
+ <string name="clock_title" msgid="2126046720254613991">"Saat"</string>
<string name="grid_title" msgid="1688173478777254123">"Uygulama tablosu"</string>
<string name="apply_theme_btn" msgid="6293081192321303991">"Uygula"</string>
<string name="edit_custom_theme_lbl" msgid="5211377705710775224">"Düzenlemek için dokunun"</string>
@@ -91,15 +89,4 @@
<string name="preset_color_tab" msgid="3133391839341329314">"Temel renkler"</string>
<string name="color_changed" msgid="7029571720331641235">"Renk değişti"</string>
<string name="adaptive_color_title" msgid="1336508599235896205">"Dinamik"</string>
- <string name="keyguard_slot_name_bottom_start" msgid="6717374042663171860">"Sol düğmesi"</string>
- <string name="keyguard_slot_name_bottom_end" msgid="7636885379738905151">"Sağ düğmesi"</string>
- <string name="keyguard_affordance_none" msgid="1751643933430782312">"Yok"</string>
- <string name="keyguard_affordance_enablement_dialog_title" msgid="3389730825561696493">"\"<xliff:g id="APPNAME">%1$s</xliff:g>\" uygulamasını seçmek için şunları kontrol edin"</string>
- <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8117011931337357438">"<xliff:g id="APPNAME">%1$s</xliff:g> uygulamasını aç"</string>
- <string name="keyguard_affordance_enablement_dialog_message" msgid="6136286758939253570">"<xliff:g id="APPNAME">%1$s</xliff:g> uygulamasını kısayol olarak ekleyebilmeniz için gerekenler"</string>
- <string name="keyguard_affordance_enablement_dialog_dismiss_button" msgid="629754625264422508">"Bitti"</string>
- <string name="keyguard_quick_affordance_title" msgid="4242813186995735584">"Kısayollar"</string>
- <string name="keyguard_quick_affordance_section_title" msgid="2806304242671717309">"Kısayollar"</string>
- <string name="keyguard_quick_affordance_two_selected_template" msgid="1757099194522296363">"<xliff:g id="FIRST">%1$s</xliff:g>, <xliff:g id="SECOND">%2$s</xliff:g>"</string>
- <string name="keyguard_quick_affordance_none_selected" msgid="8494127020144112003">"Yok"</string>
</resources>
diff --git a/res/values-uk/strings.xml b/res/values-uk/strings.xml
index 6409fbf..4fd5c71 100644
--- a/res/values-uk/strings.xml
+++ b/res/values-uk/strings.xml
@@ -19,9 +19,7 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_name" msgid="1647136562008520313">"Оформлення та стиль"</string>
<string name="theme_title" msgid="2144932106319405101">"Стиль"</string>
- <string name="clock_title" msgid="1974314575211361352">"Свій циферблат"</string>
- <string name="clock_description" msgid="3563839327378948">"Виберіть свій циферблат"</string>
- <string name="clock_picker_entry_content_description" msgid="8377139273468595734">"Змініть свій циферблат"</string>
+ <string name="clock_title" msgid="2126046720254613991">"Годинник"</string>
<string name="grid_title" msgid="1688173478777254123">"Сітка додатків"</string>
<string name="apply_theme_btn" msgid="6293081192321303991">"Застосувати"</string>
<string name="edit_custom_theme_lbl" msgid="5211377705710775224">"Торкніться, щоб змінити"</string>
@@ -86,20 +84,9 @@
<string name="themed_icon_title" msgid="7312460430471956558">"Тема значків"</string>
<string name="beta_title" msgid="8703819523760746458">"Бета"</string>
<string name="gird_picker_entry_content_description" msgid="9087651470212293439">"Змінити сітку додатків"</string>
- <string name="wallpaper_color_tab" msgid="1447926591721403840">"Кольори малюнка"</string>
+ <string name="wallpaper_color_tab" msgid="1447926591721403840">"Кольори фон. малюнка"</string>
<string name="wallpaper_color_title" msgid="5687965239180986458">"Колір фонового малюнка"</string>
<string name="preset_color_tab" msgid="3133391839341329314">"Основні кольори"</string>
<string name="color_changed" msgid="7029571720331641235">"Колір змінено"</string>
<string name="adaptive_color_title" msgid="1336508599235896205">"Динамічний"</string>
- <string name="keyguard_slot_name_bottom_start" msgid="6717374042663171860">"Ліва кнопка"</string>
- <string name="keyguard_slot_name_bottom_end" msgid="7636885379738905151">"Права кнопка"</string>
- <string name="keyguard_affordance_none" msgid="1751643933430782312">"Немає"</string>
- <string name="keyguard_affordance_enablement_dialog_title" msgid="3389730825561696493">"Щоб вибрати додаток <xliff:g id="APPNAME">%1$s</xliff:g>, виконайте наведені нижче дії"</string>
- <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8117011931337357438">"Відкрити <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
- <string name="keyguard_affordance_enablement_dialog_message" msgid="6136286758939253570">"Щоб додати можливість швидкого ввімкнення додатка <xliff:g id="APPNAME">%1$s</xliff:g>, переконайтеся, що виконано вимоги нижче."</string>
- <string name="keyguard_affordance_enablement_dialog_dismiss_button" msgid="629754625264422508">"Готово"</string>
- <string name="keyguard_quick_affordance_title" msgid="4242813186995735584">"Ярлики"</string>
- <string name="keyguard_quick_affordance_section_title" msgid="2806304242671717309">"Ярлики"</string>
- <string name="keyguard_quick_affordance_two_selected_template" msgid="1757099194522296363">"<xliff:g id="FIRST">%1$s</xliff:g>, <xliff:g id="SECOND">%2$s</xliff:g>"</string>
- <string name="keyguard_quick_affordance_none_selected" msgid="8494127020144112003">"Немає"</string>
</resources>
diff --git a/res/values-ur/strings.xml b/res/values-ur/strings.xml
index a5a05b6..8ae85d3 100644
--- a/res/values-ur/strings.xml
+++ b/res/values-ur/strings.xml
@@ -19,9 +19,7 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_name" msgid="1647136562008520313">"وال پیپر اور طرز"</string>
<string name="theme_title" msgid="2144932106319405101">"طرز"</string>
- <string name="clock_title" msgid="1974314575211361352">"حسب ضرورت گھڑی"</string>
- <string name="clock_description" msgid="3563839327378948">"حسب ضرورت گھڑی چنیں"</string>
- <string name="clock_picker_entry_content_description" msgid="8377139273468595734">"حسب ضرورت گھڑی کو تبدیل کریں"</string>
+ <string name="clock_title" msgid="2126046720254613991">"گھڑی"</string>
<string name="grid_title" msgid="1688173478777254123">"ایپ گرڈ"</string>
<string name="apply_theme_btn" msgid="6293081192321303991">"لاگو کریں"</string>
<string name="edit_custom_theme_lbl" msgid="5211377705710775224">"ترمیم کرنے کے لیے تھپتھپائيں"</string>
@@ -91,15 +89,4 @@
<string name="preset_color_tab" msgid="3133391839341329314">"بنیادی رنگ"</string>
<string name="color_changed" msgid="7029571720331641235">"رنگ کو تبدیل کر دیا گیا"</string>
<string name="adaptive_color_title" msgid="1336508599235896205">"ڈائنیمک"</string>
- <string name="keyguard_slot_name_bottom_start" msgid="6717374042663171860">"دایاں بٹن"</string>
- <string name="keyguard_slot_name_bottom_end" msgid="7636885379738905151">"بایاں بٹن"</string>
- <string name="keyguard_affordance_none" msgid="1751643933430782312">"کوئی نہیں"</string>
- <string name="keyguard_affordance_enablement_dialog_title" msgid="3389730825561696493">"`<xliff:g id="APPNAME">%1$s</xliff:g>` کو منتخب کرنے کے لیے درج ذیل کو چیک کریں"</string>
- <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8117011931337357438">"<xliff:g id="APPNAME">%1$s</xliff:g> کھولیں"</string>
- <string name="keyguard_affordance_enablement_dialog_message" msgid="6136286758939253570">"<xliff:g id="APPNAME">%1$s</xliff:g> ایپ کو شارٹ کٹ کے طور پر شامل کرنے کے لیے درج ذیل کو یقینی بنائیں"</string>
- <string name="keyguard_affordance_enablement_dialog_dismiss_button" msgid="629754625264422508">"ہو گیا"</string>
- <string name="keyguard_quick_affordance_title" msgid="4242813186995735584">"شارٹ کٹس"</string>
- <string name="keyguard_quick_affordance_section_title" msgid="2806304242671717309">"شارٹ کٹس"</string>
- <string name="keyguard_quick_affordance_two_selected_template" msgid="1757099194522296363">"<xliff:g id="FIRST">%1$s</xliff:g>، <xliff:g id="SECOND">%2$s</xliff:g>"</string>
- <string name="keyguard_quick_affordance_none_selected" msgid="8494127020144112003">"کوئی نہیں"</string>
</resources>
diff --git a/res/values-uz/strings.xml b/res/values-uz/strings.xml
index 78f5c63..44563b5 100644
--- a/res/values-uz/strings.xml
+++ b/res/values-uz/strings.xml
@@ -19,9 +19,7 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_name" msgid="1647136562008520313">"Fon rasmi va uslubi"</string>
<string name="theme_title" msgid="2144932106319405101">"Uslub"</string>
- <string name="clock_title" msgid="1974314575211361352">"Maxsus soat"</string>
- <string name="clock_description" msgid="3563839327378948">"Maxsus soat tanlash"</string>
- <string name="clock_picker_entry_content_description" msgid="8377139273468595734">"Maxsus soatni almashtirish"</string>
+ <string name="clock_title" msgid="2126046720254613991">"Soat"</string>
<string name="grid_title" msgid="1688173478777254123">"Ilovalar jadvali"</string>
<string name="apply_theme_btn" msgid="6293081192321303991">"Tatbiq etish"</string>
<string name="edit_custom_theme_lbl" msgid="5211377705710775224">"Tahrirlash uchun tegining"</string>
@@ -91,15 +89,4 @@
<string name="preset_color_tab" msgid="3133391839341329314">"Asosiy ranglar"</string>
<string name="color_changed" msgid="7029571720331641235">"Rang oʻzgartirildi"</string>
<string name="adaptive_color_title" msgid="1336508599235896205">"Dinamik"</string>
- <string name="keyguard_slot_name_bottom_start" msgid="6717374042663171860">"Chap tugma"</string>
- <string name="keyguard_slot_name_bottom_end" msgid="7636885379738905151">"Oʻng tugma"</string>
- <string name="keyguard_affordance_none" msgid="1751643933430782312">"Hech biri"</string>
- <string name="keyguard_affordance_enablement_dialog_title" msgid="3389730825561696493">"“<xliff:g id="APPNAME">%1$s</xliff:g>” ilovasini tanlash uchun quyidagilarni bajaring:"</string>
- <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8117011931337357438">"Ochish: <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
- <string name="keyguard_affordance_enablement_dialog_message" msgid="6136286758939253570">"<xliff:g id="APPNAME">%1$s</xliff:g> ilovasini yorliq sifatida qoʻshish uchun"</string>
- <string name="keyguard_affordance_enablement_dialog_dismiss_button" msgid="629754625264422508">"Tayyor"</string>
- <string name="keyguard_quick_affordance_title" msgid="4242813186995735584">"Tezkor tugmalar"</string>
- <string name="keyguard_quick_affordance_section_title" msgid="2806304242671717309">"Tezkor tugmalar"</string>
- <string name="keyguard_quick_affordance_two_selected_template" msgid="1757099194522296363">"<xliff:g id="FIRST">%1$s</xliff:g>, <xliff:g id="SECOND">%2$s</xliff:g>"</string>
- <string name="keyguard_quick_affordance_none_selected" msgid="8494127020144112003">"Hech qanday"</string>
</resources>
diff --git a/res/values-vi/strings.xml b/res/values-vi/strings.xml
index 6ed629a..c078772 100644
--- a/res/values-vi/strings.xml
+++ b/res/values-vi/strings.xml
@@ -19,9 +19,7 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_name" msgid="1647136562008520313">"Hình nền và phong cách"</string>
<string name="theme_title" msgid="2144932106319405101">"Kiểu"</string>
- <string name="clock_title" msgid="1974314575211361352">"Đồng hồ tuỳ chỉnh"</string>
- <string name="clock_description" msgid="3563839327378948">"Chọn đồng hồ tuỳ chỉnh"</string>
- <string name="clock_picker_entry_content_description" msgid="8377139273468595734">"Thay đổi đồng hồ tuỳ chỉnh"</string>
+ <string name="clock_title" msgid="2126046720254613991">"Đồng hồ"</string>
<string name="grid_title" msgid="1688173478777254123">"Lưới ứng dụng"</string>
<string name="apply_theme_btn" msgid="6293081192321303991">"Áp dụng"</string>
<string name="edit_custom_theme_lbl" msgid="5211377705710775224">"Nhấn để chỉnh sửa"</string>
@@ -91,15 +89,4 @@
<string name="preset_color_tab" msgid="3133391839341329314">"Màu cơ bản"</string>
<string name="color_changed" msgid="7029571720331641235">"Đã thay đổi màu"</string>
<string name="adaptive_color_title" msgid="1336508599235896205">"Động"</string>
- <string name="keyguard_slot_name_bottom_start" msgid="6717374042663171860">"Nút bên trái"</string>
- <string name="keyguard_slot_name_bottom_end" msgid="7636885379738905151">"Nút bên phải"</string>
- <string name="keyguard_affordance_none" msgid="1751643933430782312">"Không có"</string>
- <string name="keyguard_affordance_enablement_dialog_title" msgid="3389730825561696493">"Để chọn \"<xliff:g id="APPNAME">%1$s</xliff:g>\", hãy làm theo hướng dẫn sau đây"</string>
- <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8117011931337357438">"Mở <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
- <string name="keyguard_affordance_enablement_dialog_message" msgid="6136286758939253570">"Để tạo lối tắt cho ứng dụng <xliff:g id="APPNAME">%1$s</xliff:g>, hãy đảm bảo"</string>
- <string name="keyguard_affordance_enablement_dialog_dismiss_button" msgid="629754625264422508">"Xong"</string>
- <string name="keyguard_quick_affordance_title" msgid="4242813186995735584">"Lối tắt"</string>
- <string name="keyguard_quick_affordance_section_title" msgid="2806304242671717309">"Lối tắt"</string>
- <string name="keyguard_quick_affordance_two_selected_template" msgid="1757099194522296363">"<xliff:g id="FIRST">%1$s</xliff:g>, <xliff:g id="SECOND">%2$s</xliff:g>"</string>
- <string name="keyguard_quick_affordance_none_selected" msgid="8494127020144112003">"Không có"</string>
</resources>
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-zh-rCN/strings.xml b/res/values-zh-rCN/strings.xml
index 58b8a2a..1a20566 100644
--- a/res/values-zh-rCN/strings.xml
+++ b/res/values-zh-rCN/strings.xml
@@ -19,9 +19,7 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_name" msgid="1647136562008520313">"壁纸和样式"</string>
<string name="theme_title" msgid="2144932106319405101">"样式"</string>
- <string name="clock_title" msgid="1974314575211361352">"自定义钟面"</string>
- <string name="clock_description" msgid="3563839327378948">"选择自定义钟面"</string>
- <string name="clock_picker_entry_content_description" msgid="8377139273468595734">"更改自定义钟面"</string>
+ <string name="clock_title" msgid="2126046720254613991">"时钟"</string>
<string name="grid_title" msgid="1688173478777254123">"应用网格"</string>
<string name="apply_theme_btn" msgid="6293081192321303991">"应用"</string>
<string name="edit_custom_theme_lbl" msgid="5211377705710775224">"点按即可修改"</string>
@@ -91,15 +89,4 @@
<string name="preset_color_tab" msgid="3133391839341329314">"基本颜色"</string>
<string name="color_changed" msgid="7029571720331641235">"颜色已更改"</string>
<string name="adaptive_color_title" msgid="1336508599235896205">"动态"</string>
- <string name="keyguard_slot_name_bottom_start" msgid="6717374042663171860">"左侧按钮"</string>
- <string name="keyguard_slot_name_bottom_end" msgid="7636885379738905151">"右侧按钮"</string>
- <string name="keyguard_affordance_none" msgid="1751643933430782312">"无"</string>
- <string name="keyguard_affordance_enablement_dialog_title" msgid="3389730825561696493">"若要选择“<xliff:g id="APPNAME">%1$s</xliff:g>”,请确认满足已以下条件:"</string>
- <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8117011931337357438">"打开<xliff:g id="APPNAME">%1$s</xliff:g>"</string>
- <string name="keyguard_affordance_enablement_dialog_message" msgid="6136286758939253570">"若要将<xliff:g id="APPNAME">%1$s</xliff:g>应用添加为快捷方式,请确保:"</string>
- <string name="keyguard_affordance_enablement_dialog_dismiss_button" msgid="629754625264422508">"完成"</string>
- <string name="keyguard_quick_affordance_title" msgid="4242813186995735584">"快捷方式"</string>
- <string name="keyguard_quick_affordance_section_title" msgid="2806304242671717309">"快捷方式"</string>
- <string name="keyguard_quick_affordance_two_selected_template" msgid="1757099194522296363">"<xliff:g id="FIRST">%1$s</xliff:g>、<xliff:g id="SECOND">%2$s</xliff:g>"</string>
- <string name="keyguard_quick_affordance_none_selected" msgid="8494127020144112003">"无"</string>
</resources>
diff --git a/res/values-zh-rHK/strings.xml b/res/values-zh-rHK/strings.xml
index 017a0be..df0972c 100644
--- a/res/values-zh-rHK/strings.xml
+++ b/res/values-zh-rHK/strings.xml
@@ -19,9 +19,7 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_name" msgid="1647136562008520313">"桌布和樣式"</string>
<string name="theme_title" msgid="2144932106319405101">"樣式"</string>
- <string name="clock_title" msgid="1974314575211361352">"自訂時鐘"</string>
- <string name="clock_description" msgid="3563839327378948">"揀選自訂時鐘"</string>
- <string name="clock_picker_entry_content_description" msgid="8377139273468595734">"變更自訂時鐘"</string>
+ <string name="clock_title" msgid="2126046720254613991">"時鐘"</string>
<string name="grid_title" msgid="1688173478777254123">"應用程式網格"</string>
<string name="apply_theme_btn" msgid="6293081192321303991">"套用"</string>
<string name="edit_custom_theme_lbl" msgid="5211377705710775224">"輕按即可編輯"</string>
@@ -91,15 +89,4 @@
<string name="preset_color_tab" msgid="3133391839341329314">"基本顏色"</string>
<string name="color_changed" msgid="7029571720331641235">"已經變咗顏色"</string>
<string name="adaptive_color_title" msgid="1336508599235896205">"動態"</string>
- <string name="keyguard_slot_name_bottom_start" msgid="6717374042663171860">"左鍵"</string>
- <string name="keyguard_slot_name_bottom_end" msgid="7636885379738905151">"右鍵"</string>
- <string name="keyguard_affordance_none" msgid="1751643933430782312">"無"</string>
- <string name="keyguard_affordance_enablement_dialog_title" msgid="3389730825561696493">"請勾選以下選項以選取「<xliff:g id="APPNAME">%1$s</xliff:g>」"</string>
- <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8117011931337357438">"開啟「<xliff:g id="APPNAME">%1$s</xliff:g>」"</string>
- <string name="keyguard_affordance_enablement_dialog_message" msgid="6136286758939253570">"如要新增「<xliff:g id="APPNAME">%1$s</xliff:g>」應用程式為快速鍵,請確保:"</string>
- <string name="keyguard_affordance_enablement_dialog_dismiss_button" msgid="629754625264422508">"完成"</string>
- <string name="keyguard_quick_affordance_title" msgid="4242813186995735584">"捷徑"</string>
- <string name="keyguard_quick_affordance_section_title" msgid="2806304242671717309">"捷徑"</string>
- <string name="keyguard_quick_affordance_two_selected_template" msgid="1757099194522296363">"<xliff:g id="FIRST">%1$s</xliff:g>,<xliff:g id="SECOND">%2$s</xliff:g>"</string>
- <string name="keyguard_quick_affordance_none_selected" msgid="8494127020144112003">"無"</string>
</resources>
diff --git a/res/values-zh-rTW/strings.xml b/res/values-zh-rTW/strings.xml
index 09f59bb..478d759 100644
--- a/res/values-zh-rTW/strings.xml
+++ b/res/values-zh-rTW/strings.xml
@@ -19,9 +19,7 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_name" msgid="1647136562008520313">"桌布和樣式"</string>
<string name="theme_title" msgid="2144932106319405101">"樣式"</string>
- <string name="clock_title" msgid="1974314575211361352">"自訂時鐘"</string>
- <string name="clock_description" msgid="3563839327378948">"選擇自訂時鐘"</string>
- <string name="clock_picker_entry_content_description" msgid="8377139273468595734">"變更自訂時鐘"</string>
+ <string name="clock_title" msgid="2126046720254613991">"時鐘"</string>
<string name="grid_title" msgid="1688173478777254123">"應用程式格線"</string>
<string name="apply_theme_btn" msgid="6293081192321303991">"套用"</string>
<string name="edit_custom_theme_lbl" msgid="5211377705710775224">"輕觸這裡即可編輯"</string>
@@ -91,15 +89,4 @@
<string name="preset_color_tab" msgid="3133391839341329314">"基本顏色"</string>
<string name="color_changed" msgid="7029571720331641235">"顏色已變更"</string>
<string name="adaptive_color_title" msgid="1336508599235896205">"動態"</string>
- <string name="keyguard_slot_name_bottom_start" msgid="6717374042663171860">"左側按鈕"</string>
- <string name="keyguard_slot_name_bottom_end" msgid="7636885379738905151">"右側按鈕"</string>
- <string name="keyguard_affordance_none" msgid="1751643933430782312">"無"</string>
- <string name="keyguard_affordance_enablement_dialog_title" msgid="3389730825561696493">"必須完成以下事項才能選取「<xliff:g id="APPNAME">%1$s</xliff:g>」"</string>
- <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8117011931337357438">"開啟「<xliff:g id="APPNAME">%1$s</xliff:g>」"</string>
- <string name="keyguard_affordance_enablement_dialog_message" msgid="6136286758939253570">"如要將「<xliff:g id="APPNAME">%1$s</xliff:g>」應用程式新增為捷徑,必須滿足以下條件"</string>
- <string name="keyguard_affordance_enablement_dialog_dismiss_button" msgid="629754625264422508">"完成"</string>
- <string name="keyguard_quick_affordance_title" msgid="4242813186995735584">"捷徑"</string>
- <string name="keyguard_quick_affordance_section_title" msgid="2806304242671717309">"捷徑"</string>
- <string name="keyguard_quick_affordance_two_selected_template" msgid="1757099194522296363">"<xliff:g id="FIRST">%1$s</xliff:g>、<xliff:g id="SECOND">%2$s</xliff:g>"</string>
- <string name="keyguard_quick_affordance_none_selected" msgid="8494127020144112003">"無"</string>
</resources>
diff --git a/res/values-zu/strings.xml b/res/values-zu/strings.xml
index e4993c7..e399001 100644
--- a/res/values-zu/strings.xml
+++ b/res/values-zu/strings.xml
@@ -19,9 +19,7 @@
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_name" msgid="1647136562008520313">"Isithombe sangemuva nesitayela"</string>
<string name="theme_title" msgid="2144932106319405101">"Isitayela"</string>
- <string name="clock_title" msgid="1974314575211361352">"Iwashi Elingokomuntu Ngamunye"</string>
- <string name="clock_description" msgid="3563839327378948">"Khetha iwashi elingokomuntu ngamunye"</string>
- <string name="clock_picker_entry_content_description" msgid="8377139273468595734">"Shintsha iwashi elingokomuntu ngamunye"</string>
+ <string name="clock_title" msgid="2126046720254613991">"Iwashi"</string>
<string name="grid_title" msgid="1688173478777254123">"Igridi ye-app"</string>
<string name="apply_theme_btn" msgid="6293081192321303991">"Faka"</string>
<string name="edit_custom_theme_lbl" msgid="5211377705710775224">"Thepha ukuze uhlele"</string>
@@ -91,15 +89,4 @@
<string name="preset_color_tab" msgid="3133391839341329314">"Imibala eyisisekelo"</string>
<string name="color_changed" msgid="7029571720331641235">"Umbala ushintshiwe"</string>
<string name="adaptive_color_title" msgid="1336508599235896205">"Okuguqukayo"</string>
- <string name="keyguard_slot_name_bottom_start" msgid="6717374042663171860">"Inkinobho engakwesobunxele"</string>
- <string name="keyguard_slot_name_bottom_end" msgid="7636885379738905151">"Inkinobho yakwesokudla"</string>
- <string name="keyguard_affordance_none" msgid="1751643933430782312">"Lutho"</string>
- <string name="keyguard_affordance_enablement_dialog_title" msgid="3389730825561696493">"Ukukhetha i-`<xliff:g id="APPNAME">%1$s</xliff:g>` maka okulandelayo"</string>
- <string name="keyguard_affordance_enablement_dialog_action_template" msgid="8117011931337357438">"Vula i-<xliff:g id="APPNAME">%1$s</xliff:g>"</string>
- <string name="keyguard_affordance_enablement_dialog_message" msgid="6136286758939253570">"Ukwengeza i-app ye-<xliff:g id="APPNAME">%1$s</xliff:g> njengesinqamuleli, qinisekisa"</string>
- <string name="keyguard_affordance_enablement_dialog_dismiss_button" msgid="629754625264422508">"Kwenziwe"</string>
- <string name="keyguard_quick_affordance_title" msgid="4242813186995735584">"Izinqamuleli"</string>
- <string name="keyguard_quick_affordance_section_title" msgid="2806304242671717309">"Izinqamuleli"</string>
- <string name="keyguard_quick_affordance_two_selected_template" msgid="1757099194522296363">"<xliff:g id="FIRST">%1$s</xliff:g>, <xliff:g id="SECOND">%2$s</xliff:g>"</string>
- <string name="keyguard_quick_affordance_none_selected" msgid="8494127020144112003">"Lutho"</string>
</resources>
diff --git a/res/values/attrs.xml b/res/values/attrs.xml
index 288dd19..377d4eb 100644
--- a/res/values/attrs.xml
+++ b/res/values/attrs.xml
@@ -18,4 +18,9 @@
<resources>
<item name="linear_layout_horizontal_display_options_max" format="float" type="dimen">4.35
</item>
+
+ <declare-styleable name="SaturationAlphaTintDrawableWrapper">
+ <attr name="android:tint" />
+ <attr name="android:alpha" />
+ </declare-styleable>
</resources>
\ No newline at end of file
diff --git a/res/values/clock_colors.xml b/res/values/clock_colors.xml
new file mode 100644
index 0000000..1539a92
--- /dev/null
+++ b/res/values/clock_colors.xml
@@ -0,0 +1,73 @@
+<?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.
+-->
+<resources>
+ <string-array name="clock_color_ids">
+ <item>RED</item>
+ <item>ORANGE</item>
+ <item>YELLOW</item>
+ <item>GREEN</item>
+ <item>BLUE</item>
+ <item>INDIGO</item>
+ <item>VIOLET</item>
+ <item>GRAY</item>
+ <item>TEAL</item>
+ </string-array>
+ <array name="clock_color_names">
+ <item>@string/clock_color_red</item>
+ <item>@string/clock_color_orange</item>
+ <item>@string/clock_color_yellow</item>
+ <item>@string/clock_color_green</item>
+ <item>@string/clock_color_blue</item>
+ <item>@string/clock_color_indigo</item>
+ <item>@string/clock_color_violet</item>
+ <item>@string/clock_color_gray</item>
+ <item>@string/clock_color_teal</item>
+ </array>
+ <array name="clock_colors">
+ <item>#FFA3A7</item>
+ <item>#F7AC69</item>
+ <item>#FFC951</item>
+ <item>#88D86A</item>
+ <item>#8EC8FF</item>
+ <item>#B9AAFF</item>
+ <item>#F6A2FF</item>
+ <item>#B9B9B9</item>
+ <item>#40D9CF</item>
+ </array>
+ <array name="clock_color_tone_min">
+ <item>20</item>
+ <item>20</item>
+ <item>50</item>
+ <item>20</item>
+ <item>20</item>
+ <item>10</item>
+ <item>20</item>
+ <item>0</item>
+ <item>20</item>
+ </array>
+ <array name="clock_color_tone_max">
+ <item>95</item>
+ <item>95</item>
+ <item>95</item>
+ <item>99</item>
+ <item>95</item>
+ <item>95</item>
+ <item>97</item>
+ <item>100</item>
+ <item>99</item>
+ </array>
+</resources>
\ No newline at end of file
diff --git a/res/values/dimens.xml b/res/values/dimens.xml
index 64d9941..0d5a9a8 100644
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -130,21 +130,38 @@
<dimen name="beta_tag_background_width">46dp</dimen>
<dimen name="beta_tag_background_height">24dp</dimen>
- <!-- For the color option section -->
+ <!-- For the color picker section -->
+ <!-- Dimension for the original color picker section -->
<dimen name="color_options_container_top_margin">24dp</dimen>
-
- <!-- For the color page. -->
<dimen name="color_page_indicator_margin_top">16dp</dimen>
-
+ <!-- Dimension for the original color chip resource -->
<dimen name="component_color_chip_small_radius_default">29dp</dimen>
<dimen name="component_color_chip_small_diameter_default">58dp</dimen>
<dimen name="color_seed_chip_margin">14dp</dimen>
+ <!-- Dimension for the revamped UI color chip -->
+ <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 picker page. -->
+ <!-- Dimension for the revamped UI color chip -->
+ <dimen name="component_color_chip_small_radius_default2">24dp</dimen>
+ <dimen name="component_color_chip_small_diameter_default2">48dp</dimen>
+ <dimen name="color_seed_chip_margin2">11dp</dimen>
<!-- Keyguard quick affordances -->
<!-- Size for the container for the icon of a quick affordance for the lock screen in the picker experience. -->
<dimen name="keyguard_quick_affordance_icon_container_size">74dp</dimen>
<!-- Size for the icon of a quick affordance for the lock screen in the picker experience. -->
<dimen name="keyguard_quick_affordance_icon_size">24dp</dimen>
- <!-- Width of a single selectable item in the lock screen quick affordance picker. -->
- <dimen name="keyguard_quick_affordance_picker_item_width">74dp</dimen>
+
+ <dimen name="clock_carousel_item_width">190dp</dimen>
+ <dimen name="clock_carousel_item_height">380dp</dimen>
+ <dimen name="clock_carousel_item_margin">16dp</dimen>
+ <dimen name="clock_carousel_guideline_margin">140dp</dimen>
+ <!-- Scale of the carousel items that are not selected and at the side -->
+ <dimen name="clock_carousel_scale" format="float">0.5</dimen>
+ <!-- Alpha of the carousel items that are not selected and at the side -->
+ <dimen name="clock_carousel_alpha" format="float">0.4</dimen>
</resources>
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/res/values/strings.xml b/res/values/strings.xml
index 13fc8a0..01113c4 100755
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -33,6 +33,60 @@
<!-- 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=19] -->
+ <string name="clock_settings_title">Clock Settings</string>
+
+ <!-- Title of a section of the customization picker where the user can configure clock color and size. [CHAR LIMIT=20] -->
+ <string name="clock_color_and_size_title">Clock color & size</string>
+
+ <!-- Description of a section of the customization picker where the user can configure clock color and size, e.g. Violet, small. [CHAR LIMIT=NONE] -->
+ <string name="clock_color_and_size_description"><xliff:g name="color">%1$s</xliff:g>, <xliff:g name="size">%2$s</xliff:g></string>
+
+ <!-- Title of a tab to change the clock color. [CHAR LIMIT=15] -->
+ <string name="clock_color">Color</string>
+
+ <!-- Title of a clock color red option that will appear in the description of the custom clock section. [CHAR LIMIT=15] -->
+ <string name="clock_color_red">Red</string>
+
+ <!-- Title of a clock color orange option that will appear in the description of the custom clock section. [CHAR LIMIT=15] -->
+ <string name="clock_color_orange">Orange</string>
+
+ <!-- Title of a clock color yellow option that will appear in the description of the custom clock section. [CHAR LIMIT=15] -->
+ <string name="clock_color_yellow">Yellow</string>
+
+ <!-- Title of a clock color green option that will appear in the description of the custom clock section. [CHAR LIMIT=15] -->
+ <string name="clock_color_green">Green</string>
+
+ <!-- Title of a clock color blue option that will appear in the description of the custom clock section. [CHAR LIMIT=15] -->
+ <string name="clock_color_blue">Blue</string>
+
+ <!-- Title of a clock color indigo option that will appear in the description of the custom clock section. [CHAR LIMIT=15] -->
+ <string name="clock_color_indigo">Indigo</string>
+
+ <!-- Title of a clock color violet option that will appear in the description of the custom clock section. [CHAR LIMIT=15] -->
+ <string name="clock_color_violet">Violet</string>
+
+ <!-- Title of a clock color grey option that will appear in the description of the custom clock section. [CHAR LIMIT=15] -->
+ <string name="clock_color_gray">Grey</string>
+
+ <!-- Title of a clock color teal option that will appear in the description of the custom clock section. [CHAR LIMIT=15] -->
+ <string name="clock_color_teal">Teal</string>
+
+ <!-- Title of a tab to change the clock size. [CHAR LIMIT=15] -->
+ <string name="clock_size">Size</string>
+
+ <!-- Title of a radio button to apply clock size dynamic. [CHAR LIMIT=15] -->
+ <string name="clock_size_dynamic">Dynamic</string>
+
+ <!-- Description of a radio button to apply clock size dynamic. [CHAR LIMIT=NONE] -->
+ <string name="clock_size_dynamic_description">Clock size changes according to lock screen content</string>
+
+ <!-- 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>
@@ -257,30 +311,42 @@
<!-- The title for the tab with colors from wallpaper. [CHAR_LIMIT=20]-->
<string name="wallpaper_color_tab">Wallpaper colors</string>
+ <!-- The subheader for the tab with colors from wallpaper. [CHAR_LIMIT=55]-->
+ <string name="wallpaper_color_subheader">Icons, text, and more match colors in your wallpaper</string>
<!-- The description on an item that shows a color obtained from the wallpaper
(used mainly for accessibility). [CHAR_LIMIT=NONE] -->
<string name="wallpaper_color_title">Wallpaper color</string>
<!-- The title for the tab with a default set of color options. [CHAR_LIMIT=20]-->
<string name="preset_color_tab">Basic colors</string>
+ <!-- The revised title for the tab with a default set of color options. [CHAR_LIMIT=20]-->
+ <string name="preset_color_tab_2">Other colors</string>
+ <!-- The subheader for the tab with a default set of color options. [CHAR_LIMIT=55]-->
+ <string name="preset_color_subheader">Choose any color for your icons, clock, and more</string>
<!-- The text for A11y announcement when color changes. -->
<string name="color_changed">Color changed</string>
<!-- Title of a section of color selection option that obtains colors automatically from the
wallpaper instead of a set color [CHAR LIMIT=15] -->
<string name="adaptive_color_title">Dynamic</string>
+ <!--
+ Title for a screen where the user can configure the system colors by selecting from a list of
+ color options.
+ [CHAR LIMIT=32].
+ -->
+ <string name="color_picker_title">System colors</string>
<!--
- Name of the slot on the "start" side of the bottom of the lock screen, where quick affordance
- buttons can be added to the lock screen. In left-to-right languages, this is the left-hand side
- button. In right-to-left languages, this is the right-hand side button. [CHAR LIMIT=16].
+ Name of the slot on the "start" side of the bottom of the lock screen, where lock screen
+ shortcuts can be added to the lock screen. In left-to-right languages, this is the left-hand
+ side button. In right-to-left languages, this is the right-hand side button. [CHAR LIMIT=16].
-->
- <string name="keyguard_slot_name_bottom_start">Left button</string>
+ <string name="keyguard_slot_name_bottom_start">Left shortcut</string>
<!--
- Name of the slot on the "end" side of the bottom of the lock screen, where quick affordance
- buttons can be added to the lock screen. In left-to-right languages, this is the right-hand side
- button. In right-to-left languages, this is the left-hand side button. [CHAR LIMIT=16].
+ Name of the slot on the "end" side of the bottom of the lock screen, where lock screen shortcuts
+ can be added to the lock screen. In left-to-right languages, this is the right-hand side button.
+ In right-to-left languages, this is the left-hand side button. [CHAR LIMIT=16].
-->
- <string name="keyguard_slot_name_bottom_end">Right button</string>
+ <string name="keyguard_slot_name_bottom_end">Right shortcut</string>
<!--
Name for an option to have no quick affordance selected for one of the sides of the lock
@@ -344,4 +410,74 @@
[CHAR LIMIT=60].
-->
<string name="keyguard_quick_affordance_none_selected">None</string>
+
+ <!--
+ Title for a section in a list of sections in the settings app that allows the user to modify
+ how notifications behave whilst the device is locked.
+
+ [CHAR LIMIT=32].
+ -->
+ <string name="notifications_section_title">Notifications</string>
+
+ <!--
+ Summary for a setting that lets the user toggle between showing or hiding notifications on their
+ device's lock screen. This one is shown when the user is allowing notifications to show on their
+ device's lock screen.
+
+ [CHAR LIMIT=64].
+ -->
+ <string name="show_notifications_on_lock_screen">Show notifications on the lock screen</string>
+
+ <!--
+ Summary for a setting that lets the user toggle between showing or hiding notifications on their
+ device's lock screen. This one is shown when the user is not allowing notifications to show on
+ their device's lock screen.
+
+ [CHAR LIMIT=64].
+ -->
+ <string name="hide_notifications_on_lock_screen">Hide notifications on the lock screen</string>
+
+ <!--
+ Title for a section in a list of sections in the settings app that allows the user to access
+ additional settings related to lock screen behaviour.
+
+ [CHAR LIMIT=32].
+ -->
+ <string name="more_settings_section_title">More options</string>
+
+ <!--
+ Summary for a setting that lets the user access additional settings related to lock screen
+ behaviour. Please note that "Now Playing" is an entity; it's a name of an existing feature
+ that allows users to see the song that the device is picking up through its microphone on
+ the lock screen; therefore, it should not be translated literally.
+
+ [CHAR LIMIT=64].
+ -->
+ <string name="more_settings_section_description">Text on lock screen, Now Playing, and more</string>
+
+ <!--
+ Label for button that lets the user navigate to a full-screen experience of selecting
+ system colors.
+
+ [CHAR LIMIT=128].
+ -->
+ <string name="more_colors">More Colors</string>
+
+ <!--
+ Accessibility string for a button that allows the user to select the default color for their
+ lock screen clock on the device. This is shown next to other buttons that allow the user to
+ select from a set of custom colors.
+
+ [CHAR LIMIT=NONE].
+ -->
+ <string name="content_description_default_color_option">Default color option</string>
+
+ <!--
+ Accessibility string for a button that allows the user to select a custom color for their lock
+ screen clock on the device. This is shown next to other such buttons that allow the user to
+ select from a set of custom colors.
+
+ [CHAR LIMIT=NONE].
+ -->
+ <string name="content_description_color_option">Color option <xliff:g name="color_number" example="1">%1$d</xliff:g></string>
</resources>
diff --git a/res/xml/carousel_scene.xml b/res/xml/carousel_scene.xml
new file mode 100644
index 0000000..44fb556
--- /dev/null
+++ b/res/xml/carousel_scene.xml
@@ -0,0 +1,139 @@
+<?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.
+-->
+<MotionScene
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:motion="http://schemas.android.com/apk/res-auto">
+
+ <Transition
+ motion:constraintSetStart="@id/start"
+ motion:constraintSetEnd="@+id/next"
+ motion:duration="1000"
+ android:id="@+id/forward">
+ <OnSwipe
+ motion:dragDirection="dragLeft"
+ motion:touchAnchorSide="left" />
+ </Transition>
+
+ <Transition
+ motion:constraintSetStart="@+id/start"
+ motion:constraintSetEnd="@+id/previous"
+ android:id="@+id/backward">
+ <OnSwipe
+ motion:dragDirection="dragRight"
+ motion:touchAnchorSide="right" />
+ </Transition>
+
+ <ConstraintSet android:id="@+id/previous">
+ <Constraint
+ android:id="@+id/item_view_0"
+ android:layout_width="@dimen/clock_carousel_item_width"
+ android:layout_height="@dimen/clock_carousel_item_height"
+ android:scaleX="@dimen/clock_carousel_scale"
+ android:scaleY="@dimen/clock_carousel_scale"
+ android:alpha="@dimen/clock_carousel_alpha"
+ motion:layout_constraintEnd_toStartOf="@id/guideline_start"
+ motion:layout_constraintTop_toTopOf="parent"
+ motion:layout_constraintBottom_toBottomOf="parent" />
+ <Constraint
+ android:id="@+id/item_view_1"
+ android:layout_width="@dimen/clock_carousel_item_width"
+ android:layout_height="@dimen/clock_carousel_item_height"
+ motion:layout_constraintWidth_max="@dimen/clock_carousel_item_width"
+ motion:layout_constraintHorizontal_bias="0.5"
+ motion:layout_constraintStart_toStartOf="parent"
+ motion:layout_constraintEnd_toEndOf="parent"
+ motion:layout_constraintTop_toTopOf="parent"
+ motion:layout_constraintBottom_toBottomOf="parent" />
+ <Constraint
+ android:id="@+id/item_view_2"
+ android:layout_width="@dimen/clock_carousel_item_width"
+ android:layout_height="@dimen/clock_carousel_item_height"
+ android:scaleX="@dimen/clock_carousel_scale"
+ android:scaleY="@dimen/clock_carousel_scale"
+ android:alpha="@dimen/clock_carousel_alpha"
+ motion:layout_constraintStart_toStartOf="@id/guideline_end"
+ motion:layout_constraintTop_toTopOf="parent"
+ motion:layout_constraintBottom_toBottomOf="parent" />
+ </ConstraintSet>
+
+ <ConstraintSet android:id="@+id/start">
+ <Constraint
+ android:id="@+id/item_view_1"
+ android:layout_width="@dimen/clock_carousel_item_width"
+ android:layout_height="@dimen/clock_carousel_item_height"
+ android:scaleX="@dimen/clock_carousel_scale"
+ android:scaleY="@dimen/clock_carousel_scale"
+ android:alpha="@dimen/clock_carousel_alpha"
+ motion:layout_constraintEnd_toStartOf="@id/guideline_start"
+ motion:layout_constraintTop_toTopOf="parent"
+ motion:layout_constraintBottom_toBottomOf="parent" />
+ <Constraint
+ android:id="@+id/item_view_2"
+ android:layout_width="@dimen/clock_carousel_item_width"
+ android:layout_height="@dimen/clock_carousel_item_height"
+ motion:layout_constraintWidth_max="@dimen/clock_carousel_item_width"
+ motion:layout_constraintHorizontal_bias="0.5"
+ motion:layout_constraintStart_toStartOf="parent"
+ motion:layout_constraintEnd_toEndOf="parent"
+ motion:layout_constraintTop_toTopOf="parent"
+ motion:layout_constraintBottom_toBottomOf="parent" />
+ <Constraint
+ android:id="@+id/item_view_3"
+ android:layout_width="@dimen/clock_carousel_item_width"
+ android:layout_height="@dimen/clock_carousel_item_height"
+ android:scaleX="@dimen/clock_carousel_scale"
+ android:scaleY="@dimen/clock_carousel_scale"
+ android:alpha="@dimen/clock_carousel_alpha"
+ motion:layout_constraintStart_toStartOf="@id/guideline_end"
+ motion:layout_constraintTop_toTopOf="parent"
+ motion:layout_constraintBottom_toBottomOf="parent" />
+ </ConstraintSet>
+
+ <ConstraintSet android:id="@+id/next">
+ <Constraint
+ android:id="@+id/item_view_2"
+ android:layout_width="@dimen/clock_carousel_item_width"
+ android:layout_height="@dimen/clock_carousel_item_height"
+ android:scaleX="@dimen/clock_carousel_scale"
+ android:scaleY="@dimen/clock_carousel_scale"
+ android:alpha="@dimen/clock_carousel_alpha"
+ motion:layout_constraintEnd_toStartOf="@id/guideline_start"
+ motion:layout_constraintTop_toTopOf="parent"
+ motion:layout_constraintBottom_toBottomOf="parent" />
+ <Constraint
+ android:id="@+id/item_view_3"
+ android:layout_width="@dimen/clock_carousel_item_width"
+ android:layout_height="@dimen/clock_carousel_item_height"
+ motion:layout_constraintWidth_max="@dimen/clock_carousel_item_width"
+ motion:layout_constraintHorizontal_bias="0.5"
+ motion:layout_constraintStart_toStartOf="parent"
+ motion:layout_constraintEnd_toEndOf="parent"
+ motion:layout_constraintTop_toTopOf="parent"
+ motion:layout_constraintBottom_toBottomOf="parent" />
+ <Constraint
+ android:id="@+id/item_view_4"
+ android:layout_width="@dimen/clock_carousel_item_width"
+ android:layout_height="@dimen/clock_carousel_item_height"
+ android:scaleX="@dimen/clock_carousel_scale"
+ android:scaleY="@dimen/clock_carousel_scale"
+ android:alpha="@dimen/clock_carousel_alpha"
+ motion:layout_constraintStart_toStartOf="@id/guideline_end"
+ motion:layout_constraintTop_toTopOf="parent"
+ motion:layout_constraintBottom_toBottomOf="parent" />
+ </ConstraintSet>
+
+</MotionScene>
\ No newline at end of file
diff --git a/src/com/android/customization/model/clock/ClockSectionController.kt b/src/com/android/customization/model/clock/ClockSectionController.kt
deleted file mode 100644
index 1e339bb..0000000
--- a/src/com/android/customization/model/clock/ClockSectionController.kt
+++ /dev/null
@@ -1,50 +0,0 @@
-/*
- * Copyright (C) 2022 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.clock
-
-import android.content.Context
-import android.view.LayoutInflater
-import com.android.customization.picker.clock.ClockCustomDemoFragment
-import com.android.customization.picker.clock.ClockSectionView
-import com.android.systemui.shared.customization.data.content.CustomizationProviderClient
-import com.android.systemui.shared.customization.data.content.CustomizationProviderContract as Contract
-import com.android.wallpaper.R
-import com.android.wallpaper.model.CustomizationSectionController
-import com.android.wallpaper.model.CustomizationSectionController.CustomizationSectionNavigationController
-import kotlinx.coroutines.runBlocking
-
-/** A [CustomizationSectionController] for clock customization. */
-class ClockSectionController(
- private val navigationController: CustomizationSectionNavigationController,
- private val customizationProviderClient: CustomizationProviderClient,
-) : CustomizationSectionController<ClockSectionView?> {
- override fun isAvailable(context: Context?): Boolean {
- return runBlocking { customizationProviderClient.queryFlags() }
- .firstOrNull { it.name == Contract.FlagsTable.FLAG_NAME_CUSTOM_CLOCKS_ENABLED }
- ?.value == true
- }
-
- override fun createView(context: Context): ClockSectionView {
- val view =
- LayoutInflater.from(context)
- .inflate(
- R.layout.clock_section_view,
- null,
- ) as ClockSectionView
- view.setOnClickListener { navigationController.navigateTo(ClockCustomDemoFragment()) }
- return view
- }
-}
diff --git a/src/com/android/customization/model/color/ColorCustomizationManager.java b/src/com/android/customization/model/color/ColorCustomizationManager.java
index 908480f..29f6ba6 100644
--- a/src/com/android/customization/model/color/ColorCustomizationManager.java
+++ b/src/com/android/customization/model/color/ColorCustomizationManager.java
@@ -210,7 +210,7 @@
* or {@link ColorOptionsProvider#COLOR_SOURCE_PRESET}.
*/
@ColorSource
- public String getCurrentColorSource() {
+ public @Nullable String getCurrentColorSource() {
if (mCurrentSource == null) {
parseSettings(getStoredOverlays());
}
@@ -221,7 +221,7 @@
* @return The style of the currently applied color. One of enum values in
* {@link com.android.systemui.monet.Style}.
*/
- public String getCurrentStyle() {
+ public @Nullable String getCurrentStyle() {
if (mCurrentStyle == null) {
parseSettings(getStoredOverlays());
}
diff --git a/src/com/android/customization/model/color/ColorOption.java b/src/com/android/customization/model/color/ColorOption.java
index c8b28c2..216bb9b 100644
--- a/src/com/android/customization/model/color/ColorOption.java
+++ b/src/com/android/customization/model/color/ColorOption.java
@@ -107,9 +107,15 @@
if (other == null) {
return false;
}
- if (mIsDefault) {
- return other.isDefault() || TextUtils.isEmpty(other.getSerializedPackages())
- || EMPTY_JSON.equals(other.getSerializedPackages());
+ if (mStyle != other.getStyle()) {
+ return false;
+ }
+ String thisSerializedPackages = getSerializedPackages();
+ if (mIsDefault || TextUtils.isEmpty(thisSerializedPackages)
+ || EMPTY_JSON.equals(thisSerializedPackages)) {
+ String otherSerializedPackages = other.getSerializedPackages();
+ return other.isDefault() || TextUtils.isEmpty(otherSerializedPackages)
+ || EMPTY_JSON.equals(otherSerializedPackages);
}
// Map#equals ensures keys and values are compared.
return mPackagesByCategory.equals(other.mPackagesByCategory);
@@ -182,7 +188,8 @@
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
}
- protected CharSequence getContentDescription(Context context) {
+ /** */
+ public CharSequence getContentDescription(Context context) {
if (mContentDescription == null) {
CharSequence defaultName = context.getString(R.string.default_theme_title);
if (isDefault()) {
diff --git a/src/com/android/customization/model/color/ColorProvider.kt b/src/com/android/customization/model/color/ColorProvider.kt
index 3d2cc7e..f91ec6b 100644
--- a/src/com/android/customization/model/color/ColorProvider.kt
+++ b/src/com/android/customization/model/color/ColorProvider.kt
@@ -220,12 +220,22 @@
*/
@ColorInt
private fun ColorScheme.getLightColorPreview(): IntArray {
- return intArrayOf(
- setAlphaComponent(this.accent1[2], ALPHA_MASK),
- setAlphaComponent(this.accent1[2], ALPHA_MASK),
- ColorStateList.valueOf(this.accent3[6]).withLStar(85f).colors[0],
- setAlphaComponent(this.accent1[6], ALPHA_MASK)
- )
+ return when (this.style) {
+ Style.EXPRESSIVE ->
+ intArrayOf(
+ setAlphaComponent(this.accent1.s100, ALPHA_MASK),
+ setAlphaComponent(this.accent1.s100, ALPHA_MASK),
+ ColorStateList.valueOf(this.neutral2.s500).withLStar(80f).colors[0],
+ setAlphaComponent(this.accent2.s500, ALPHA_MASK)
+ )
+ else ->
+ intArrayOf(
+ setAlphaComponent(this.accent1.s100, ALPHA_MASK),
+ setAlphaComponent(this.accent1.s100, ALPHA_MASK),
+ ColorStateList.valueOf(this.accent3.s500).withLStar(85f).colors[0],
+ setAlphaComponent(this.accent1.s500, ALPHA_MASK)
+ )
+ }
}
/**
@@ -234,24 +244,19 @@
*/
@ColorInt
private fun ColorScheme.getDarkColorPreview(): IntArray {
- return intArrayOf(
- setAlphaComponent(this.accent1[2], ALPHA_MASK),
- setAlphaComponent(this.accent1[2], ALPHA_MASK),
- ColorStateList.valueOf(this.accent3[6]).withLStar(85f).colors[0],
- setAlphaComponent(this.accent1[6], ALPHA_MASK)
- )
+ return getLightColorPreview()
}
private fun ColorScheme.getPresetColorPreview(seed: Int): IntArray {
return when (this.style) {
- Style.FRUIT_SALAD -> intArrayOf(seed, this.accent1[2])
+ Style.FRUIT_SALAD -> intArrayOf(seed, this.accent1.s100)
Style.TONAL_SPOT -> intArrayOf(this.accentColor, this.accentColor)
Style.MONOCHROMATIC ->
intArrayOf(
setAlphaComponent(0x000000, 255),
setAlphaComponent(0xFFFFFF, 255),
)
- else -> intArrayOf(this.accent1[2], this.accent1[2])
+ else -> intArrayOf(this.accent1.s100, this.accent1.s100)
}
}
@@ -288,7 +293,9 @@
if (
style == Style.MONOCHROMATIC &&
- !InjectorProvider.getInjector().getFlags().isMonochromaticFlagEnabled()
+ !InjectorProvider.getInjector()
+ .getFlags()
+ .isMonochromaticThemeEnabled(mContext)
) {
continue
}
diff --git a/src/com/android/customization/model/color/ColorSectionController.java b/src/com/android/customization/model/color/ColorSectionController.java
index 3b8a927..be051ac 100644
--- a/src/com/android/customization/model/color/ColorSectionController.java
+++ b/src/com/android/customization/model/color/ColorSectionController.java
@@ -41,7 +41,6 @@
import androidx.annotation.Nullable;
import androidx.lifecycle.LifecycleOwner;
import androidx.recyclerview.widget.RecyclerView;
-import androidx.viewpager2.widget.MarginPageTransformer;
import androidx.viewpager2.widget.ViewPager2;
import com.android.customization.model.CustomizationManager;
@@ -54,7 +53,6 @@
import com.android.wallpaper.model.CustomizationSectionController;
import com.android.wallpaper.model.WallpaperColorsViewModel;
import com.android.wallpaper.module.InjectorProvider;
-import com.android.wallpaper.module.LargeScreenMultiPanesChecker;
import com.android.wallpaper.widget.PageIndicator;
import com.android.wallpaper.widget.SeparatedTabLayout;
@@ -104,7 +102,6 @@
new Optional[]{Optional.empty(), Optional.empty()};
private long mLastColorApplyingTime = 0L;
private ColorSectionView mColorSectionView;
- private boolean mIsMultiPane;
private static int getNumPages(int optionsPerPage, int totalOptions) {
return (int) Math.ceil((float) totalOptions / optionsPerPage);
@@ -118,7 +115,6 @@
new OverlayManagerCompat(activity));
mWallpaperColorsViewModel = viewModel;
mLifecycleOwner = lifecycleOwner;
- mIsMultiPane = new LargeScreenMultiPanesChecker().isMultiPanesEnabled(activity);
if (savedInstanceState != null) {
if (savedInstanceState.containsKey(KEY_COLOR_TAB_POSITION)) {
@@ -174,13 +170,13 @@
// TODO(b/202145216): Use just 2 views when tapping either button on top.
mTabLayout.setViewPager(mColorSectionViewPager);
- mWallpaperColorsViewModel.getHomeWallpaperColors().observe(mLifecycleOwner,
+ mWallpaperColorsViewModel.getHomeWallpaperColorsLiveData().observe(mLifecycleOwner,
homeColors -> {
mHomeWallpaperColors = homeColors;
mHomeWallpaperColorsReady = true;
maybeLoadColors();
});
- mWallpaperColorsViewModel.getLockWallpaperColors().observe(mLifecycleOwner,
+ mWallpaperColorsViewModel.getLockWallpaperColorsLiveData().observe(mLifecycleOwner,
lockColors -> {
mLockWallpaperColors = lockColors;
mLockWallpaperColorsReady = true;
@@ -472,16 +468,6 @@
mContainer = itemView.findViewById(R.id.color_page_container);
// Correct scrolling goes under collapsing toolbar while scrolling oclor options.
mContainer.getChildAt(0).setNestedScrollingEnabled(false);
- /**
- * Sets page transformer with margin to separate color pages and
- * sets color pages' padding to not scroll to window boundary if multi-pane case
- */
- if (mIsMultiPane) {
- final int padding = itemView.getContext().getResources().getDimensionPixelSize(
- R.dimen.section_horizontal_padding);
- mContainer.setPageTransformer(new MarginPageTransformer(padding * 2));
- mContainer.setPadding(padding, /* top= */ 0, padding, /* bottom= */ 0);
- }
mPageIndicator = itemView.findViewById(R.id.color_page_indicator);
if (ColorProvider.themeStyleEnabled) {
mPageIndicator.setVisibility(VISIBLE);
@@ -539,15 +525,13 @@
ColorOptionViewHolder(View itemView) {
super(itemView);
mContainer = itemView.findViewById(R.id.color_option_container);
- // Sets layout with margins for non multi-pane case to separate color options.
- if (!mIsMultiPane) {
- final FrameLayout.LayoutParams layoutParams = new FrameLayout.LayoutParams(
- mContainer.getLayoutParams());
- final int margin = itemView.getContext().getResources().getDimensionPixelSize(
- R.dimen.section_horizontal_padding);
- layoutParams.setMargins(margin, /* top= */ 0, margin, /* bottom= */ 0);
- mContainer.setLayoutParams(layoutParams);
- }
+ // Sets layout with margins to separate color options.
+ final FrameLayout.LayoutParams layoutParams = new FrameLayout.LayoutParams(
+ mContainer.getLayoutParams());
+ final int margin = itemView.getContext().getResources().getDimensionPixelSize(
+ R.dimen.section_horizontal_padding);
+ layoutParams.setMargins(margin, /* top= */ 0, margin, /* bottom= */ 0);
+ mContainer.setLayoutParams(layoutParams);
}
}
}
diff --git a/src/com/android/customization/model/color/ColorSeedOption.java b/src/com/android/customization/model/color/ColorSeedOption.java
index 53d3954..ba61ed1 100644
--- a/src/com/android/customization/model/color/ColorSeedOption.java
+++ b/src/com/android/customization/model/color/ColorSeedOption.java
@@ -80,7 +80,7 @@
}
@Override
- protected CharSequence getContentDescription(Context context) {
+ public CharSequence getContentDescription(Context context) {
// Override because we want all options with the same description.
return context.getString(R.string.wallpaper_color_title);
}
diff --git a/src/com/android/customization/model/color/WallpaperColorResources.java b/src/com/android/customization/model/color/WallpaperColorResources.java
index eb8b39b..dc3b903 100644
--- a/src/com/android/customization/model/color/WallpaperColorResources.java
+++ b/src/com/android/customization/model/color/WallpaperColorResources.java
@@ -21,8 +21,7 @@
import android.widget.RemoteViews.ColorResources;
import com.android.systemui.monet.ColorScheme;
-
-import java.util.List;
+import com.android.systemui.monet.TonalPalette;
/** A class to override colors in a {@link Context} with wallpaper colors. */
public class WallpaperColorResources {
@@ -43,9 +42,9 @@
ColorResources.create(context, mColorOverlay).apply(context);
}
- private void addOverlayColor(List<Integer> colors, int firstResourceColorId) {
+ private void addOverlayColor(TonalPalette colorSchemehue, int firstResourceColorId) {
int resourceColorId = firstResourceColorId;
- for (int color : colors) {
+ for (int color : colorSchemehue.getAllShades()) {
mColorOverlay.put(resourceColorId, color);
resourceColorId++;
}
diff --git a/src/com/android/customization/model/grid/GridOptionsManager.java b/src/com/android/customization/model/grid/GridOptionsManager.java
index 7f15d83..b7ee37f 100644
--- a/src/com/android/customization/model/grid/GridOptionsManager.java
+++ b/src/com/android/customization/model/grid/GridOptionsManager.java
@@ -21,7 +21,9 @@
import android.os.Looper;
import android.util.Log;
+import androidx.annotation.Nullable;
import androidx.annotation.VisibleForTesting;
+import androidx.lifecycle.LiveData;
import com.android.customization.model.CustomizationManager;
import com.android.customization.module.CustomizationInjector;
@@ -47,6 +49,7 @@
private final LauncherGridOptionsProvider mProvider;
private final ThemesUserEventLogger mEventLogger;
+ private int mGridOptionSize = -1;
/** Returns the {@link GridOptionsManager} instance. */
public static GridOptionsManager getInstance(Context context) {
@@ -71,16 +74,17 @@
@Override
public boolean isAvailable() {
- int gridOptionSize = 0;
- try {
- gridOptionSize = sExecutorService.submit(() -> {
- List<GridOption> gridOptions = mProvider.fetch(/* reload= */true);
- return gridOptions == null ? 0 : gridOptions.size();
- }).get();
- } catch (InterruptedException | ExecutionException e) {
- Log.w(TAG, "could not get gridOptionSize", e);
+ if (mGridOptionSize < 0) {
+ try {
+ mGridOptionSize = sExecutorService.submit(() -> {
+ List<GridOption> gridOptions = mProvider.fetch(/* reload= */true);
+ return gridOptions == null ? 0 : gridOptions.size();
+ }).get();
+ } catch (InterruptedException | ExecutionException e) {
+ Log.w(TAG, "could not get gridOptionSize", e);
+ }
}
- return gridOptionSize > 1 && mProvider.areGridsAvailable();
+ return mGridOptionSize > 1 && mProvider.areGridsAvailable();
}
@Override
@@ -110,6 +114,13 @@
});
}
+ /**
+ * Returns an observable that receives a new value each time that the grid options are changed.
+ */
+ public LiveData<Object> getOptionChangeObservable(@Nullable Handler handler) {
+ return mProvider.getOptionChangeObservable(handler);
+ }
+
/** Call through content provider API to render preview */
public void renderPreview(Bundle bundle, String gridName,
PreviewUtils.WorkspacePreviewCallback callback) {
diff --git a/src/com/android/customization/model/grid/GridSectionController.java b/src/com/android/customization/model/grid/GridSectionController.java
index 2f54a1b..c50bfcc 100644
--- a/src/com/android/customization/model/grid/GridSectionController.java
+++ b/src/com/android/customization/model/grid/GridSectionController.java
@@ -22,8 +22,12 @@
import android.widget.TextView;
import androidx.annotation.Nullable;
+import androidx.fragment.app.Fragment;
+import androidx.lifecycle.LifecycleOwner;
+import androidx.lifecycle.Observer;
import com.android.customization.model.CustomizationManager.OptionsFetchedListener;
+import com.android.customization.model.grid.ui.fragment.GridFragment2;
import com.android.customization.picker.grid.GridFragment;
import com.android.customization.picker.grid.GridSectionView;
import com.android.wallpaper.R;
@@ -38,11 +42,22 @@
private final GridOptionsManager mGridOptionsManager;
private final CustomizationSectionNavigationController mSectionNavigationController;
+ private final boolean mIsRevampedUiEnabled;
+ private final Observer<Object> mOptionChangeObserver;
+ private final LifecycleOwner mLifecycleOwner;
+ private TextView mSectionDescription;
+ private View mSectionTile;
- public GridSectionController(GridOptionsManager gridOptionsManager,
- CustomizationSectionNavigationController sectionNavigationController) {
+ public GridSectionController(
+ GridOptionsManager gridOptionsManager,
+ CustomizationSectionNavigationController sectionNavigationController,
+ LifecycleOwner lifecycleOwner,
+ boolean isRevampedUiEnabled) {
mGridOptionsManager = gridOptionsManager;
mSectionNavigationController = sectionNavigationController;
+ mIsRevampedUiEnabled = isRevampedUiEnabled;
+ mLifecycleOwner = lifecycleOwner;
+ mOptionChangeObserver = o -> updateUi(/* reload= */ true);
}
@Override
@@ -52,34 +67,68 @@
@Override
public GridSectionView createView(Context context) {
- GridSectionView gridSectionView = (GridSectionView) LayoutInflater.from(context)
+ final GridSectionView gridSectionView = (GridSectionView) LayoutInflater.from(context)
.inflate(R.layout.grid_section_view, /* root= */ null);
- TextView sectionDescription = gridSectionView.findViewById(R.id.grid_section_description);
- View sectionTile = gridSectionView.findViewById(R.id.grid_section_tile);
+ mSectionDescription = gridSectionView.findViewById(R.id.grid_section_description);
+ mSectionTile = gridSectionView.findViewById(R.id.grid_section_tile);
// Fetch grid options to show currently set grid.
- mGridOptionsManager.fetchOptions(new OptionsFetchedListener<GridOption>() {
- @Override
- public void onOptionsLoaded(List<GridOption> options) {
- sectionDescription.setText(getActiveOption(options).getTitle());
- }
-
- @Override
- public void onError(@Nullable Throwable throwable) {
- if (throwable != null) {
- Log.e(TAG, "Error loading grid options", throwable);
- }
- sectionDescription.setText(R.string.something_went_wrong);
- sectionTile.setVisibility(View.GONE);
- }
- }, /* The result is getting when calling isAvailable(), so reload= */ false);
+ updateUi(/* The result is getting when calling isAvailable(), so reload= */ false);
+ if (mIsRevampedUiEnabled) {
+ mGridOptionsManager.getOptionChangeObservable(/* handler= */ null).observe(
+ mLifecycleOwner,
+ mOptionChangeObserver);
+ }
gridSectionView.setOnClickListener(
- v -> mSectionNavigationController.navigateTo(new GridFragment()));
+ v -> {
+ final Fragment gridFragment;
+ if (mIsRevampedUiEnabled) {
+ gridFragment = new GridFragment2();
+ } else {
+ gridFragment = new GridFragment();
+ }
+ mSectionNavigationController.navigateTo(gridFragment);
+ });
return gridSectionView;
}
+ @Override
+ public void release() {
+ if (mIsRevampedUiEnabled && mGridOptionsManager.isAvailable()) {
+ mGridOptionsManager.getOptionChangeObservable(/* handler= */ null).removeObserver(
+ mOptionChangeObserver
+ );
+ }
+ }
+
+ @Override
+ public void onTransitionOut() {
+ CustomizationSectionController.super.onTransitionOut();
+ }
+
+ private void updateUi(final boolean reload) {
+ mGridOptionsManager.fetchOptions(
+ new OptionsFetchedListener<GridOption>() {
+ @Override
+ public void onOptionsLoaded(List<GridOption> options) {
+ final String title = getActiveOption(options).getTitle();
+ mSectionDescription.setText(title);
+ }
+
+ @Override
+ public void onError(@Nullable Throwable throwable) {
+ if (throwable != null) {
+ Log.e(TAG, "Error loading grid options", throwable);
+ }
+ mSectionDescription.setText(R.string.something_went_wrong);
+ mSectionTile.setVisibility(View.GONE);
+ }
+ },
+ reload);
+ }
+
private GridOption getActiveOption(List<GridOption> options) {
return options.stream()
.filter(option -> option.isActive(mGridOptionsManager))
diff --git a/src/com/android/customization/model/grid/LauncherGridOptionsProvider.java b/src/com/android/customization/model/grid/LauncherGridOptionsProvider.java
index fd40363..4e775c6 100644
--- a/src/com/android/customization/model/grid/LauncherGridOptionsProvider.java
+++ b/src/com/android/customization/model/grid/LauncherGridOptionsProvider.java
@@ -19,12 +19,17 @@
import android.content.ContentValues;
import android.content.Context;
import android.content.res.Resources;
+import android.database.ContentObserver;
import android.database.Cursor;
+import android.net.Uri;
import android.os.Bundle;
+import android.os.Handler;
import android.view.SurfaceView;
import androidx.annotation.Nullable;
import androidx.annotation.WorkerThread;
+import androidx.lifecycle.LiveData;
+import androidx.lifecycle.MutableLiveData;
import com.android.customization.model.ResourceConstants;
import com.android.wallpaper.R;
@@ -53,6 +58,7 @@
private final Context mContext;
private final PreviewUtils mPreviewUtils;
private List<GridOption> mOptions;
+ private OptionChangeLiveData mLiveData;
public LauncherGridOptionsProvider(Context context, String authorityMetadataKey) {
mPreviewUtils = new PreviewUtils(context, authorityMetadataKey);
@@ -117,4 +123,52 @@
return mContext.getContentResolver().update(mPreviewUtils.getUri(DEFAULT_GRID), values,
null, null);
}
+
+ /**
+ * Returns an observable that receives a new value each time that the grid options are changed.
+ * Do not call if {@link #areGridsAvailable()} returns false
+ */
+ public LiveData<Object> getOptionChangeObservable(
+ @Nullable Handler handler) {
+ if (mLiveData == null) {
+ mLiveData = new OptionChangeLiveData(
+ mContext, mPreviewUtils.getUri(DEFAULT_GRID), handler);
+ }
+
+ return mLiveData;
+ }
+
+ private static class OptionChangeLiveData extends MutableLiveData<Object> {
+
+ private final ContentResolver mContentResolver;
+ private final Uri mUri;
+ private final ContentObserver mContentObserver;
+
+ OptionChangeLiveData(
+ Context context,
+ Uri uri,
+ @Nullable Handler handler) {
+ mContentResolver = context.getContentResolver();
+ mUri = uri;
+ mContentObserver = new ContentObserver(handler) {
+ @Override
+ public void onChange(boolean selfChange) {
+ postValue(new Object());
+ }
+ };
+ }
+
+ @Override
+ protected void onActive() {
+ mContentResolver.registerContentObserver(
+ mUri,
+ /* notifyForDescendants= */ true,
+ mContentObserver);
+ }
+
+ @Override
+ protected void onInactive() {
+ mContentResolver.unregisterContentObserver(mContentObserver);
+ }
+ }
}
diff --git a/src/com/android/customization/model/grid/data/repository/GridRepository.kt b/src/com/android/customization/model/grid/data/repository/GridRepository.kt
new file mode 100644
index 0000000..9a3be0c
--- /dev/null
+++ b/src/com/android/customization/model/grid/data/repository/GridRepository.kt
@@ -0,0 +1,127 @@
+/*
+ * 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.grid.data.repository
+
+import androidx.lifecycle.asFlow
+import com.android.customization.model.CustomizationManager
+import com.android.customization.model.grid.GridOption
+import com.android.customization.model.grid.GridOptionsManager
+import com.android.customization.model.grid.shared.model.GridOptionItemModel
+import com.android.customization.model.grid.shared.model.GridOptionItemsModel
+import kotlin.coroutines.resume
+import kotlinx.coroutines.CoroutineDispatcher
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.MutableStateFlow
+import kotlinx.coroutines.flow.SharingStarted
+import kotlinx.coroutines.flow.map
+import kotlinx.coroutines.flow.stateIn
+import kotlinx.coroutines.suspendCancellableCoroutine
+import kotlinx.coroutines.withContext
+
+interface GridRepository {
+ suspend fun isAvailable(): Boolean
+ fun getOptionChanges(): Flow<Unit>
+ suspend fun getOptions(): GridOptionItemsModel
+}
+
+class GridRepositoryImpl(
+ private val applicationScope: CoroutineScope,
+ private val manager: GridOptionsManager,
+ private val backgroundDispatcher: CoroutineDispatcher,
+) : GridRepository {
+
+ override suspend fun isAvailable(): Boolean {
+ return withContext(backgroundDispatcher) { manager.isAvailable }
+ }
+
+ override fun getOptionChanges(): Flow<Unit> =
+ manager.getOptionChangeObservable(/* handler= */ null).asFlow().map {}
+
+ private val selectedOption = MutableStateFlow<GridOption?>(null)
+
+ override suspend fun getOptions(): GridOptionItemsModel {
+ return withContext(backgroundDispatcher) {
+ suspendCancellableCoroutine { continuation ->
+ manager.fetchOptions(
+ object : CustomizationManager.OptionsFetchedListener<GridOption> {
+ override fun onOptionsLoaded(options: MutableList<GridOption>?) {
+ val optionsOrEmpty = options ?: emptyList()
+ selectedOption.value = optionsOrEmpty.find { it.isActive(manager) }
+ continuation.resume(
+ GridOptionItemsModel.Loaded(
+ optionsOrEmpty.map { option -> toModel(option) }
+ )
+ )
+ }
+
+ override fun onError(throwable: Throwable?) {
+ continuation.resume(
+ GridOptionItemsModel.Error(
+ throwable ?: Exception("Failed to load grid options!")
+ ),
+ )
+ }
+ },
+ /* reload= */ true,
+ )
+ }
+ }
+ }
+
+ private fun toModel(option: GridOption): GridOptionItemModel {
+ return GridOptionItemModel(
+ name = option.title,
+ rows = option.rows,
+ cols = option.cols,
+ isSelected =
+ selectedOption
+ .map { it.key() }
+ .map { selectedOptionKey -> option.key() == selectedOptionKey }
+ .stateIn(
+ scope = applicationScope,
+ started = SharingStarted.Eagerly,
+ initialValue = false,
+ ),
+ onSelected = { onSelected(option) },
+ )
+ }
+
+ private suspend fun onSelected(option: GridOption) {
+ withContext(backgroundDispatcher) {
+ suspendCancellableCoroutine { continuation ->
+ manager.apply(
+ option,
+ object : CustomizationManager.Callback {
+ override fun onSuccess() {
+ continuation.resume(true)
+ }
+
+ override fun onError(throwable: Throwable?) {
+ continuation.resume(false)
+ }
+ },
+ )
+ }
+ }
+ }
+
+ private fun GridOption?.key(): String? {
+ return if (this != null) "${cols}x${rows}" else null
+ }
+}
diff --git a/src/com/android/customization/model/grid/domain/interactor/GridInteractor.kt b/src/com/android/customization/model/grid/domain/interactor/GridInteractor.kt
new file mode 100644
index 0000000..cdb679d
--- /dev/null
+++ b/src/com/android/customization/model/grid/domain/interactor/GridInteractor.kt
@@ -0,0 +1,98 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package com.android.customization.model.grid.domain.interactor
+
+import com.android.customization.model.grid.data.repository.GridRepository
+import com.android.customization.model.grid.shared.model.GridOptionItemModel
+import com.android.customization.model.grid.shared.model.GridOptionItemsModel
+import javax.inject.Provider
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.SharingStarted
+import kotlinx.coroutines.flow.emptyFlow
+import kotlinx.coroutines.flow.flatMapLatest
+import kotlinx.coroutines.flow.flow
+import kotlinx.coroutines.flow.map
+import kotlinx.coroutines.flow.onStart
+import kotlinx.coroutines.flow.shareIn
+
+class GridInteractor(
+ private val applicationScope: CoroutineScope,
+ private val repository: GridRepository,
+ private val snapshotRestorer: Provider<GridSnapshotRestorer>,
+) {
+ val options: Flow<GridOptionItemsModel> =
+ flow { emit(repository.isAvailable()) }
+ .flatMapLatest { isAvailable ->
+ if (isAvailable) {
+ // this upstream flow tells us each time the options are changed.
+ repository
+ .getOptionChanges()
+ // when we start, we pretend the options _just_ changed. This way, we load
+ // something as soon as possible into the flow so it's ready by the time the
+ // first observer starts to observe.
+ .onStart { emit(Unit) }
+ // each time the options changed, we load them.
+ .map { reload() }
+ // we place the loaded options in a SharedFlow so downstream observers all
+ // share the same flow and don't trigger a new one each time they want to
+ // start observing.
+ .shareIn(
+ scope = applicationScope,
+ started = SharingStarted.WhileSubscribed(),
+ replay = 1,
+ )
+ } else {
+ emptyFlow()
+ }
+ }
+
+ suspend fun setSelectedOption(model: GridOptionItemModel) {
+ model.onSelected.invoke()
+ }
+
+ suspend fun getSelectedOption(): GridOptionItemModel? {
+ return (repository.getOptions() as? GridOptionItemsModel.Loaded)?.options?.firstOrNull {
+ optionItem ->
+ optionItem.isSelected.value
+ }
+ }
+
+ private suspend fun reload(): GridOptionItemsModel {
+ val model = repository.getOptions()
+ return if (model is GridOptionItemsModel.Loaded) {
+ GridOptionItemsModel.Loaded(
+ options =
+ model.options.map { option ->
+ GridOptionItemModel(
+ name = option.name,
+ cols = option.cols,
+ rows = option.rows,
+ isSelected = option.isSelected,
+ onSelected = {
+ option.onSelected()
+ snapshotRestorer.get().store(option)
+ },
+ )
+ }
+ )
+ } else {
+ model
+ }
+ }
+}
diff --git a/src/com/android/customization/model/grid/domain/interactor/GridSnapshotRestorer.kt b/src/com/android/customization/model/grid/domain/interactor/GridSnapshotRestorer.kt
new file mode 100644
index 0000000..19d4c77
--- /dev/null
+++ b/src/com/android/customization/model/grid/domain/interactor/GridSnapshotRestorer.kt
@@ -0,0 +1,74 @@
+/*
+ * 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.grid.domain.interactor
+
+import android.util.Log
+import com.android.customization.model.grid.shared.model.GridOptionItemModel
+import com.android.wallpaper.picker.undo.domain.interactor.SnapshotRestorer
+import com.android.wallpaper.picker.undo.domain.interactor.SnapshotStore
+import com.android.wallpaper.picker.undo.shared.model.RestorableSnapshot
+
+class GridSnapshotRestorer(
+ private val interactor: GridInteractor,
+) : SnapshotRestorer {
+
+ private var store: SnapshotStore = SnapshotStore.NOOP
+ private var originalOption: GridOptionItemModel? = null
+
+ override suspend fun setUpSnapshotRestorer(store: SnapshotStore): RestorableSnapshot {
+ this.store = store
+ val option = interactor.getSelectedOption()
+ originalOption = option
+ return snapshot(option)
+ }
+
+ override suspend fun restoreToSnapshot(snapshot: RestorableSnapshot) {
+ val optionNameFromSnapshot = snapshot.args[KEY_GRID_OPTION_NAME]
+ originalOption?.let { optionToRestore ->
+ if (optionToRestore.name != optionNameFromSnapshot) {
+ Log.wtf(
+ TAG,
+ """Original snapshot name was ${optionToRestore.name} but we're being told to
+ | restore to $optionNameFromSnapshot. The current implementation doesn't
+ | support undo, only a reset back to the original grid option."""
+ .trimMargin(),
+ )
+ }
+
+ interactor.setSelectedOption(optionToRestore)
+ }
+ }
+
+ fun store(option: GridOptionItemModel) {
+ store.store(snapshot(option))
+ }
+
+ private fun snapshot(option: GridOptionItemModel?): RestorableSnapshot {
+ return RestorableSnapshot(
+ args =
+ buildMap {
+ option?.name?.let { optionName -> put(KEY_GRID_OPTION_NAME, optionName) }
+ }
+ )
+ }
+
+ companion object {
+ private const val TAG = "GridSnapshotRestorer"
+ private const val KEY_GRID_OPTION_NAME = "grid_option"
+ }
+}
diff --git a/src/com/android/customization/picker/clock/ClockSectionView.kt b/src/com/android/customization/model/grid/shared/model/GridOptionItemModel.kt
similarity index 61%
copy from src/com/android/customization/picker/clock/ClockSectionView.kt
copy to src/com/android/customization/model/grid/shared/model/GridOptionItemModel.kt
index fac975a..2eabeab 100644
--- a/src/com/android/customization/picker/clock/ClockSectionView.kt
+++ b/src/com/android/customization/model/grid/shared/model/GridOptionItemModel.kt
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2022 The Android Open Source Project
+ * 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.
@@ -12,12 +12,17 @@
* 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
-import android.content.Context
-import android.util.AttributeSet
-import com.android.wallpaper.picker.SectionView
+package com.android.customization.model.grid.shared.model
-/** The [SectionView] for app clock. */
-class ClockSectionView(context: Context?, attrs: AttributeSet?) : SectionView(context, attrs)
+import kotlinx.coroutines.flow.StateFlow
+
+data class GridOptionItemModel(
+ val name: String,
+ val cols: Int,
+ val rows: Int,
+ val isSelected: StateFlow<Boolean>,
+ val onSelected: suspend () -> Unit,
+)
diff --git a/src/com/android/customization/picker/clock/ClockSectionView.kt b/src/com/android/customization/model/grid/shared/model/GridOptionItemsModel.kt
similarity index 61%
copy from src/com/android/customization/picker/clock/ClockSectionView.kt
copy to src/com/android/customization/model/grid/shared/model/GridOptionItemsModel.kt
index fac975a..e969be8 100644
--- a/src/com/android/customization/picker/clock/ClockSectionView.kt
+++ b/src/com/android/customization/model/grid/shared/model/GridOptionItemsModel.kt
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2022 The Android Open Source Project
+ * 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.
@@ -12,12 +12,16 @@
* 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
-import android.content.Context
-import android.util.AttributeSet
-import com.android.wallpaper.picker.SectionView
+package com.android.customization.model.grid.shared.model
-/** The [SectionView] for app clock. */
-class ClockSectionView(context: Context?, attrs: AttributeSet?) : SectionView(context, attrs)
+sealed class GridOptionItemsModel {
+ data class Loaded(
+ val options: List<GridOptionItemModel>,
+ ) : GridOptionItemsModel()
+ data class Error(
+ val throwable: Throwable?,
+ ) : GridOptionItemsModel()
+}
diff --git a/src/com/android/customization/model/grid/ui/binder/GridIconViewBinder.kt b/src/com/android/customization/model/grid/ui/binder/GridIconViewBinder.kt
new file mode 100644
index 0000000..fba89a7
--- /dev/null
+++ b/src/com/android/customization/model/grid/ui/binder/GridIconViewBinder.kt
@@ -0,0 +1,17 @@
+package com.android.customization.model.grid.ui.binder
+
+import android.widget.ImageView
+import com.android.customization.model.grid.ui.viewmodel.GridIconViewModel
+import com.android.customization.widget.GridTileDrawable
+
+object GridIconViewBinder {
+ fun bind(view: ImageView, viewModel: GridIconViewModel) {
+ view.setImageDrawable(
+ GridTileDrawable(
+ viewModel.columns,
+ viewModel.rows,
+ viewModel.path,
+ )
+ )
+ }
+}
diff --git a/src/com/android/customization/model/grid/ui/binder/GridScreenBinder.kt b/src/com/android/customization/model/grid/ui/binder/GridScreenBinder.kt
new file mode 100644
index 0000000..78536ca
--- /dev/null
+++ b/src/com/android/customization/model/grid/ui/binder/GridScreenBinder.kt
@@ -0,0 +1,81 @@
+/*
+ * 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.grid.ui.binder
+
+import android.view.View
+import android.widget.ImageView
+import androidx.lifecycle.Lifecycle
+import androidx.lifecycle.LifecycleOwner
+import androidx.lifecycle.lifecycleScope
+import androidx.lifecycle.repeatOnLifecycle
+import androidx.recyclerview.widget.LinearLayoutManager
+import androidx.recyclerview.widget.RecyclerView
+import com.android.customization.model.grid.ui.viewmodel.GridIconViewModel
+import com.android.customization.model.grid.ui.viewmodel.GridScreenViewModel
+import com.android.customization.picker.common.ui.view.ItemSpacing
+import com.android.wallpaper.R
+import com.android.wallpaper.picker.option.ui.adapter.OptionItemAdapter
+import com.android.wallpaper.picker.option.ui.binder.OptionItemBinder
+import kotlinx.coroutines.CoroutineDispatcher
+import kotlinx.coroutines.launch
+
+object GridScreenBinder {
+ fun bind(
+ view: View,
+ viewModel: GridScreenViewModel,
+ lifecycleOwner: LifecycleOwner,
+ backgroundDispatcher: CoroutineDispatcher,
+ onOptionsChanged: () -> Unit,
+ ) {
+ val optionView: RecyclerView = view.requireViewById(R.id.options)
+ optionView.layoutManager =
+ LinearLayoutManager(
+ view.context,
+ RecyclerView.HORIZONTAL,
+ /* reverseLayout= */ false,
+ )
+ optionView.addItemDecoration(ItemSpacing(ItemSpacing.ITEM_SPACING_DP))
+ val adapter =
+ OptionItemAdapter(
+ layoutResourceId = R.layout.grid_option_2,
+ lifecycleOwner = lifecycleOwner,
+ backgroundDispatcher = backgroundDispatcher,
+ foregroundTintSpec =
+ OptionItemBinder.TintSpec(
+ selectedColor = view.context.getColor(R.color.text_color_primary),
+ unselectedColor = view.context.getColor(R.color.text_color_secondary),
+ ),
+ bindIcon = { foregroundView: View, gridIcon: GridIconViewModel ->
+ val imageView = foregroundView as? ImageView
+ imageView?.let { GridIconViewBinder.bind(imageView, gridIcon) }
+ }
+ )
+ optionView.adapter = adapter
+
+ lifecycleOwner.lifecycleScope.launch {
+ lifecycleOwner.repeatOnLifecycle(Lifecycle.State.STARTED) {
+ launch {
+ viewModel.optionItems.collect { options ->
+ adapter.setItems(options)
+ onOptionsChanged()
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/src/com/android/customization/model/grid/ui/fragment/GridFragment2.kt b/src/com/android/customization/model/grid/ui/fragment/GridFragment2.kt
new file mode 100644
index 0000000..d8cad82
--- /dev/null
+++ b/src/com/android/customization/model/grid/ui/fragment/GridFragment2.kt
@@ -0,0 +1,132 @@
+/*
+ * 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.grid.ui.fragment
+
+import android.os.Bundle
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import androidx.lifecycle.ViewModelProvider
+import com.android.customization.model.grid.ui.binder.GridScreenBinder
+import com.android.customization.model.grid.ui.viewmodel.GridScreenViewModel
+import com.android.customization.module.ThemePickerInjector
+import com.android.wallpaper.R
+import com.android.wallpaper.module.CurrentWallpaperInfoFactory
+import com.android.wallpaper.module.CustomizationSections
+import com.android.wallpaper.module.InjectorProvider
+import com.android.wallpaper.picker.AppbarFragment
+import com.android.wallpaper.picker.customization.domain.interactor.WallpaperInteractor
+import com.android.wallpaper.picker.customization.ui.binder.ScreenPreviewBinder
+import com.android.wallpaper.picker.customization.ui.viewmodel.ScreenPreviewViewModel
+import com.android.wallpaper.util.PreviewUtils
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.suspendCancellableCoroutine
+
+@OptIn(ExperimentalCoroutinesApi::class)
+class GridFragment2 : AppbarFragment() {
+
+ override fun onCreateView(
+ inflater: LayoutInflater,
+ container: ViewGroup?,
+ savedInstanceState: Bundle?
+ ): View {
+ val view =
+ inflater.inflate(
+ R.layout.fragment_grid,
+ container,
+ false,
+ )
+ setUpToolbar(view)
+
+ val injector = InjectorProvider.getInjector() as ThemePickerInjector
+
+ val wallpaperInfoFactory = injector.getCurrentWallpaperInfoFactory(requireContext())
+ var screenPreviewBinding =
+ bindScreenPreview(
+ view,
+ wallpaperInfoFactory,
+ injector.getWallpaperInteractor(requireContext())
+ )
+
+ val viewModelFactory = injector.getGridScreenViewModelFactory(requireContext())
+ GridScreenBinder.bind(
+ view = view,
+ viewModel =
+ ViewModelProvider(
+ this,
+ viewModelFactory,
+ )[GridScreenViewModel::class.java],
+ lifecycleOwner = this,
+ backgroundDispatcher = Dispatchers.IO,
+ onOptionsChanged = {
+ screenPreviewBinding.destroy()
+ screenPreviewBinding =
+ bindScreenPreview(
+ view,
+ wallpaperInfoFactory,
+ injector.getWallpaperInteractor(requireContext())
+ )
+ }
+ )
+
+ return view
+ }
+
+ override fun getDefaultTitle(): CharSequence {
+ return getString(R.string.grid_title)
+ }
+
+ private fun bindScreenPreview(
+ view: View,
+ wallpaperInfoFactory: CurrentWallpaperInfoFactory,
+ wallpaperInteractor: WallpaperInteractor,
+ ): ScreenPreviewBinder.Binding {
+ return ScreenPreviewBinder.bind(
+ activity = requireActivity(),
+ previewView = view.requireViewById(R.id.preview),
+ viewModel =
+ ScreenPreviewViewModel(
+ previewUtils =
+ PreviewUtils(
+ context = requireContext(),
+ authorityMetadataKey =
+ requireContext()
+ .getString(
+ R.string.grid_control_metadata_name,
+ ),
+ ),
+ wallpaperInfoProvider = {
+ suspendCancellableCoroutine { continuation ->
+ wallpaperInfoFactory.createCurrentWallpaperInfos(
+ { homeWallpaper, lockWallpaper, _ ->
+ continuation.resume(homeWallpaper ?: lockWallpaper, null)
+ },
+ /* forceRefresh= */ true,
+ )
+ }
+ },
+ wallpaperInteractor = wallpaperInteractor,
+ ),
+ lifecycleOwner = this,
+ offsetToStart = false,
+ screen = CustomizationSections.Screen.HOME_SCREEN,
+ onPreviewDirty = { activity?.recreate() },
+ )
+ }
+}
diff --git a/src/com/android/customization/picker/clock/ClockSectionView.kt b/src/com/android/customization/model/grid/ui/viewmodel/GridIconViewModel.kt
similarity index 61%
copy from src/com/android/customization/picker/clock/ClockSectionView.kt
copy to src/com/android/customization/model/grid/ui/viewmodel/GridIconViewModel.kt
index fac975a..3942d7c 100644
--- a/src/com/android/customization/picker/clock/ClockSectionView.kt
+++ b/src/com/android/customization/model/grid/ui/viewmodel/GridIconViewModel.kt
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2022 The Android Open Source Project
+ * 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.
@@ -12,12 +12,13 @@
* 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
-import android.content.Context
-import android.util.AttributeSet
-import com.android.wallpaper.picker.SectionView
+package com.android.customization.model.grid.ui.viewmodel
-/** The [SectionView] for app clock. */
-class ClockSectionView(context: Context?, attrs: AttributeSet?) : SectionView(context, attrs)
+data class GridIconViewModel(
+ val columns: Int,
+ val rows: Int,
+ val path: String,
+)
diff --git a/src/com/android/customization/model/grid/ui/viewmodel/GridScreenViewModel.kt b/src/com/android/customization/model/grid/ui/viewmodel/GridScreenViewModel.kt
new file mode 100644
index 0000000..c11a594
--- /dev/null
+++ b/src/com/android/customization/model/grid/ui/viewmodel/GridScreenViewModel.kt
@@ -0,0 +1,106 @@
+/*
+ * 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.grid.ui.viewmodel
+
+import android.annotation.SuppressLint
+import android.content.Context
+import android.content.res.Resources
+import androidx.lifecycle.ViewModel
+import androidx.lifecycle.ViewModelProvider
+import androidx.lifecycle.viewModelScope
+import com.android.customization.model.ResourceConstants
+import com.android.customization.model.grid.domain.interactor.GridInteractor
+import com.android.customization.model.grid.shared.model.GridOptionItemsModel
+import com.android.wallpaper.picker.common.text.ui.viewmodel.Text
+import com.android.wallpaper.picker.option.ui.viewmodel.OptionItemViewModel
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.MutableStateFlow
+import kotlinx.coroutines.flow.StateFlow
+import kotlinx.coroutines.flow.map
+import kotlinx.coroutines.launch
+
+class GridScreenViewModel(
+ context: Context,
+ private val interactor: GridInteractor,
+) : ViewModel() {
+
+ @SuppressLint("StaticFieldLeak") // We're not leaking this context as it is the app context.
+ private val applicationContext = context.applicationContext
+
+ val optionItems: Flow<List<OptionItemViewModel<GridIconViewModel>>> =
+ interactor.options.map { model -> toViewModel(model) }
+
+ private fun toViewModel(
+ model: GridOptionItemsModel,
+ ): List<OptionItemViewModel<GridIconViewModel>> {
+ val iconShapePath =
+ applicationContext.resources.getString(
+ Resources.getSystem()
+ .getIdentifier(
+ ResourceConstants.CONFIG_ICON_MASK,
+ "string",
+ ResourceConstants.ANDROID_PACKAGE,
+ )
+ )
+
+ return when (model) {
+ is GridOptionItemsModel.Loaded ->
+ model.options.map { option ->
+ val text = Text.Loaded(option.name)
+ OptionItemViewModel<GridIconViewModel>(
+ key =
+ MutableStateFlow("${option.cols}x${option.rows}") as StateFlow<String>,
+ payload =
+ GridIconViewModel(
+ columns = option.cols,
+ rows = option.rows,
+ path = iconShapePath,
+ ),
+ text = text,
+ isSelected = option.isSelected,
+ onClicked =
+ option.isSelected.map { isSelected ->
+ if (!isSelected) {
+ { viewModelScope.launch { option.onSelected() } }
+ } else {
+ null
+ }
+ },
+ )
+ }
+ is GridOptionItemsModel.Error -> emptyList()
+ }
+ }
+
+ class Factory(
+ context: Context,
+ private val interactor: GridInteractor,
+ ) : ViewModelProvider.Factory {
+
+ private val applicationContext = context.applicationContext
+
+ @Suppress("UNCHECKED_CAST")
+ override fun <T : ViewModel> create(modelClass: Class<T>): T {
+ return GridScreenViewModel(
+ context = applicationContext,
+ interactor = interactor,
+ )
+ as T
+ }
+ }
+}
diff --git a/src/com/android/customization/model/mode/DarkModeSectionController.java b/src/com/android/customization/model/mode/DarkModeSectionController.java
index f56b709..ebeaa56 100644
--- a/src/com/android/customization/model/mode/DarkModeSectionController.java
+++ b/src/com/android/customization/model/mode/DarkModeSectionController.java
@@ -59,12 +59,17 @@
private Context mContext;
private DarkModeSectionView mDarkModeSectionView;
+ private final DarkModeSnapshotRestorer mSnapshotRestorer;
- public DarkModeSectionController(Context context, Lifecycle lifecycle) {
+ public DarkModeSectionController(
+ Context context,
+ Lifecycle lifecycle,
+ DarkModeSnapshotRestorer snapshotRestorer) {
mContext = context;
mLifecycle = lifecycle;
mPowerManager = context.getSystemService(PowerManager.class);
mLifecycle.addObserver(this);
+ mSnapshotRestorer = snapshotRestorer;
}
@OnLifecycleEvent(Lifecycle.Event.ON_START)
@@ -132,6 +137,7 @@
mDarkModeSectionView.announceForAccessibility(
context.getString(R.string.mode_changed));
uiModeManager.setNightModeActivated(viewActivated);
+ mSnapshotRestorer.store(viewActivated);
},
/* delayMillis= */ shortDelay);
}
diff --git a/src/com/android/customization/model/mode/DarkModeSnapshotRestorer.kt b/src/com/android/customization/model/mode/DarkModeSnapshotRestorer.kt
new file mode 100644
index 0000000..93bd0bf
--- /dev/null
+++ b/src/com/android/customization/model/mode/DarkModeSnapshotRestorer.kt
@@ -0,0 +1,101 @@
+/*
+ * 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.mode
+
+import android.app.UiModeManager
+import android.content.Context
+import android.content.res.Configuration
+import androidx.annotation.VisibleForTesting
+import com.android.wallpaper.picker.undo.domain.interactor.SnapshotRestorer
+import com.android.wallpaper.picker.undo.domain.interactor.SnapshotStore
+import com.android.wallpaper.picker.undo.shared.model.RestorableSnapshot
+import kotlinx.coroutines.CoroutineDispatcher
+import kotlinx.coroutines.withContext
+
+class DarkModeSnapshotRestorer : SnapshotRestorer {
+
+ private val backgroundDispatcher: CoroutineDispatcher
+ private val isActive: () -> Boolean
+ private val setActive: suspend (Boolean) -> Unit
+
+ private var store: SnapshotStore = SnapshotStore.NOOP
+
+ constructor(
+ context: Context,
+ manager: UiModeManager,
+ backgroundDispatcher: CoroutineDispatcher,
+ ) : this(
+ backgroundDispatcher = backgroundDispatcher,
+ isActive = {
+ context.applicationContext.resources.configuration.uiMode and
+ Configuration.UI_MODE_NIGHT_YES != 0
+ },
+ setActive = { isActive -> manager.setNightModeActivated(isActive) },
+ )
+
+ @VisibleForTesting
+ constructor(
+ backgroundDispatcher: CoroutineDispatcher,
+ isActive: () -> Boolean,
+ setActive: suspend (Boolean) -> Unit,
+ ) {
+ this.backgroundDispatcher = backgroundDispatcher
+ this.isActive = isActive
+ this.setActive = setActive
+ }
+
+ override suspend fun setUpSnapshotRestorer(store: SnapshotStore): RestorableSnapshot {
+ this.store = store
+ return snapshot(
+ isActivated = isActive(),
+ )
+ }
+
+ override suspend fun restoreToSnapshot(snapshot: RestorableSnapshot) {
+ val isActivated = snapshot.args[KEY]?.toBoolean() == true
+ withContext(backgroundDispatcher) { setActive(isActivated) }
+ }
+
+ fun store(
+ isActivated: Boolean,
+ ) {
+ store.store(
+ snapshot(
+ isActivated = isActivated,
+ ),
+ )
+ }
+
+ private fun snapshot(
+ isActivated: Boolean,
+ ): RestorableSnapshot {
+ return RestorableSnapshot(
+ args =
+ buildMap {
+ put(
+ KEY,
+ isActivated.toString(),
+ )
+ }
+ )
+ }
+
+ companion object {
+ private const val KEY = "is_activated"
+ }
+}
diff --git a/src/com/android/customization/model/themedicon/ThemedIconSectionController.java b/src/com/android/customization/model/themedicon/ThemedIconSectionController.java
index a1623d1..5d551a6 100644
--- a/src/com/android/customization/model/themedicon/ThemedIconSectionController.java
+++ b/src/com/android/customization/model/themedicon/ThemedIconSectionController.java
@@ -20,11 +20,13 @@
import android.view.LayoutInflater;
import androidx.annotation.Nullable;
+import androidx.lifecycle.Observer;
+import com.android.customization.model.themedicon.domain.interactor.ThemedIconInteractor;
+import com.android.customization.model.themedicon.domain.interactor.ThemedIconSnapshotRestorer;
import com.android.customization.picker.themedicon.ThemedIconSectionView;
import com.android.wallpaper.R;
import com.android.wallpaper.model.CustomizationSectionController;
-import com.android.wallpaper.model.WorkspaceViewModel;
/** The {@link CustomizationSectionController} for themed icon section. */
public class ThemedIconSectionController implements
@@ -33,16 +35,26 @@
private static final String KEY_THEMED_ICON_ENABLED = "SAVED_THEMED_ICON_ENABLED";
private final ThemedIconSwitchProvider mThemedIconOptionsProvider;
- private final WorkspaceViewModel mWorkspaceViewModel;
+ private final ThemedIconInteractor mInteractor;
+ private final ThemedIconSnapshotRestorer mSnapshotRestorer;
+ private final Observer<Boolean> mIsActivatedChangeObserver;
private ThemedIconSectionView mThemedIconSectionView;
private boolean mSavedThemedIconEnabled = false;
-
- public ThemedIconSectionController(ThemedIconSwitchProvider themedIconOptionsProvider,
- WorkspaceViewModel workspaceViewModel, @Nullable Bundle savedInstanceState) {
+ public ThemedIconSectionController(
+ ThemedIconSwitchProvider themedIconOptionsProvider,
+ ThemedIconInteractor interactor,
+ @Nullable Bundle savedInstanceState,
+ ThemedIconSnapshotRestorer snapshotRestorer) {
mThemedIconOptionsProvider = themedIconOptionsProvider;
- mWorkspaceViewModel = workspaceViewModel;
+ mInteractor = interactor;
+ mSnapshotRestorer = snapshotRestorer;
+ mIsActivatedChangeObserver = isActivated -> {
+ if (mThemedIconSectionView.isAttachedToWindow()) {
+ mThemedIconSectionView.getSwitch().setChecked(isActivated);
+ }
+ };
if (savedInstanceState != null) {
mSavedThemedIconEnabled = savedInstanceState.getBoolean(
@@ -64,15 +76,22 @@
mThemedIconSectionView.getSwitch().setChecked(mSavedThemedIconEnabled);
mThemedIconOptionsProvider.fetchThemedIconEnabled(
enabled -> mThemedIconSectionView.getSwitch().setChecked(enabled));
+ mInteractor.isActivatedAsLiveData().observeForever(mIsActivatedChangeObserver);
return mThemedIconSectionView;
}
+ @Override
+ public void release() {
+ mInteractor.isActivatedAsLiveData().removeObserver(mIsActivatedChangeObserver);
+ }
+
private void onViewActivated(Context context, boolean viewActivated) {
if (context == null) {
return;
}
mThemedIconOptionsProvider.setThemedIconEnabled(viewActivated);
- mWorkspaceViewModel.getUpdateWorkspace().setValue(viewActivated);
+ mInteractor.setActivated(viewActivated);
+ mSnapshotRestorer.store(viewActivated);
}
@Override
diff --git a/src/com/android/customization/model/themedicon/ThemedIconSwitchProvider.java b/src/com/android/customization/model/themedicon/ThemedIconSwitchProvider.java
index 9acd319..5e2a60a 100644
--- a/src/com/android/customization/model/themedicon/ThemedIconSwitchProvider.java
+++ b/src/com/android/customization/model/themedicon/ThemedIconSwitchProvider.java
@@ -118,7 +118,7 @@
*
* <p>The value would also be stored in SharedPreferences.
*/
- protected void setThemedIconEnabled(boolean enabled) {
+ public void setThemedIconEnabled(boolean enabled) {
mExecutorService.submit(() -> {
ContentValues values = new ContentValues();
values.put(COL_ICON_THEMED_VALUE, enabled);
diff --git a/src/com/android/customization/model/themedicon/data/repository/ThemedIconRepository.kt b/src/com/android/customization/model/themedicon/data/repository/ThemedIconRepository.kt
new file mode 100644
index 0000000..9108811
--- /dev/null
+++ b/src/com/android/customization/model/themedicon/data/repository/ThemedIconRepository.kt
@@ -0,0 +1,30 @@
+/*
+ * 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.themedicon.data.repository
+
+import kotlinx.coroutines.flow.MutableStateFlow
+import kotlinx.coroutines.flow.asStateFlow
+
+class ThemeIconRepository {
+ private val _isActivated = MutableStateFlow(false)
+ val isActivated = _isActivated.asStateFlow()
+
+ fun setActivated(isActivated: Boolean) {
+ _isActivated.value = isActivated
+ }
+}
diff --git a/src/com/android/customization/model/themedicon/domain/interactor/ThemedIconInteractor.kt b/src/com/android/customization/model/themedicon/domain/interactor/ThemedIconInteractor.kt
new file mode 100644
index 0000000..1cfe877
--- /dev/null
+++ b/src/com/android/customization/model/themedicon/domain/interactor/ThemedIconInteractor.kt
@@ -0,0 +1,38 @@
+/*
+ * 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.themedicon.domain.interactor
+
+import androidx.lifecycle.LiveData
+import androidx.lifecycle.asLiveData
+import com.android.customization.model.themedicon.data.repository.ThemeIconRepository
+
+class ThemedIconInteractor(
+ private val repository: ThemeIconRepository,
+) {
+ val isActivated = repository.isActivated
+
+ private var isActivatedAsLiveData: LiveData<Boolean>? = null
+
+ fun isActivatedAsLiveData(): LiveData<Boolean> {
+ return isActivatedAsLiveData ?: isActivated.asLiveData().also { isActivatedAsLiveData = it }
+ }
+
+ fun setActivated(isActivated: Boolean) {
+ repository.setActivated(isActivated)
+ }
+}
diff --git a/src/com/android/customization/model/themedicon/domain/interactor/ThemedIconSnapshotRestorer.kt b/src/com/android/customization/model/themedicon/domain/interactor/ThemedIconSnapshotRestorer.kt
new file mode 100644
index 0000000..cacc45e
--- /dev/null
+++ b/src/com/android/customization/model/themedicon/domain/interactor/ThemedIconSnapshotRestorer.kt
@@ -0,0 +1,60 @@
+/*
+ * 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.themedicon.domain.interactor
+
+import com.android.wallpaper.picker.undo.domain.interactor.SnapshotRestorer
+import com.android.wallpaper.picker.undo.domain.interactor.SnapshotStore
+import com.android.wallpaper.picker.undo.shared.model.RestorableSnapshot
+
+class ThemedIconSnapshotRestorer(
+ private val isActivated: () -> Boolean,
+ private val setActivated: (isActivated: Boolean) -> Unit,
+ private val interactor: ThemedIconInteractor,
+) : SnapshotRestorer {
+
+ private var store: SnapshotStore = SnapshotStore.NOOP
+
+ override suspend fun setUpSnapshotRestorer(store: SnapshotStore): RestorableSnapshot {
+ this.store = store
+ return snapshot()
+ }
+
+ override suspend fun restoreToSnapshot(snapshot: RestorableSnapshot) {
+ val isActivated = snapshot.args[KEY]?.toBoolean() == true
+ setActivated(isActivated)
+ interactor.setActivated(isActivated)
+ }
+
+ fun store(
+ isActivated: Boolean,
+ ) {
+ store.store(snapshot(isActivated = isActivated))
+ }
+
+ private fun snapshot(
+ isActivated: Boolean? = null,
+ ): RestorableSnapshot {
+ return RestorableSnapshot(
+ args = buildMap { put(KEY, (isActivated ?: isActivated()).toString()) }
+ )
+ }
+
+ companion object {
+ private const val KEY = "is_activated"
+ }
+}
diff --git a/src/com/android/customization/module/CustomizationInjector.kt b/src/com/android/customization/module/CustomizationInjector.kt
index 3cf8393..306ef04 100644
--- a/src/com/android/customization/module/CustomizationInjector.kt
+++ b/src/com/android/customization/module/CustomizationInjector.kt
@@ -15,12 +15,22 @@
*/
package com.android.customization.module
+import android.app.Activity
import android.content.Context
import androidx.fragment.app.FragmentActivity
import com.android.customization.model.theme.OverlayManagerCompat
import com.android.customization.model.theme.ThemeBundleProvider
import com.android.customization.model.theme.ThemeManager
+import com.android.customization.picker.clock.domain.interactor.ClockPickerInteractor
+import com.android.customization.picker.clock.ui.view.ClockViewFactory
+import com.android.customization.picker.clock.ui.viewmodel.ClockCarouselViewModel
+import com.android.customization.picker.clock.ui.viewmodel.ClockSectionViewModel
+import com.android.customization.picker.clock.ui.viewmodel.ClockSettingsViewModel
+import com.android.customization.picker.color.domain.interactor.ColorPickerInteractor
+import com.android.customization.picker.color.ui.viewmodel.ColorPickerViewModel
import com.android.customization.picker.quickaffordance.domain.interactor.KeyguardQuickAffordancePickerInteractor
+import com.android.systemui.shared.clocks.ClockRegistry
+import com.android.wallpaper.model.WallpaperColorsViewModel
import com.android.wallpaper.module.Injector
interface CustomizationInjector : Injector {
@@ -30,10 +40,35 @@
provider: ThemeBundleProvider,
activity: FragmentActivity,
overlayManagerCompat: OverlayManagerCompat,
- logger: ThemesUserEventLogger
+ logger: ThemesUserEventLogger,
): ThemeManager
fun getKeyguardQuickAffordancePickerInteractor(
- context: Context
+ context: Context,
): KeyguardQuickAffordancePickerInteractor
+
+ fun getClockRegistry(context: Context): ClockRegistry
+
+ fun getClockPickerInteractor(context: Context): ClockPickerInteractor
+
+ fun getClockSectionViewModel(context: Context): ClockSectionViewModel
+
+ fun getColorPickerInteractor(
+ context: Context,
+ wallpaperColorsViewModel: WallpaperColorsViewModel,
+ ): ColorPickerInteractor
+
+ fun getColorPickerViewModelFactory(
+ context: Context,
+ wallpaperColorsViewModel: WallpaperColorsViewModel,
+ ): ColorPickerViewModel.Factory
+
+ fun getClockCarouselViewModel(context: Context): ClockCarouselViewModel
+
+ fun getClockViewFactory(activity: Activity): ClockViewFactory
+
+ fun getClockSettingsViewModelFactory(
+ context: Context,
+ wallpaperColorsViewModel: WallpaperColorsViewModel,
+ ): ClockSettingsViewModel.Factory
}
diff --git a/src/com/android/customization/module/DefaultCustomizationSections.java b/src/com/android/customization/module/DefaultCustomizationSections.java
index c47a6e6..232e948 100644
--- a/src/com/android/customization/module/DefaultCustomizationSections.java
+++ b/src/com/android/customization/module/DefaultCustomizationSections.java
@@ -11,21 +11,36 @@
import com.android.customization.model.grid.GridOptionsManager;
import com.android.customization.model.grid.GridSectionController;
import com.android.customization.model.mode.DarkModeSectionController;
+import com.android.customization.model.mode.DarkModeSnapshotRestorer;
import com.android.customization.model.themedicon.ThemedIconSectionController;
import com.android.customization.model.themedicon.ThemedIconSwitchProvider;
+import com.android.customization.model.themedicon.domain.interactor.ThemedIconInteractor;
+import com.android.customization.model.themedicon.domain.interactor.ThemedIconSnapshotRestorer;
+import com.android.customization.picker.clock.ui.view.ClockViewFactory;
+import com.android.customization.picker.clock.ui.viewmodel.ClockCarouselViewModel;
+import com.android.customization.picker.color.ui.section.ColorSectionController2;
+import com.android.customization.picker.color.ui.viewmodel.ColorPickerViewModel;
+import com.android.customization.picker.notifications.ui.section.NotificationSectionController;
+import com.android.customization.picker.notifications.ui.viewmodel.NotificationSectionViewModel;
+import com.android.customization.picker.preview.ui.section.PreviewWithClockCarouselSectionController;
import com.android.customization.picker.quickaffordance.domain.interactor.KeyguardQuickAffordancePickerInteractor;
import com.android.customization.picker.quickaffordance.ui.section.KeyguardQuickAffordanceSectionController;
import com.android.customization.picker.quickaffordance.ui.viewmodel.KeyguardQuickAffordancePickerViewModel;
+import com.android.customization.picker.settings.ui.section.MoreSettingsSectionController;
+import com.android.wallpaper.config.BaseFlags;
import com.android.wallpaper.model.CustomizationSectionController;
import com.android.wallpaper.model.CustomizationSectionController.CustomizationSectionNavigationController;
import com.android.wallpaper.model.PermissionRequester;
import com.android.wallpaper.model.WallpaperColorsViewModel;
import com.android.wallpaper.model.WallpaperPreviewNavigator;
import com.android.wallpaper.model.WallpaperSectionController;
-import com.android.wallpaper.model.WorkspaceViewModel;
import com.android.wallpaper.module.CurrentWallpaperInfoFactory;
import com.android.wallpaper.module.CustomizationSections;
+import com.android.wallpaper.picker.customization.domain.interactor.WallpaperInteractor;
+import com.android.wallpaper.picker.customization.ui.section.ConnectedSectionController;
import com.android.wallpaper.picker.customization.ui.section.ScreenPreviewSectionController;
+import com.android.wallpaper.picker.customization.ui.section.WallpaperQuickSwitchSectionController;
+import com.android.wallpaper.picker.customization.ui.viewmodel.WallpaperQuickSwitchViewModel;
import com.android.wallpaper.util.DisplayUtils;
import java.util.ArrayList;
@@ -34,47 +49,100 @@
/** {@link CustomizationSections} for the customization picker. */
public final class DefaultCustomizationSections implements CustomizationSections {
+ private final ColorPickerViewModel.Factory mColorPickerViewModelFactory;
private final KeyguardQuickAffordancePickerInteractor mKeyguardQuickAffordancePickerInteractor;
private final KeyguardQuickAffordancePickerViewModel.Factory
mKeyguardQuickAffordancePickerViewModelFactory;
+ private final NotificationSectionViewModel.Factory mNotificationSectionViewModelFactory;
+ private final BaseFlags mFlags;
+ private final ClockCarouselViewModel mClockCarouselViewModel;
+ private final ClockViewFactory mClockViewFactory;
+ private final DarkModeSnapshotRestorer mDarkModeSnapshotRestorer;
+ private final ThemedIconSnapshotRestorer mThemedIconSnapshotRestorer;
+ private final ThemedIconInteractor mThemedIconInteractor;
public DefaultCustomizationSections(
+ ColorPickerViewModel.Factory colorPickerViewModelFactory,
KeyguardQuickAffordancePickerInteractor keyguardQuickAffordancePickerInteractor,
KeyguardQuickAffordancePickerViewModel.Factory
- keyguardQuickAffordancePickerViewModelFactory) {
+ keyguardQuickAffordancePickerViewModelFactory,
+ NotificationSectionViewModel.Factory notificationSectionViewModelFactory,
+ BaseFlags flags,
+ ClockCarouselViewModel clockCarouselViewModel,
+ ClockViewFactory clockViewFactory,
+ DarkModeSnapshotRestorer darkModeSnapshotRestorer,
+ ThemedIconSnapshotRestorer themedIconSnapshotRestorer,
+ ThemedIconInteractor themedIconInteractor) {
+ mColorPickerViewModelFactory = colorPickerViewModelFactory;
mKeyguardQuickAffordancePickerInteractor = keyguardQuickAffordancePickerInteractor;
mKeyguardQuickAffordancePickerViewModelFactory =
keyguardQuickAffordancePickerViewModelFactory;
+ mNotificationSectionViewModelFactory = notificationSectionViewModelFactory;
+ mFlags = flags;
+ mClockCarouselViewModel = clockCarouselViewModel;
+ mClockViewFactory = clockViewFactory;
+ mDarkModeSnapshotRestorer = darkModeSnapshotRestorer;
+ mThemedIconSnapshotRestorer = themedIconSnapshotRestorer;
+ mThemedIconInteractor = themedIconInteractor;
}
@Override
- public List<CustomizationSectionController<?>> getSectionControllersForScreen(
+ public List<CustomizationSectionController<?>> getRevampedUISectionControllersForScreen(
Screen screen,
FragmentActivity activity,
LifecycleOwner lifecycleOwner,
WallpaperColorsViewModel wallpaperColorsViewModel,
- WorkspaceViewModel workspaceViewModel,
PermissionRequester permissionRequester,
WallpaperPreviewNavigator wallpaperPreviewNavigator,
CustomizationSectionNavigationController sectionNavigationController,
@Nullable Bundle savedInstanceState,
CurrentWallpaperInfoFactory wallpaperInfoFactory,
- DisplayUtils displayUtils) {
+ DisplayUtils displayUtils,
+ WallpaperQuickSwitchViewModel wallpaperQuickSwitchViewModel,
+ WallpaperInteractor wallpaperInteractor) {
List<CustomizationSectionController<?>> sectionControllers = new ArrayList<>();
// Wallpaper section.
sectionControllers.add(
- new ScreenPreviewSectionController(
+ mFlags.isCustomClocksEnabled(activity)
+ ? new PreviewWithClockCarouselSectionController(
activity,
lifecycleOwner,
screen,
wallpaperInfoFactory,
wallpaperColorsViewModel,
- displayUtils));
+ displayUtils,
+ mClockCarouselViewModel,
+ mClockViewFactory,
+ sectionNavigationController,
+ wallpaperInteractor)
+ : new ScreenPreviewSectionController(
+ activity,
+ lifecycleOwner,
+ screen,
+ wallpaperInfoFactory,
+ wallpaperColorsViewModel,
+ displayUtils,
+ sectionNavigationController,
+ wallpaperInteractor));
- // Theme color section.
- sectionControllers.add(new ColorSectionController(
- activity, wallpaperColorsViewModel, lifecycleOwner, savedInstanceState));
+ sectionControllers.add(
+ new ConnectedSectionController(
+ // Theme color section.
+ new ColorSectionController2(
+ sectionNavigationController,
+ new ViewModelProvider(
+ activity,
+ mColorPickerViewModelFactory)
+ .get(ColorPickerViewModel.class),
+ lifecycleOwner),
+ // Wallpaper quick switch section.
+ new WallpaperQuickSwitchSectionController(
+ screen,
+ wallpaperQuickSwitchViewModel,
+ lifecycleOwner,
+ sectionNavigationController),
+ /* reverseOrderWhenHorizontal= */ true));
switch (screen) {
case LOCK_SCREEN:
@@ -88,21 +156,36 @@
mKeyguardQuickAffordancePickerViewModelFactory)
.get(KeyguardQuickAffordancePickerViewModel.class),
lifecycleOwner));
+
+ // Notifications section.
+ sectionControllers.add(
+ new NotificationSectionController(
+ new ViewModelProvider(
+ activity,
+ mNotificationSectionViewModelFactory)
+ .get(NotificationSectionViewModel.class),
+ lifecycleOwner));
+
+ // More settings section.
+ sectionControllers.add(new MoreSettingsSectionController());
break;
case HOME_SCREEN:
- // Dark/Light theme section.
- sectionControllers.add(new DarkModeSectionController(activity,
- lifecycleOwner.getLifecycle()));
-
// Themed app icon section.
- sectionControllers.add(new ThemedIconSectionController(
- ThemedIconSwitchProvider.getInstance(activity), workspaceViewModel,
- savedInstanceState));
+ sectionControllers.add(
+ new ThemedIconSectionController(
+ ThemedIconSwitchProvider.getInstance(activity),
+ mThemedIconInteractor,
+ savedInstanceState,
+ mThemedIconSnapshotRestorer));
// App grid section.
- sectionControllers.add(new GridSectionController(
- GridOptionsManager.getInstance(activity), sectionNavigationController));
+ sectionControllers.add(
+ new GridSectionController(
+ GridOptionsManager.getInstance(activity),
+ sectionNavigationController,
+ lifecycleOwner,
+ /* isRevampedUiEnabled= */ true));
break;
}
@@ -114,7 +197,6 @@
FragmentActivity activity,
LifecycleOwner lifecycleOwner,
WallpaperColorsViewModel wallpaperColorsViewModel,
- WorkspaceViewModel workspaceViewModel,
PermissionRequester permissionRequester,
WallpaperPreviewNavigator wallpaperPreviewNavigator,
CustomizationSectionNavigationController sectionNavigationController,
@@ -123,27 +205,42 @@
List<CustomizationSectionController<?>> sectionControllers = new ArrayList<>();
// Wallpaper section.
- sectionControllers.add(new WallpaperSectionController(
- activity, lifecycleOwner, permissionRequester, wallpaperColorsViewModel,
- workspaceViewModel, sectionNavigationController, wallpaperPreviewNavigator,
- savedInstanceState, displayUtils));
+ sectionControllers.add(
+ new WallpaperSectionController(
+ activity,
+ lifecycleOwner,
+ permissionRequester,
+ wallpaperColorsViewModel,
+ mThemedIconInteractor.isActivatedAsLiveData(),
+ sectionNavigationController,
+ wallpaperPreviewNavigator,
+ savedInstanceState,
+ displayUtils));
// Theme color section.
sectionControllers.add(new ColorSectionController(
activity, wallpaperColorsViewModel, lifecycleOwner, savedInstanceState));
// Dark/Light theme section.
- sectionControllers.add(new DarkModeSectionController(activity,
- lifecycleOwner.getLifecycle()));
+ sectionControllers.add(new DarkModeSectionController(
+ activity,
+ lifecycleOwner.getLifecycle(),
+ mDarkModeSnapshotRestorer));
// Themed app icon section.
sectionControllers.add(new ThemedIconSectionController(
- ThemedIconSwitchProvider.getInstance(activity), workspaceViewModel,
- savedInstanceState));
+ ThemedIconSwitchProvider.getInstance(activity),
+ mThemedIconInteractor,
+ savedInstanceState,
+ mThemedIconSnapshotRestorer));
// App grid section.
- sectionControllers.add(new GridSectionController(
- GridOptionsManager.getInstance(activity), sectionNavigationController));
+ sectionControllers.add(
+ new GridSectionController(
+ GridOptionsManager.getInstance(activity),
+ sectionNavigationController,
+ lifecycleOwner,
+ /* isRevampedUiEnabled= */ false));
return sectionControllers;
}
diff --git a/src/com/android/customization/module/StatsLogUserEventLogger.java b/src/com/android/customization/module/StatsLogUserEventLogger.java
index 2b6767b..9645454 100644
--- a/src/com/android/customization/module/StatsLogUserEventLogger.java
+++ b/src/com/android/customization/module/StatsLogUserEventLogger.java
@@ -144,7 +144,7 @@
final boolean isLockWallpaperSet = mWallpaperStatusChecker.isLockWallpaperSet(mContext);
final String homeCollectionId = mPreferences.getHomeWallpaperCollectionId();
final String homeRemoteId = mPreferences.getHomeWallpaperRemoteId();
- final String effects = mPreferences.getWallpaperEffects();
+ final String effects = mPreferences.getHomeWallpaperEffects();
String homeWallpaperId = TextUtils.isEmpty(homeRemoteId)
? mPreferences.getHomeWallpaperServiceName() : homeRemoteId;
String lockCollectionId = isLockWallpaperSet ? mPreferences.getLockWallpaperCollectionId()
diff --git a/src/com/android/customization/module/ThemePickerInjector.kt b/src/com/android/customization/module/ThemePickerInjector.kt
index b3f95d5..eb20037 100644
--- a/src/com/android/customization/module/ThemePickerInjector.kt
+++ b/src/com/android/customization/module/ThemePickerInjector.kt
@@ -16,22 +16,55 @@
package com.android.customization.module
import android.app.Activity
+import android.app.UiModeManager
import android.content.Context
import android.content.Intent
import android.net.Uri
import android.os.Bundle
+import android.text.TextUtils
+import androidx.activity.ComponentActivity
import androidx.fragment.app.Fragment
import androidx.fragment.app.FragmentActivity
+import androidx.lifecycle.ViewModelProvider
+import com.android.customization.model.color.ColorCustomizationManager
+import com.android.customization.model.color.ColorOptionsProvider
+import com.android.customization.model.grid.GridOptionsManager
+import com.android.customization.model.grid.data.repository.GridRepositoryImpl
+import com.android.customization.model.grid.domain.interactor.GridInteractor
+import com.android.customization.model.grid.domain.interactor.GridSnapshotRestorer
+import com.android.customization.model.grid.ui.viewmodel.GridScreenViewModel
+import com.android.customization.model.mode.DarkModeSnapshotRestorer
import com.android.customization.model.theme.OverlayManagerCompat
import com.android.customization.model.theme.ThemeBundleProvider
import com.android.customization.model.theme.ThemeManager
+import com.android.customization.model.themedicon.ThemedIconSwitchProvider
+import com.android.customization.model.themedicon.data.repository.ThemeIconRepository
+import com.android.customization.model.themedicon.domain.interactor.ThemedIconInteractor
+import com.android.customization.model.themedicon.domain.interactor.ThemedIconSnapshotRestorer
+import com.android.customization.picker.clock.data.repository.ClockPickerRepositoryImpl
+import com.android.customization.picker.clock.data.repository.ClockRegistryProvider
+import com.android.customization.picker.clock.domain.interactor.ClockPickerInteractor
+import com.android.customization.picker.clock.ui.view.ClockViewFactory
+import com.android.customization.picker.clock.ui.viewmodel.ClockCarouselViewModel
+import com.android.customization.picker.clock.ui.viewmodel.ClockSectionViewModel
+import com.android.customization.picker.clock.ui.viewmodel.ClockSettingsViewModel
+import com.android.customization.picker.color.data.repository.ColorPickerRepositoryImpl
+import com.android.customization.picker.color.domain.interactor.ColorPickerInteractor
+import com.android.customization.picker.color.domain.interactor.ColorPickerSnapshotRestorer
+import com.android.customization.picker.color.ui.viewmodel.ColorPickerViewModel
+import com.android.customization.picker.notifications.data.repository.NotificationsRepository
+import com.android.customization.picker.notifications.domain.interactor.NotificationsInteractor
+import com.android.customization.picker.notifications.domain.interactor.NotificationsSnapshotRestorer
+import com.android.customization.picker.notifications.ui.viewmodel.NotificationSectionViewModel
import com.android.customization.picker.quickaffordance.data.repository.KeyguardQuickAffordancePickerRepository
import com.android.customization.picker.quickaffordance.domain.interactor.KeyguardQuickAffordancePickerInteractor
import com.android.customization.picker.quickaffordance.domain.interactor.KeyguardQuickAffordanceSnapshotRestorer
import com.android.customization.picker.quickaffordance.ui.viewmodel.KeyguardQuickAffordancePickerViewModel
+import com.android.systemui.shared.clocks.ClockRegistry
import com.android.systemui.shared.customization.data.content.CustomizationProviderClient
import com.android.systemui.shared.customization.data.content.CustomizationProviderClientImpl
import com.android.wallpaper.model.LiveWallpaperInfo
+import com.android.wallpaper.model.WallpaperColorsViewModel
import com.android.wallpaper.model.WallpaperInfo
import com.android.wallpaper.module.CustomizationSections
import com.android.wallpaper.module.FragmentFactory
@@ -42,13 +75,20 @@
import com.android.wallpaper.picker.ImagePreviewFragment
import com.android.wallpaper.picker.LivePreviewFragment
import com.android.wallpaper.picker.PreviewFragment
+import com.android.wallpaper.picker.customization.data.content.WallpaperClientImpl
+import com.android.wallpaper.picker.customization.data.repository.WallpaperRepository
+import com.android.wallpaper.picker.customization.domain.interactor.WallpaperInteractor
import com.android.wallpaper.picker.undo.domain.interactor.SnapshotRestorer
-import kotlinx.coroutines.Dispatchers.IO
+import kotlinx.coroutines.DelicateCoroutinesApi
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.GlobalScope
+@OptIn(DelicateCoroutinesApi::class)
open class ThemePickerInjector : WallpaperPicker2Injector(), CustomizationInjector {
private var customizationSections: CustomizationSections? = null
private var userEventLogger: UserEventLogger? = null
private var prefs: WallpaperPreferences? = null
+ private var wallpaperInteractor: WallpaperInteractor? = null
private var keyguardQuickAffordancePickerInteractor: KeyguardQuickAffordancePickerInteractor? =
null
private var keyguardQuickAffordancePickerViewModelFactory:
@@ -58,12 +98,44 @@
private var fragmentFactory: FragmentFactory? = null
private var keyguardQuickAffordanceSnapshotRestorer: KeyguardQuickAffordanceSnapshotRestorer? =
null
+ private var notificationsSnapshotRestorer: NotificationsSnapshotRestorer? = null
+ private var clockRegistry: ClockRegistry? = null
+ private var clockPickerInteractor: ClockPickerInteractor? = null
+ private var clockSectionViewModel: ClockSectionViewModel? = null
+ private var clockCarouselViewModel: ClockCarouselViewModel? = null
+ private var clockViewFactory: ClockViewFactory? = null
+ private var notificationsInteractor: NotificationsInteractor? = null
+ private var notificationSectionViewModelFactory: NotificationSectionViewModel.Factory? = null
+ private var colorPickerInteractor: ColorPickerInteractor? = null
+ private var colorPickerViewModelFactory: ColorPickerViewModel.Factory? = null
+ private var colorPickerSnapshotRestorer: ColorPickerSnapshotRestorer? = null
+ private var colorCustomizationManager: ColorCustomizationManager? = null
+ private var darkModeSnapshotRestorer: DarkModeSnapshotRestorer? = null
+ private var themedIconSnapshotRestorer: ThemedIconSnapshotRestorer? = null
+ private var themedIconInteractor: ThemedIconInteractor? = null
+ private var clockSettingsViewModelFactory: ClockSettingsViewModel.Factory? = null
+ private var gridInteractor: GridInteractor? = null
+ private var gridSnapshotRestorer: GridSnapshotRestorer? = null
+ private var gridScreenViewModelFactory: GridScreenViewModel.Factory? = null
- override fun getCustomizationSections(activity: Activity): CustomizationSections {
+ override fun getCustomizationSections(activity: ComponentActivity): CustomizationSections {
return customizationSections
?: DefaultCustomizationSections(
+ getColorPickerViewModelFactory(
+ context = activity,
+ wallpaperColorsViewModel = getWallpaperColorsViewModel(),
+ ),
getKeyguardQuickAffordancePickerInteractor(activity),
- getKeyguardQuickAffordancePickerViewModelFactory(activity)
+ getKeyguardQuickAffordancePickerViewModelFactory(activity),
+ NotificationSectionViewModel.Factory(
+ interactor = getNotificationsInteractor(activity),
+ ),
+ getFlags(),
+ getClockCarouselViewModel(activity),
+ getClockViewFactory(activity),
+ getDarkModeSnapshotRestorer(activity),
+ getThemedIconSnapshotRestorer(activity),
+ getThemedIconInteractor(),
)
.also { customizationSections = it }
}
@@ -122,6 +194,13 @@
return super<WallpaperPicker2Injector>.getSnapshotRestorers(context).toMutableMap().apply {
this[KEY_QUICK_AFFORDANCE_SNAPSHOT_RESTORER] =
getKeyguardQuickAffordanceSnapshotRestorer(context)
+ this[KEY_WALLPAPER_SNAPSHOT_RESTORER] = getWallpaperSnapshotRestorer(context)
+ this[KEY_NOTIFICATIONS_SNAPSHOT_RESTORER] = getNotificationsSnapshotRestorer(context)
+ this[KEY_DARK_MODE_SNAPSHOT_RESTORER] = getDarkModeSnapshotRestorer(context)
+ this[KEY_THEMED_ICON_SNAPSHOT_RESTORER] = getThemedIconSnapshotRestorer(context)
+ this[KEY_APP_GRID_SNAPSHOT_RESTORER] = getGridSnapshotRestorer(context)
+ this[KEY_COLOR_PICKER_SNAPSHOT_RESTORER] =
+ getColorPickerSnapshotRestorer(context, getWallpaperColorsViewModel())
}
}
@@ -138,6 +217,25 @@
return ThemeManager(provider, activity, overlayManagerCompat, logger)
}
+ override fun getWallpaperInteractor(context: Context): WallpaperInteractor {
+ return wallpaperInteractor
+ ?: WallpaperInteractor(
+ repository =
+ WallpaperRepository(
+ scope = GlobalScope,
+ client = WallpaperClientImpl(context = context),
+ backgroundDispatcher = Dispatchers.IO,
+ ),
+ shouldHandleReload = {
+ TextUtils.equals(
+ getColorCustomizationManager(context).currentColorSource,
+ ColorOptionsProvider.COLOR_SOURCE_PRESET
+ )
+ }
+ )
+ .also { wallpaperInteractor = it }
+ }
+
override fun getKeyguardQuickAffordancePickerInteractor(
context: Context
): KeyguardQuickAffordancePickerInteractor {
@@ -154,32 +252,45 @@
?: KeyguardQuickAffordancePickerViewModel.Factory(
context,
getKeyguardQuickAffordancePickerInteractor(context),
- getUndoInteractor(context),
getCurrentWallpaperInfoFactory(context),
- )
+ ) { intent ->
+ context.startActivity(intent)
+ }
.also { keyguardQuickAffordancePickerViewModelFactory = it }
}
+ fun getNotificationSectionViewModelFactory(
+ context: Context,
+ ): NotificationSectionViewModel.Factory {
+ return notificationSectionViewModelFactory
+ ?: NotificationSectionViewModel.Factory(
+ interactor = getNotificationsInteractor(context),
+ )
+ .also { notificationSectionViewModelFactory = it }
+ }
+
private fun getKeyguardQuickAffordancePickerInteractorImpl(
context: Context
): KeyguardQuickAffordancePickerInteractor {
val client = getKeyguardQuickAffordancePickerProviderClient(context)
return KeyguardQuickAffordancePickerInteractor(
- KeyguardQuickAffordancePickerRepository(client, IO),
+ KeyguardQuickAffordancePickerRepository(client, Dispatchers.IO),
client
- ) { getKeyguardQuickAffordanceSnapshotRestorer(context) }
+ ) {
+ getKeyguardQuickAffordanceSnapshotRestorer(context)
+ }
}
protected fun getKeyguardQuickAffordancePickerProviderClient(
context: Context
): CustomizationProviderClient {
return customizationProviderClient
- ?: CustomizationProviderClientImpl(context, IO).also {
+ ?: CustomizationProviderClientImpl(context, Dispatchers.IO).also {
customizationProviderClient = it
}
}
- protected fun getKeyguardQuickAffordanceSnapshotRestorer(
+ private fun getKeyguardQuickAffordanceSnapshotRestorer(
context: Context
): KeyguardQuickAffordanceSnapshotRestorer {
return keyguardQuickAffordanceSnapshotRestorer
@@ -190,16 +301,238 @@
.also { keyguardQuickAffordanceSnapshotRestorer = it }
}
+ private fun getNotificationsSnapshotRestorer(context: Context): NotificationsSnapshotRestorer {
+ return notificationsSnapshotRestorer
+ ?: NotificationsSnapshotRestorer(
+ interactor =
+ getNotificationsInteractor(
+ context = context,
+ ),
+ )
+ .also { notificationsSnapshotRestorer = it }
+ }
+
+ override fun getClockRegistry(context: Context): ClockRegistry {
+ return clockRegistry
+ ?: ClockRegistryProvider(
+ context = context,
+ coroutineScope = GlobalScope,
+ mainDispatcher = Dispatchers.Main,
+ backgroundDispatcher = Dispatchers.IO,
+ )
+ .get()
+ .also { clockRegistry = it }
+ }
+
+ override fun getClockPickerInteractor(
+ context: Context,
+ ): ClockPickerInteractor {
+ return clockPickerInteractor
+ ?: ClockPickerInteractor(
+ ClockPickerRepositoryImpl(
+ secureSettingsRepository = getSecureSettingsRepository(context),
+ registry = getClockRegistry(context),
+ scope = GlobalScope,
+ ),
+ )
+ .also { clockPickerInteractor = it }
+ }
+
+ override fun getClockSectionViewModel(context: Context): ClockSectionViewModel {
+ return clockSectionViewModel
+ ?: ClockSectionViewModel(context, getClockPickerInteractor(context)).also {
+ clockSectionViewModel = it
+ }
+ }
+
+ override fun getClockCarouselViewModel(context: Context): ClockCarouselViewModel {
+ return clockCarouselViewModel
+ ?: ClockCarouselViewModel(getClockPickerInteractor(context)).also {
+ clockCarouselViewModel = it
+ }
+ }
+
+ override fun getClockViewFactory(activity: Activity): ClockViewFactory {
+ return clockViewFactory
+ ?: ClockViewFactory(activity, getClockRegistry(activity)).also { clockViewFactory = it }
+ }
+
+ protected fun getNotificationsInteractor(
+ context: Context,
+ ): NotificationsInteractor {
+ return notificationsInteractor
+ ?: NotificationsInteractor(
+ repository =
+ NotificationsRepository(
+ scope = GlobalScope,
+ backgroundDispatcher = Dispatchers.IO,
+ secureSettingsRepository = getSecureSettingsRepository(context),
+ ),
+ snapshotRestorer = { getNotificationsSnapshotRestorer(context) },
+ )
+ .also { notificationsInteractor = it }
+ }
+
+ override fun getColorPickerInteractor(
+ context: Context,
+ wallpaperColorsViewModel: WallpaperColorsViewModel,
+ ): ColorPickerInteractor {
+ return colorPickerInteractor
+ ?: ColorPickerInteractor(
+ repository =
+ ColorPickerRepositoryImpl(
+ wallpaperColorsViewModel,
+ getColorCustomizationManager(context)
+ ),
+ snapshotRestorer = {
+ getColorPickerSnapshotRestorer(context, wallpaperColorsViewModel)
+ }
+ )
+ .also { colorPickerInteractor = it }
+ }
+
+ override fun getColorPickerViewModelFactory(
+ context: Context,
+ wallpaperColorsViewModel: WallpaperColorsViewModel,
+ ): ColorPickerViewModel.Factory {
+ return colorPickerViewModelFactory
+ ?: ColorPickerViewModel.Factory(
+ context,
+ getColorPickerInteractor(context, wallpaperColorsViewModel),
+ )
+ .also { colorPickerViewModelFactory = it }
+ }
+
+ private fun getColorPickerSnapshotRestorer(
+ context: Context,
+ wallpaperColorsViewModel: WallpaperColorsViewModel,
+ ): ColorPickerSnapshotRestorer {
+ return colorPickerSnapshotRestorer
+ ?: ColorPickerSnapshotRestorer(
+ getColorPickerInteractor(context, wallpaperColorsViewModel)
+ )
+ .also { colorPickerSnapshotRestorer = it }
+ }
+
+ private fun getColorCustomizationManager(context: Context): ColorCustomizationManager {
+ return colorCustomizationManager
+ ?: ColorCustomizationManager.getInstance(context, OverlayManagerCompat(context)).also {
+ colorCustomizationManager = it
+ }
+ }
+
+ fun getDarkModeSnapshotRestorer(
+ context: Context,
+ ): DarkModeSnapshotRestorer {
+ return darkModeSnapshotRestorer
+ ?: DarkModeSnapshotRestorer(
+ context = context,
+ manager = context.getSystemService(Context.UI_MODE_SERVICE) as UiModeManager,
+ backgroundDispatcher = Dispatchers.IO,
+ )
+ .also { darkModeSnapshotRestorer = it }
+ }
+
+ protected fun getThemedIconSnapshotRestorer(
+ context: Context,
+ ): ThemedIconSnapshotRestorer {
+ val optionProvider = ThemedIconSwitchProvider.getInstance(context)
+ return themedIconSnapshotRestorer
+ ?: ThemedIconSnapshotRestorer(
+ isActivated = { optionProvider.isThemedIconEnabled },
+ setActivated = { isActivated ->
+ optionProvider.isThemedIconEnabled = isActivated
+ },
+ interactor = getThemedIconInteractor(),
+ )
+ .also { themedIconSnapshotRestorer = it }
+ }
+
+ protected fun getThemedIconInteractor(): ThemedIconInteractor {
+ return themedIconInteractor
+ ?: ThemedIconInteractor(
+ repository = ThemeIconRepository(),
+ )
+ .also { themedIconInteractor = it }
+ }
+
+ override fun getClockSettingsViewModelFactory(
+ context: Context,
+ wallpaperColorsViewModel: WallpaperColorsViewModel,
+ ): ClockSettingsViewModel.Factory {
+ return clockSettingsViewModelFactory
+ ?: ClockSettingsViewModel.Factory(
+ context,
+ getClockPickerInteractor(context),
+ getColorPickerInteractor(
+ context,
+ wallpaperColorsViewModel,
+ ),
+ )
+ .also { clockSettingsViewModelFactory = it }
+ }
+
+ fun getGridScreenViewModelFactory(
+ context: Context,
+ ): ViewModelProvider.Factory {
+ return gridScreenViewModelFactory
+ ?: GridScreenViewModel.Factory(
+ context = context,
+ interactor = getGridInteractor(context),
+ )
+ .also { gridScreenViewModelFactory = it }
+ }
+
+ private fun getGridInteractor(
+ context: Context,
+ ): GridInteractor {
+ return gridInteractor
+ ?: GridInteractor(
+ applicationScope = GlobalScope,
+ repository =
+ GridRepositoryImpl(
+ applicationScope = GlobalScope,
+ manager = GridOptionsManager.getInstance(context),
+ backgroundDispatcher = Dispatchers.IO,
+ ),
+ snapshotRestorer = { getGridSnapshotRestorer(context) },
+ )
+ .also { gridInteractor = it }
+ }
+
+ private fun getGridSnapshotRestorer(
+ context: Context,
+ ): GridSnapshotRestorer {
+ return gridSnapshotRestorer
+ ?: GridSnapshotRestorer(
+ interactor = getGridInteractor(context),
+ )
+ .also { gridSnapshotRestorer = it }
+ }
+
companion object {
@JvmStatic
private val KEY_QUICK_AFFORDANCE_SNAPSHOT_RESTORER =
WallpaperPicker2Injector.MIN_SNAPSHOT_RESTORER_KEY
+ @JvmStatic
+ private val KEY_WALLPAPER_SNAPSHOT_RESTORER = KEY_QUICK_AFFORDANCE_SNAPSHOT_RESTORER + 1
+ @JvmStatic
+ private val KEY_NOTIFICATIONS_SNAPSHOT_RESTORER = KEY_WALLPAPER_SNAPSHOT_RESTORER + 1
+ @JvmStatic
+ private val KEY_DARK_MODE_SNAPSHOT_RESTORER = KEY_NOTIFICATIONS_SNAPSHOT_RESTORER + 1
+ @JvmStatic
+ private val KEY_THEMED_ICON_SNAPSHOT_RESTORER = KEY_DARK_MODE_SNAPSHOT_RESTORER + 1
+ @JvmStatic
+ private val KEY_APP_GRID_SNAPSHOT_RESTORER = KEY_THEMED_ICON_SNAPSHOT_RESTORER + 1
+ @JvmStatic
+ private val KEY_COLOR_PICKER_SNAPSHOT_RESTORER = KEY_APP_GRID_SNAPSHOT_RESTORER + 1
/**
* When this injector is overridden, this is the minimal value that should be used by
* restorers returns in [getSnapshotRestorers].
+ *
+ * It should always be greater than the biggest restorer key.
*/
- @JvmStatic
- protected val MIN_SNAPSHOT_RESTORER_KEY = KEY_QUICK_AFFORDANCE_SNAPSHOT_RESTORER + 1
+ @JvmStatic protected val MIN_SNAPSHOT_RESTORER_KEY = KEY_COLOR_PICKER_SNAPSHOT_RESTORER + 1
}
}
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/WallpaperPreviewer.java b/src/com/android/customization/picker/WallpaperPreviewer.java
index 354eec2..1b9ea9f 100644
--- a/src/com/android/customization/picker/WallpaperPreviewer.java
+++ b/src/com/android/customization/picker/WallpaperPreviewer.java
@@ -19,6 +19,8 @@
import android.app.WallpaperColors;
import android.content.Intent;
import android.graphics.Rect;
+import android.graphics.RenderEffect;
+import android.graphics.Shader.TileMode;
import android.service.wallpaper.WallpaperService;
import android.view.Surface;
import android.view.SurfaceView;
@@ -38,6 +40,7 @@
import com.android.wallpaper.util.ResourceUtils;
import com.android.wallpaper.util.ScreenSizeCalculator;
import com.android.wallpaper.util.SizeCalculator;
+import com.android.wallpaper.util.VideoWallpaperUtils;
import com.android.wallpaper.util.WallpaperConnection;
import com.android.wallpaper.util.WallpaperConnection.WallpaperConnectionListener;
import com.android.wallpaper.util.WallpaperSurfaceCallback;
@@ -53,6 +56,7 @@
private final Activity mActivity;
private final ImageView mHomePreview;
private final SurfaceView mWallpaperSurface;
+ @Nullable private final ImageView mFadeInScrim;
private WallpaperSurfaceCallback mWallpaperSurfaceCallback;
private WallpaperInfo mWallpaper;
@@ -67,11 +71,17 @@
public WallpaperPreviewer(Lifecycle lifecycle, Activity activity, ImageView homePreview,
SurfaceView wallpaperSurface) {
+ this(lifecycle, activity, homePreview, wallpaperSurface, null);
+ }
+
+ public WallpaperPreviewer(Lifecycle lifecycle, Activity activity, ImageView homePreview,
+ SurfaceView wallpaperSurface, @Nullable ImageView fadeInScrim) {
lifecycle.addObserver(this);
mActivity = activity;
mHomePreview = homePreview;
mWallpaperSurface = wallpaperSurface;
+ mFadeInScrim = fadeInScrim;
mWallpaperSurfaceCallback = new WallpaperSurfaceCallback(activity, mHomePreview,
mWallpaperSurface, this::setUpWallpaperPreview);
mWallpaperSurface.setZOrderMediaOverlay(true);
@@ -139,6 +149,11 @@
@Nullable WallpaperColorsListener listener) {
mWallpaper = wallpaperInfo;
mWallpaperColorsListener = listener;
+ if (mFadeInScrim != null && VideoWallpaperUtils.needsFadeIn(wallpaperInfo)) {
+ mFadeInScrim.animate().cancel();
+ mFadeInScrim.setAlpha(1f);
+ mFadeInScrim.setVisibility(View.VISIBLE);
+ }
setUpWallpaperPreview();
}
@@ -157,10 +172,16 @@
mActivity, android.R.attr.colorSecondary),
/* offsetToStart= */ true);
if (mWallpaper instanceof LiveWallpaperInfo) {
+ ImageView preview = homeImageWallpaper;
+ if (VideoWallpaperUtils.needsFadeIn(mWallpaper) && mFadeInScrim != null) {
+ preview = mFadeInScrim;
+ preview.setRenderEffect(
+ RenderEffect.createBlurEffect(150f, 150f, TileMode.CLAMP));
+ }
mWallpaper.getThumbAsset(mActivity.getApplicationContext())
.loadPreviewImage(
mActivity,
- homeImageWallpaper,
+ preview,
ResourceUtils.getColorAttr(
mActivity, android.R.attr.colorSecondary),
/* offsetToStart= */ true);
@@ -209,6 +230,17 @@
mWallpaperColorsListener.onWallpaperColorsChanged(colors);
}
}
+
+ @Override
+ public void onEngineShown() {
+ if (mFadeInScrim != null && VideoWallpaperUtils.needsFadeIn(
+ homeWallpaper)) {
+ mFadeInScrim.animate().alpha(0.0f)
+ .setDuration(VideoWallpaperUtils.TRANSITION_MILLIS)
+ .withEndAction(
+ () -> mFadeInScrim.setVisibility(View.INVISIBLE));
+ }
+ }
}, mWallpaperSurface);
mWallpaperConnection.setVisibility(true);
diff --git a/src/com/android/customization/picker/clock/ClockCustomDemoFragment.kt b/src/com/android/customization/picker/clock/ClockCustomDemoFragment.kt
deleted file mode 100644
index 8648dca..0000000
--- a/src/com/android/customization/picker/clock/ClockCustomDemoFragment.kt
+++ /dev/null
@@ -1,191 +0,0 @@
-package com.android.customization.picker.clock
-
-import android.app.NotificationManager
-import android.content.ComponentName
-import android.content.Context
-import android.os.Bundle
-import android.os.Handler
-import android.os.UserHandle
-import android.view.ContextThemeWrapper
-import android.view.LayoutInflater
-import android.view.View
-import android.view.ViewGroup
-import android.view.ViewGroup.LayoutParams.MATCH_PARENT
-import android.view.ViewGroup.LayoutParams.WRAP_CONTENT
-import android.widget.FrameLayout
-import android.widget.TextView
-import androidx.core.view.setPadding
-import androidx.recyclerview.widget.LinearLayoutManager
-import androidx.recyclerview.widget.RecyclerView
-import com.android.internal.annotations.VisibleForTesting
-import com.android.systemui.plugins.ClockMetadata
-import com.android.systemui.plugins.ClockProviderPlugin
-import com.android.systemui.plugins.Plugin
-import com.android.systemui.plugins.PluginListener
-import com.android.systemui.plugins.PluginManager
-import com.android.systemui.shared.clocks.ClockRegistry
-import com.android.systemui.shared.clocks.DefaultClockProvider
-import com.android.systemui.shared.plugins.PluginActionManager
-import com.android.systemui.shared.plugins.PluginEnabler
-import com.android.systemui.shared.plugins.PluginEnabler.ENABLED
-import com.android.systemui.shared.plugins.PluginInstance
-import com.android.systemui.shared.plugins.PluginManagerImpl
-import com.android.systemui.shared.plugins.PluginPrefs
-import com.android.systemui.shared.system.UncaughtExceptionPreHandlerManager_Factory
-import com.android.wallpaper.R
-import com.android.wallpaper.picker.AppbarFragment
-import java.util.concurrent.Executors
-
-private val TAG = ClockCustomDemoFragment::class.simpleName
-
-class ClockCustomDemoFragment : AppbarFragment() {
- @VisibleForTesting lateinit var clockRegistry: ClockRegistry
- val isDebugDevice = true
- val privilegedPlugins = listOf<String>()
- val action = ClockProviderPlugin.ACTION
- lateinit var view: ViewGroup
- @VisibleForTesting lateinit var recyclerView: RecyclerView
- lateinit var pluginManager: PluginManager
- @VisibleForTesting
- val pluginListener =
- object : PluginListener<ClockProviderPlugin> {
- override fun onPluginConnected(plugin: ClockProviderPlugin, context: Context) {
- val listInUse = clockRegistry.getClocks().filter { "NOT_IN_USE" !in it.clockId }
- recyclerView.adapter = ClockRecyclerAdapter(listInUse, context, clockRegistry)
- }
- }
-
- override fun onAttach(context: Context) {
- super.onAttach(context)
- val defaultClockProvider =
- DefaultClockProvider(context, LayoutInflater.from(context), context.resources)
- pluginManager = createPluginManager(context)
- clockRegistry =
- ClockRegistry(
- context,
- pluginManager,
- Handler.getMain(),
- isEnabled = true,
- userHandle = UserHandle.USER_OWNER,
- defaultClockProvider
- )
- pluginManager.addPluginListener(pluginListener, ClockProviderPlugin::class.java, true)
- }
-
- override fun onCreateView(
- inflater: LayoutInflater,
- container: ViewGroup?,
- savedInstanceState: Bundle?
- ): View {
- val view = inflater.inflate(R.layout.fragment_clock_custom_picker_demo, container, false)
- setUpToolbar(view)
- return view
- }
-
- override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
- recyclerView = view.requireViewById(R.id.clock_preview_card_list_demo)
- recyclerView.layoutManager = LinearLayoutManager(context, RecyclerView.VERTICAL, false)
- super.onViewCreated(view, savedInstanceState)
- }
-
- override fun getDefaultTitle(): CharSequence {
- return getString(R.string.clock_title)
- }
-
- private fun createPluginManager(context: Context): PluginManager {
- val instanceFactory =
- PluginInstance.Factory(
- this::class.java.classLoader,
- PluginInstance.InstanceFactory<Plugin>(),
- PluginInstance.VersionChecker(),
- privilegedPlugins,
- isDebugDevice
- )
-
- /*
- * let SystemUI handle plugin, in this class assume plugins are enabled
- */
- val pluginEnabler =
- object : PluginEnabler {
- override fun setEnabled(component: ComponentName) {}
-
- override fun setDisabled(
- component: ComponentName,
- @PluginEnabler.DisableReason reason: Int
- ) {}
-
- override fun isEnabled(component: ComponentName): Boolean {
- return true
- }
-
- @PluginEnabler.DisableReason
- override fun getDisableReason(componentName: ComponentName): Int {
- return ENABLED
- }
- }
-
- val pluginActionManager =
- PluginActionManager.Factory(
- context,
- context.packageManager,
- context.mainExecutor,
- Executors.newSingleThreadExecutor(),
- context.getSystemService(NotificationManager::class.java),
- pluginEnabler,
- privilegedPlugins,
- instanceFactory
- )
- return PluginManagerImpl(
- context,
- pluginActionManager,
- isDebugDevice,
- uncaughtExceptionPreHandlerManager,
- pluginEnabler,
- PluginPrefs(context),
- listOf()
- )
- }
-
- companion object {
- private val uncaughtExceptionPreHandlerManager =
- UncaughtExceptionPreHandlerManager_Factory.create().get()
- }
-
- internal class ClockRecyclerAdapter(
- val list: List<ClockMetadata>,
- val context: Context,
- val clockRegistry: ClockRegistry
- ) : RecyclerView.Adapter<ClockRecyclerAdapter.ViewHolder>() {
- class ViewHolder(val view: View, val textView: TextView, val onItemClicked: (Int) -> Unit) :
- RecyclerView.ViewHolder(view) {
- init {
- itemView.setOnClickListener { onItemClicked(absoluteAdapterPosition) }
- }
- }
-
- override fun onCreateViewHolder(viewGroup: ViewGroup, viewType: Int): ViewHolder {
- val rootView = FrameLayout(viewGroup.context)
- val textView =
- TextView(ContextThemeWrapper(viewGroup.context, R.style.SectionTitleTextStyle))
- textView.setPadding(ITEM_PADDING)
- rootView.addView(textView)
- val lp = RecyclerView.LayoutParams(MATCH_PARENT, WRAP_CONTENT)
- rootView.setLayoutParams(lp)
- return ViewHolder(
- rootView,
- textView,
- { clockRegistry.currentClockId = list[it].clockId }
- )
- }
-
- override fun onBindViewHolder(viewHolder: ViewHolder, position: Int) {
- viewHolder.textView.text = list[position].name
- }
-
- override fun getItemCount() = list.size
-
- companion object {
- val ITEM_PADDING = 40
- }
- }
-}
diff --git a/src/com/android/customization/picker/clock/ClockCustomFragment.java b/src/com/android/customization/picker/clock/ClockCustomFragment.java
deleted file mode 100644
index 56860fe..0000000
--- a/src/com/android/customization/picker/clock/ClockCustomFragment.java
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Copyright (C) 2022 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;
-
-import static com.android.wallpaper.widget.BottomActionBar.BottomAction.APPLY;
-import static com.android.wallpaper.widget.BottomActionBar.BottomAction.INFORMATION;
-
-import android.os.Bundle;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.recyclerview.widget.RecyclerView;
-
-import com.android.customization.model.clock.custom.ClockCustomManager;
-import com.android.customization.model.clock.custom.ClockOption;
-import com.android.customization.widget.OptionSelectorController;
-import com.android.wallpaper.R;
-import com.android.wallpaper.picker.AppbarFragment;
-import com.android.wallpaper.widget.BottomActionBar;
-
-import com.google.common.collect.Lists;
-
-/**
- * Fragment that contains the main UI for selecting and applying a custom clock.
- */
-public class ClockCustomFragment extends AppbarFragment {
-
- OptionSelectorController<ClockOption> mClockSelectorController;
-
- @Nullable
- @Override
- public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
- @Nullable Bundle savedInstanceState) {
- View view = inflater.inflate(R.layout.fragment_clock_custom_picker, container, false);
-
- setUpToolbar(view);
-
- RecyclerView clockPreviewCardList = view.requireViewById(R.id.clock_preview_card_list);
-
- mClockSelectorController = new OptionSelectorController<>(clockPreviewCardList,
- Lists.newArrayList(new ClockOption(), new ClockOption(), new ClockOption(),
- new ClockOption(), new ClockOption()), false,
- OptionSelectorController.CheckmarkStyle.CENTER_CHANGE_COLOR_WHEN_NOT_SELECTED);
- mClockSelectorController.initOptions(new ClockCustomManager());
-
- return view;
- }
-
- @Override
- public CharSequence getDefaultTitle() {
- return getString(R.string.clock_title);
- }
-
- @Override
- protected void onBottomActionBarReady(BottomActionBar bottomActionBar) {
- super.onBottomActionBarReady(bottomActionBar);
- bottomActionBar.showActionsOnly(INFORMATION, APPLY);
- bottomActionBar.show();
- }
-}
diff --git a/src/com/android/customization/picker/clock/ClockFacePickerActivity.java b/src/com/android/customization/picker/clock/ClockFacePickerActivity.java
deleted file mode 100644
index 5e51234..0000000
--- a/src/com/android/customization/picker/clock/ClockFacePickerActivity.java
+++ /dev/null
@@ -1,82 +0,0 @@
-/*
- * Copyright (C) 2019 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;
-
-import android.content.Intent;
-import android.os.Bundle;
-import androidx.fragment.app.FragmentActivity;
-import androidx.fragment.app.FragmentManager;
-import androidx.fragment.app.FragmentTransaction;
-import com.android.customization.model.clock.BaseClockManager;
-import com.android.customization.model.clock.Clockface;
-import com.android.customization.model.clock.ContentProviderClockProvider;
-import com.android.customization.picker.clock.ClockFragment.ClockFragmentHost;
-import com.android.wallpaper.R;
-
-/**
- * Activity allowing for the clock face picker to be linked to from other setup flows.
- *
- * This should be used with startActivityForResult. The resulting intent contains an extra
- * "clock_face_name" with the id of the picked clock face.
- */
-public class ClockFacePickerActivity extends FragmentActivity implements ClockFragmentHost {
-
- private static final String EXTRA_CLOCK_FACE_NAME = "clock_face_name";
-
- private BaseClockManager mClockManager;
-
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_clock_face_picker);
-
- // Creating a class that overrides {@link ClockManager#apply} to return the clock id to the
- // calling activity instead of putting the value into settings.
- //
- mClockManager = new BaseClockManager(
- new ContentProviderClockProvider(ClockFacePickerActivity.this)) {
-
- @Override
- protected void handleApply(Clockface option, Callback callback) {
- Intent result = new Intent();
- result.putExtra(EXTRA_CLOCK_FACE_NAME, option.getId());
- setResult(RESULT_OK, result);
- callback.onSuccess();
- finish();
- }
-
- @Override
- protected String lookUpCurrentClock() {
- return getIntent().getStringExtra(EXTRA_CLOCK_FACE_NAME);
- }
- };
- if (!mClockManager.isAvailable()) {
- finish();
- } else {
- final FragmentManager fm = getSupportFragmentManager();
- final FragmentTransaction fragmentTransaction = fm.beginTransaction();
- final ClockFragment clockFragment = ClockFragment.newInstance(
- getString(R.string.clock_title));
- fragmentTransaction.replace(R.id.fragment_container, clockFragment);
- fragmentTransaction.commitNow();
- }
- }
-
- @Override
- public BaseClockManager getClockManager() {
- return mClockManager;
- }
-}
diff --git a/src/com/android/customization/picker/clock/ClockFragment.java b/src/com/android/customization/picker/clock/ClockFragment.java
deleted file mode 100644
index bc02ae3..0000000
--- a/src/com/android/customization/picker/clock/ClockFragment.java
+++ /dev/null
@@ -1,209 +0,0 @@
-/*
- * Copyright (C) 2019 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;
-
-import android.app.Activity;
-import android.content.Context;
-import android.content.res.Resources;
-import android.os.Bundle;
-import android.util.Log;
-import android.view.LayoutInflater;
-import android.view.View;
-import android.view.ViewGroup;
-import android.widget.ImageView;
-import android.widget.Toast;
-
-import androidx.annotation.NonNull;
-import androidx.annotation.Nullable;
-import androidx.core.widget.ContentLoadingProgressBar;
-import androidx.recyclerview.widget.RecyclerView;
-
-import com.android.customization.model.CustomizationManager.Callback;
-import com.android.customization.model.CustomizationManager.OptionsFetchedListener;
-import com.android.customization.model.clock.BaseClockManager;
-import com.android.customization.model.clock.Clockface;
-import com.android.customization.module.ThemesUserEventLogger;
-import com.android.customization.picker.BasePreviewAdapter;
-import com.android.customization.picker.BasePreviewAdapter.PreviewPage;
-import com.android.customization.widget.OptionSelectorController;
-import com.android.wallpaper.R;
-import com.android.wallpaper.asset.Asset;
-import com.android.wallpaper.module.InjectorProvider;
-import com.android.wallpaper.picker.AppbarFragment;
-import com.android.wallpaper.widget.PreviewPager;
-
-import java.util.List;
-
-/**
- * Fragment that contains the main UI for selecting and applying a Clockface.
- */
-public class ClockFragment extends AppbarFragment {
-
- private static final String TAG = "ClockFragment";
-
- /**
- * Interface to be implemented by an Activity hosting a {@link ClockFragment}
- */
- public interface ClockFragmentHost {
- BaseClockManager getClockManager();
- }
-
- public static ClockFragment newInstance(CharSequence title) {
- ClockFragment fragment = new ClockFragment();
- fragment.setArguments(AppbarFragment.createArguments(title));
- return fragment;
- }
-
- private RecyclerView mOptionsContainer;
- private OptionSelectorController<Clockface> mOptionsController;
- private Clockface mSelectedOption;
- private BaseClockManager mClockManager;
- private PreviewPager mPreviewPager;
- private ContentLoadingProgressBar mLoading;
- private View mContent;
- private View mError;
- private ThemesUserEventLogger mEventLogger;
-
- @Override
- public void onAttach(Context context) {
- super.onAttach(context);
- mClockManager = ((ClockFragmentHost) context).getClockManager();
- mEventLogger = (ThemesUserEventLogger)
- InjectorProvider.getInjector().getUserEventLogger(context);
- }
-
- @Nullable
- @Override
- public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
- @Nullable Bundle savedInstanceState) {
- View view = inflater.inflate(
- R.layout.fragment_clock_picker, container, /* attachToRoot */ false);
- setUpToolbar(view);
- mContent = view.findViewById(R.id.content_section);
- mPreviewPager = view.findViewById(R.id.clock_preview_pager);
- mOptionsContainer = view.findViewById(R.id.options_container);
- mLoading = view.findViewById(R.id.loading_indicator);
- mError = view.findViewById(R.id.error_section);
- setUpOptions();
- view.findViewById(R.id.apply_button).setOnClickListener(v -> {
- mClockManager.apply(mSelectedOption, new Callback() {
- @Override
- public void onSuccess() {
- mOptionsController.setAppliedOption(mSelectedOption);
- Toast.makeText(getContext(), R.string.applied_clock_msg,
- Toast.LENGTH_SHORT).show();
- }
-
- @Override
- public void onError(@Nullable Throwable throwable) {
- if (throwable != null) {
- Log.e(TAG, "Error loading clockfaces", throwable);
- }
- //TODO(santie): handle
- }
- });
-
- });
- return view;
- }
-
- private void createAdapter() {
- mPreviewPager.setAdapter(new ClockPreviewAdapter(getActivity(), mSelectedOption));
- }
-
- private void setUpOptions() {
- hideError();
- mLoading.show();
- mClockManager.fetchOptions(new OptionsFetchedListener<Clockface>() {
- @Override
- public void onOptionsLoaded(List<Clockface> options) {
- mLoading.hide();
- mOptionsController = new OptionSelectorController<>(mOptionsContainer, options);
-
- mOptionsController.addListener(selected -> {
- mSelectedOption = (Clockface) selected;
- mEventLogger.logClockSelected(mSelectedOption);
- createAdapter();
- });
- mOptionsController.initOptions(mClockManager);
- for (Clockface option : options) {
- if (option.isActive(mClockManager)) {
- mSelectedOption = option;
- }
- }
- // For development only, as there should always be a grid set.
- if (mSelectedOption == null) {
- mSelectedOption = options.get(0);
- }
- createAdapter();
- }
- @Override
- public void onError(@Nullable Throwable throwable) {
- if (throwable != null) {
- Log.e(TAG, "Error loading clockfaces", throwable);
- }
- showError();
- }
- }, false);
- }
-
- private void hideError() {
- mContent.setVisibility(View.VISIBLE);
- mError.setVisibility(View.GONE);
- }
-
- private void showError() {
- mLoading.hide();
- mContent.setVisibility(View.GONE);
- mError.setVisibility(View.VISIBLE);
- }
-
- private static class ClockfacePreviewPage extends PreviewPage {
-
- private final Asset mPreviewAsset;
-
- public ClockfacePreviewPage(String title, Activity activity, Asset previewAsset) {
- super(title, activity);
- mPreviewAsset = previewAsset;
- }
-
- @Override
- public void bindPreviewContent() {
- ImageView previewImage = card.findViewById(R.id.clock_preview_image);
- Context context = previewImage.getContext();
- Resources res = previewImage.getResources();
- mPreviewAsset.loadDrawableWithTransition(context, previewImage,
- 100 /* transitionDurationMillis */,
- null /* drawableLoadedListener */,
- res.getColor(android.R.color.transparent, null) /* placeholderColor */);
- card.setContentDescription(card.getResources().getString(
- R.string.clock_preview_content_description, title));
- }
- }
-
- /**
- * Adapter class for mPreviewPager.
- * This is a ViewPager as it allows for a nice pagination effect (ie, pages snap on swipe,
- * we don't want to just scroll)
- */
- private static class ClockPreviewAdapter extends BasePreviewAdapter<ClockfacePreviewPage> {
- ClockPreviewAdapter(Activity activity, Clockface clockface) {
- super(activity, R.layout.clock_preview_card);
- addPage(new ClockfacePreviewPage(
- clockface.getTitle(), activity , clockface.getPreviewAsset()));
- }
- }
-}
diff --git a/src/com/android/customization/picker/clock/data/repository/ClockPickerRepository.kt b/src/com/android/customization/picker/clock/data/repository/ClockPickerRepository.kt
new file mode 100644
index 0000000..ae66ce3
--- /dev/null
+++ b/src/com/android/customization/picker/clock/data/repository/ClockPickerRepository.kt
@@ -0,0 +1,52 @@
+/*
+ * 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.data.repository
+
+import androidx.annotation.ColorInt
+import androidx.annotation.IntRange
+import com.android.customization.picker.clock.shared.ClockSize
+import com.android.customization.picker.clock.shared.model.ClockMetadataModel
+import kotlinx.coroutines.flow.Flow
+
+/**
+ * Repository for accessing application clock settings, as well as selecting and configuring custom
+ * clocks.
+ */
+interface ClockPickerRepository {
+ val allClocks: Flow<List<ClockMetadataModel>>
+
+ val selectedClock: Flow<ClockMetadataModel>
+
+ val selectedClockSize: Flow<ClockSize>
+
+ fun setSelectedClock(clockId: String)
+
+ /**
+ * Set clock color to the settings.
+ *
+ * @param selectedColor selected color in the color option list.
+ * @param colorToneProgress color tone from 0 to 100 to apply to the selected color
+ * @param seedColor the actual clock color after blending the selected color and color tone
+ */
+ fun setClockColor(
+ selectedColorId: String?,
+ @IntRange(from = 0, to = 100) colorToneProgress: Int,
+ @ColorInt seedColor: Int?,
+ )
+
+ 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
new file mode 100644
index 0000000..880a00b
--- /dev/null
+++ b/src/com/android/customization/picker/clock/data/repository/ClockPickerRepositoryImpl.kt
@@ -0,0 +1,193 @@
+/*
+ * 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.data.repository
+
+import android.provider.Settings
+import androidx.annotation.ColorInt
+import androidx.annotation.IntRange
+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.CoroutineScope
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.channels.awaitClose
+import kotlinx.coroutines.delay
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.SharedFlow
+import kotlinx.coroutines.flow.SharingStarted
+import kotlinx.coroutines.flow.callbackFlow
+import kotlinx.coroutines.flow.map
+import kotlinx.coroutines.flow.mapLatest
+import kotlinx.coroutines.flow.mapNotNull
+import kotlinx.coroutines.flow.shareIn
+import org.json.JSONObject
+
+/** Implementation of [ClockPickerRepository], using [ClockRegistry]. */
+class ClockPickerRepositoryImpl(
+ private val secureSettingsRepository: SecureSettingsRepository,
+ private val registry: ClockRegistry,
+ scope: CoroutineScope,
+) : ClockPickerRepository {
+
+ @OptIn(ExperimentalCoroutinesApi::class)
+ override val allClocks: Flow<List<ClockMetadataModel>> =
+ callbackFlow {
+ fun send() {
+ val allClocks =
+ registry
+ .getClocks()
+ .filter { "NOT_IN_USE" !in it.clockId }
+ .map { it.toModel() }
+ trySend(allClocks)
+ }
+
+ val listener =
+ object : ClockRegistry.ClockChangeListener {
+ override fun onAvailableClocksChanged() {
+ send()
+ }
+ }
+ registry.registerClockChangeListener(listener)
+ send()
+ awaitClose { registry.unregisterClockChangeListener(listener) }
+ }
+ .mapLatest { allClocks ->
+ // Loading list of clock plugins can cause many consecutive calls of
+ // onAvailableClocksChanged(). We only care about the final fully-initiated clock
+ // list. Delay to avoid unnecessary too many emits.
+ delay(100)
+ allClocks
+ }
+
+ /** The currently-selected clock. This also emits the clock color information. */
+ override val selectedClock: Flow<ClockMetadataModel> =
+ callbackFlow {
+ fun send() {
+ val currentClockId = registry.currentClockId
+ val metadata = registry.settings?.metadata
+ val model =
+ registry
+ .getClocks()
+ .find { clockMetadata -> clockMetadata.clockId == currentClockId }
+ ?.toModel(
+ selectedColorId = metadata?.getSelectedColorId(),
+ colorTone = metadata?.getColorTone()
+ ?: ClockMetadataModel.DEFAULT_COLOR_TONE_PROGRESS,
+ seedColor = registry.seedColor
+ )
+ trySend(model)
+ }
+
+ val listener =
+ object : ClockRegistry.ClockChangeListener {
+ override fun onCurrentClockChanged() {
+ send()
+ }
+
+ override fun onAvailableClocksChanged() {
+ send()
+ }
+ }
+ registry.registerClockChangeListener(listener)
+ send()
+ awaitClose { registry.unregisterClockChangeListener(listener) }
+ }
+ .mapNotNull { it }
+
+ override fun setSelectedClock(clockId: String) {
+ registry.mutateSetting { oldSettings ->
+ val newSettings = oldSettings.copy(clockId = clockId)
+ newSettings.metadata = oldSettings.metadata
+ newSettings
+ }
+ }
+
+ override fun setClockColor(
+ selectedColorId: String?,
+ @IntRange(from = 0, to = 100) colorToneProgress: Int,
+ @ColorInt seedColor: Int?,
+ ) {
+ registry.mutateSetting { oldSettings ->
+ val newSettings = oldSettings.copy(seedColor = seedColor)
+ newSettings.metadata =
+ oldSettings.metadata
+ .put(KEY_METADATA_SELECTED_COLOR_ID, selectedColorId)
+ .put(KEY_METADATA_COLOR_TONE_PROGRESS, colorToneProgress)
+ newSettings
+ }
+ }
+
+ 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 suspend fun setClockSize(size: ClockSize) {
+ secureSettingsRepository.set(
+ name = Settings.Secure.LOCKSCREEN_USE_DOUBLE_LINE_CLOCK,
+ value = if (size == ClockSize.DYNAMIC) 1 else 0,
+ )
+ }
+
+ private fun JSONObject.getSelectedColorId(): String? {
+ return if (this.isNull(KEY_METADATA_SELECTED_COLOR_ID)) {
+ null
+ } else {
+ this.getString(KEY_METADATA_SELECTED_COLOR_ID)
+ }
+ }
+
+ private fun JSONObject.getColorTone(): Int {
+ return this.optInt(
+ KEY_METADATA_COLOR_TONE_PROGRESS,
+ ClockMetadataModel.DEFAULT_COLOR_TONE_PROGRESS
+ )
+ }
+
+ /** By default, [ClockMetadataModel] has no color information unless specified. */
+ private fun ClockMetadata.toModel(
+ selectedColorId: String? = null,
+ @IntRange(from = 0, to = 100) colorTone: Int = 0,
+ @ColorInt seedColor: Int? = null,
+ ): ClockMetadataModel {
+ return ClockMetadataModel(
+ clockId = clockId,
+ name = name,
+ selectedColorId = selectedColorId,
+ colorToneProgress = colorTone,
+ seedColor = seedColor,
+ )
+ }
+
+ companion object {
+ // The selected color in the color option list
+ private const val KEY_METADATA_SELECTED_COLOR_ID = "metadataSelectedColorId"
+
+ // The color tone to apply to the selected color
+ private const val KEY_METADATA_COLOR_TONE_PROGRESS = "metadataColorToneProgress"
+ }
+}
diff --git a/src/com/android/customization/picker/clock/data/repository/ClockRegistryProvider.kt b/src/com/android/customization/picker/clock/data/repository/ClockRegistryProvider.kt
new file mode 100644
index 0000000..bfe87c9
--- /dev/null
+++ b/src/com/android/customization/picker/clock/data/repository/ClockRegistryProvider.kt
@@ -0,0 +1,121 @@
+/*
+ * 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.data.repository
+
+import android.app.NotificationManager
+import android.content.ComponentName
+import android.content.Context
+import android.view.LayoutInflater
+import com.android.systemui.plugins.Plugin
+import com.android.systemui.plugins.PluginManager
+import com.android.systemui.shared.clocks.ClockRegistry
+import com.android.systemui.shared.clocks.DefaultClockProvider
+import com.android.systemui.shared.plugins.PluginActionManager
+import com.android.systemui.shared.plugins.PluginEnabler
+import com.android.systemui.shared.plugins.PluginInstance
+import com.android.systemui.shared.plugins.PluginManagerImpl
+import com.android.systemui.shared.plugins.PluginPrefs
+import com.android.systemui.shared.system.UncaughtExceptionPreHandlerManager_Factory
+import java.util.concurrent.Executors
+import kotlinx.coroutines.CoroutineDispatcher
+import kotlinx.coroutines.CoroutineScope
+
+/**
+ * Provide the [ClockRegistry] singleton. Note that we need to make sure that the [PluginManager]
+ * needs to be connected before [ClockRegistry] is ready to use.
+ */
+class ClockRegistryProvider(
+ private val context: Context,
+ private val coroutineScope: CoroutineScope,
+ private val mainDispatcher: CoroutineDispatcher,
+ private val backgroundDispatcher: CoroutineDispatcher,
+) {
+ private val pluginManager: PluginManager by lazy { createPluginManager(context) }
+ private val clockRegistry: ClockRegistry by lazy {
+ ClockRegistry(
+ context,
+ pluginManager,
+ coroutineScope,
+ mainDispatcher,
+ backgroundDispatcher,
+ isEnabled = true,
+ handleAllUsers = false,
+ DefaultClockProvider(context, LayoutInflater.from(context), context.resources)
+ )
+ .apply { registerListeners() }
+ }
+
+ fun get(): ClockRegistry {
+ return clockRegistry
+ }
+
+ private fun createPluginManager(context: Context): PluginManager {
+ val privilegedPlugins = listOf<String>()
+ val isDebugDevice = true
+
+ val instanceFactory =
+ PluginInstance.Factory(
+ this::class.java.classLoader,
+ PluginInstance.InstanceFactory<Plugin>(),
+ PluginInstance.VersionChecker(),
+ privilegedPlugins,
+ isDebugDevice,
+ )
+
+ /*
+ * let SystemUI handle plugin, in this class assume plugins are enabled
+ */
+ val pluginEnabler =
+ object : PluginEnabler {
+ override fun setEnabled(component: ComponentName) = Unit
+
+ override fun setDisabled(
+ component: ComponentName,
+ @PluginEnabler.DisableReason reason: Int
+ ) = Unit
+
+ override fun isEnabled(component: ComponentName): Boolean {
+ return true
+ }
+
+ @PluginEnabler.DisableReason
+ override fun getDisableReason(componentName: ComponentName): Int {
+ return PluginEnabler.ENABLED
+ }
+ }
+
+ val pluginActionManager =
+ PluginActionManager.Factory(
+ context,
+ context.packageManager,
+ context.mainExecutor,
+ Executors.newSingleThreadExecutor(),
+ context.getSystemService(NotificationManager::class.java),
+ pluginEnabler,
+ privilegedPlugins,
+ instanceFactory,
+ )
+ return PluginManagerImpl(
+ context,
+ pluginActionManager,
+ isDebugDevice,
+ UncaughtExceptionPreHandlerManager_Factory.create().get(),
+ pluginEnabler,
+ PluginPrefs(context),
+ listOf(),
+ )
+ }
+}
diff --git a/src/com/android/customization/picker/clock/domain/interactor/ClockPickerInteractor.kt b/src/com/android/customization/picker/clock/domain/interactor/ClockPickerInteractor.kt
new file mode 100644
index 0000000..6f3657a
--- /dev/null
+++ b/src/com/android/customization/picker/clock/domain/interactor/ClockPickerInteractor.kt
@@ -0,0 +1,65 @@
+/*
+ * 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.domain.interactor
+
+import androidx.annotation.ColorInt
+import androidx.annotation.IntRange
+import com.android.customization.picker.clock.data.repository.ClockPickerRepository
+import com.android.customization.picker.clock.shared.ClockSize
+import com.android.customization.picker.clock.shared.model.ClockMetadataModel
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.distinctUntilChanged
+import kotlinx.coroutines.flow.map
+
+/**
+ * Interactor for accessing application clock settings, as well as selecting and configuring custom
+ * clocks.
+ */
+class ClockPickerInteractor(private val repository: ClockPickerRepository) {
+
+ val allClocks: Flow<List<ClockMetadataModel>> = repository.allClocks
+
+ val selectedClockId: Flow<String> =
+ repository.selectedClock.map { clock -> clock.clockId }.distinctUntilChanged()
+
+ val selectedColorId: Flow<String?> =
+ repository.selectedClock.map { clock -> clock.selectedColorId }.distinctUntilChanged()
+
+ val colorToneProgress: Flow<Int> =
+ repository.selectedClock.map { clock -> clock.colorToneProgress }
+
+ val seedColor: Flow<Int?> = repository.selectedClock.map { clock -> clock.seedColor }
+
+ val selectedClockSize: Flow<ClockSize> = repository.selectedClockSize
+
+ fun setSelectedClock(clockId: String) {
+ repository.setSelectedClock(clockId)
+ }
+
+ fun setClockColor(
+ selectedColorId: String?,
+ @IntRange(from = 0, to = 100) colorToneProgress: Int,
+ @ColorInt seedColor: Int?,
+ ) {
+ repository.setClockColor(selectedColorId, colorToneProgress, seedColor)
+ }
+
+ suspend fun setClockSize(size: ClockSize) {
+ repository.setClockSize(size)
+ }
+}
diff --git a/src/com/android/customization/picker/clock/domain/interactor/ClocksSnapshotRestorer.kt b/src/com/android/customization/picker/clock/domain/interactor/ClocksSnapshotRestorer.kt
index 63b4a9b..7bb3232 100644
--- a/src/com/android/customization/picker/clock/domain/interactor/ClocksSnapshotRestorer.kt
+++ b/src/com/android/customization/picker/clock/domain/interactor/ClocksSnapshotRestorer.kt
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2022 The Android Open Source Project
+ * 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.
@@ -18,12 +18,13 @@
package com.android.customization.picker.clock.domain.interactor
import com.android.wallpaper.picker.undo.domain.interactor.SnapshotRestorer
+import com.android.wallpaper.picker.undo.domain.interactor.SnapshotStore
import com.android.wallpaper.picker.undo.shared.model.RestorableSnapshot
/** Handles state restoration for clocks. */
class ClocksSnapshotRestorer : SnapshotRestorer {
override suspend fun setUpSnapshotRestorer(
- updater: (RestorableSnapshot) -> Unit,
+ store: SnapshotStore,
): RestorableSnapshot {
// TODO(b/262924055): implement as part of the clock settings screen.
return RestorableSnapshot(mapOf())
diff --git a/src/com/android/customization/picker/clock/ClockSectionView.kt b/src/com/android/customization/picker/clock/shared/ClockSize.kt
similarity index 61%
copy from src/com/android/customization/picker/clock/ClockSectionView.kt
copy to src/com/android/customization/picker/clock/shared/ClockSize.kt
index fac975a..279ee54 100644
--- a/src/com/android/customization/picker/clock/ClockSectionView.kt
+++ b/src/com/android/customization/picker/clock/shared/ClockSize.kt
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2022 The Android Open Source Project
+ * 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.
@@ -12,12 +12,11 @@
* 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
+package com.android.customization.picker.clock.shared
-import android.content.Context
-import android.util.AttributeSet
-import com.android.wallpaper.picker.SectionView
-
-/** The [SectionView] for app clock. */
-class ClockSectionView(context: Context?, attrs: AttributeSet?) : SectionView(context, attrs)
+enum class ClockSize {
+ DYNAMIC,
+ SMALL,
+}
diff --git a/src/com/android/customization/picker/clock/shared/model/ClockMetadataModel.kt b/src/com/android/customization/picker/clock/shared/model/ClockMetadataModel.kt
new file mode 100644
index 0000000..bd87ba6
--- /dev/null
+++ b/src/com/android/customization/picker/clock/shared/model/ClockMetadataModel.kt
@@ -0,0 +1,34 @@
+/*
+ * 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.shared.model
+
+import androidx.annotation.ColorInt
+import androidx.annotation.IntRange
+
+/** Model for clock metadata. */
+data class ClockMetadataModel(
+ val clockId: String,
+ val name: String,
+ val selectedColorId: String?,
+ @IntRange(from = 0, to = 100) val colorToneProgress: Int,
+ @ColorInt val seedColor: Int?,
+) {
+ companion object {
+ const val DEFAULT_COLOR_TONE_PROGRESS = 75
+ }
+}
diff --git a/src/com/android/customization/picker/clock/ui/adapter/ClockSettingsTabAdapter.kt b/src/com/android/customization/picker/clock/ui/adapter/ClockSettingsTabAdapter.kt
new file mode 100644
index 0000000..746fdb3
--- /dev/null
+++ b/src/com/android/customization/picker/clock/ui/adapter/ClockSettingsTabAdapter.kt
@@ -0,0 +1,69 @@
+/*
+ * 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.adapter
+
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import android.widget.TextView
+import androidx.recyclerview.widget.RecyclerView
+import com.android.customization.picker.clock.ui.viewmodel.ClockSettingsTabViewModel
+import com.android.wallpaper.R
+
+/** Adapter for the tab recycler view on the clock settings screen. */
+class ClockSettingsTabAdapter : RecyclerView.Adapter<ClockSettingsTabAdapter.ViewHolder>() {
+
+ private val items = mutableListOf<ClockSettingsTabViewModel>()
+
+ fun setItems(items: List<ClockSettingsTabViewModel>) {
+ this.items.clear()
+ this.items.addAll(items)
+ notifyDataSetChanged()
+ }
+
+ override fun getItemCount(): Int {
+ return items.size
+ }
+
+ override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
+ return ViewHolder(
+ LayoutInflater.from(parent.context)
+ .inflate(
+ R.layout.picker_fragment_tab,
+ parent,
+ false,
+ )
+ )
+ }
+
+ override fun onBindViewHolder(holder: ViewHolder, position: Int) {
+ val item = items[position]
+ holder.itemView.isSelected = item.isSelected
+ holder.textView.text = item.name
+ holder.textView.setOnClickListener(
+ if (item.onClicked != null) {
+ View.OnClickListener { item.onClicked.invoke() }
+ } else {
+ null
+ }
+ )
+ }
+
+ class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
+ val textView: TextView = itemView.requireViewById(R.id.text)
+ }
+}
diff --git a/src/com/android/customization/picker/clock/ui/binder/ClockCarouselViewBinder.kt b/src/com/android/customization/picker/clock/ui/binder/ClockCarouselViewBinder.kt
new file mode 100644
index 0000000..9ad735d
--- /dev/null
+++ b/src/com/android/customization/picker/clock/ui/binder/ClockCarouselViewBinder.kt
@@ -0,0 +1,110 @@
+/*
+ * 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.binder
+
+import android.view.ViewGroup
+import android.widget.FrameLayout
+import androidx.core.view.isVisible
+import androidx.lifecycle.Lifecycle
+import androidx.lifecycle.LifecycleOwner
+import androidx.lifecycle.lifecycleScope
+import androidx.lifecycle.repeatOnLifecycle
+import com.android.customization.picker.clock.ui.view.ClockCarouselView
+import com.android.customization.picker.clock.ui.view.ClockViewFactory
+import com.android.customization.picker.clock.ui.viewmodel.ClockCarouselViewModel
+import com.android.wallpaper.R
+import kotlinx.coroutines.launch
+
+object ClockCarouselViewBinder {
+ /**
+ * The binding is used by the view where there is an action executed from another view, e.g.
+ * toggling show/hide of the view that the binder is holding.
+ */
+ interface Binding {
+ fun show()
+ fun hide()
+ }
+
+ @JvmStatic
+ fun bind(
+ carouselView: ClockCarouselView,
+ singleClockView: ViewGroup,
+ viewModel: ClockCarouselViewModel,
+ clockViewFactory: ClockViewFactory,
+ lifecycleOwner: LifecycleOwner,
+ ): Binding {
+ val singleClockHostView =
+ singleClockView.requireViewById<FrameLayout>(R.id.single_clock_host_view)
+ lifecycleOwner.lifecycleScope.launch {
+ lifecycleOwner.repeatOnLifecycle(Lifecycle.State.STARTED) {
+ launch { viewModel.isCarouselVisible.collect { carouselView.isVisible = it } }
+
+ launch {
+ viewModel.allClockIds.collect { allClockIds ->
+ carouselView.setUpClockCarouselView(
+ clockIds = allClockIds,
+ onGetClockPreview = { clockId -> clockViewFactory.getView(clockId) },
+ onClockSelected = { clockId -> viewModel.setSelectedClock(clockId) },
+ )
+ }
+ }
+
+ launch {
+ viewModel.selectedIndex.collect { selectedIndex ->
+ carouselView.setSelectedClockIndex(selectedIndex)
+ }
+ }
+
+ launch {
+ viewModel.seedColor.collect { clockViewFactory.updateColorForAllClocks(it) }
+ }
+
+ launch {
+ viewModel.isSingleClockViewVisible.collect { singleClockView.isVisible = it }
+ }
+
+ launch {
+ viewModel.clockId.collect { clockId ->
+ singleClockHostView.removeAllViews()
+ val clockView = clockViewFactory.getView(clockId)
+ // The clock view might still be attached to an existing parent. Detach
+ // before adding to another parent.
+ (clockView.parent as? ViewGroup)?.removeView(clockView)
+ singleClockHostView.addView(clockView)
+ }
+ }
+ }
+ }
+
+ lifecycleOwner.lifecycleScope.launch {
+ lifecycleOwner.repeatOnLifecycle(Lifecycle.State.RESUMED) {
+ clockViewFactory.registerTimeTicker()
+ }
+ // When paused
+ clockViewFactory.unregisterTimeTicker()
+ }
+
+ return object : Binding {
+ override fun show() {
+ viewModel.showClockCarousel(true)
+ }
+
+ override fun hide() {
+ viewModel.showClockCarousel(false)
+ }
+ }
+ }
+}
diff --git a/src/com/android/customization/picker/clock/ui/binder/ClockSectionViewBinder.kt b/src/com/android/customization/picker/clock/ui/binder/ClockSectionViewBinder.kt
new file mode 100644
index 0000000..7dc0d0c
--- /dev/null
+++ b/src/com/android/customization/picker/clock/ui/binder/ClockSectionViewBinder.kt
@@ -0,0 +1,53 @@
+/*
+ * 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.binder
+
+import android.view.View
+import android.widget.TextView
+import androidx.lifecycle.Lifecycle
+import androidx.lifecycle.LifecycleOwner
+import androidx.lifecycle.lifecycleScope
+import androidx.lifecycle.repeatOnLifecycle
+import com.android.customization.picker.clock.ui.viewmodel.ClockSectionViewModel
+import com.android.wallpaper.R
+import kotlinx.coroutines.flow.collectLatest
+import kotlinx.coroutines.launch
+
+object ClockSectionViewBinder {
+ fun bind(
+ view: View,
+ viewModel: ClockSectionViewModel,
+ lifecycleOwner: LifecycleOwner,
+ onClicked: () -> Unit,
+ ) {
+ view.setOnClickListener { onClicked() }
+
+ val selectedClockColorAndSize: TextView =
+ view.requireViewById(R.id.selected_clock_color_and_size)
+
+ lifecycleOwner.lifecycleScope.launch {
+ lifecycleOwner.repeatOnLifecycle(Lifecycle.State.STARTED) {
+ launch {
+ viewModel.selectedClockColorAndSizeText.collectLatest {
+ selectedClockColorAndSize.text = it
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/src/com/android/customization/picker/clock/ui/binder/ClockSettingsBinder.kt b/src/com/android/customization/picker/clock/ui/binder/ClockSettingsBinder.kt
new file mode 100644
index 0000000..66d9251
--- /dev/null
+++ b/src/com/android/customization/picker/clock/ui/binder/ClockSettingsBinder.kt
@@ -0,0 +1,181 @@
+/*
+ * 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.binder
+
+import android.view.View
+import android.view.ViewGroup
+import android.widget.FrameLayout
+import android.widget.SeekBar
+import androidx.core.view.isInvisible
+import androidx.core.view.isVisible
+import androidx.lifecycle.Lifecycle
+import androidx.lifecycle.LifecycleOwner
+import androidx.lifecycle.lifecycleScope
+import androidx.lifecycle.repeatOnLifecycle
+import androidx.recyclerview.widget.LinearLayoutManager
+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.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.adapter.ColorOptionAdapter
+import com.android.customization.picker.common.ui.view.ItemSpacing
+import com.android.wallpaper.R
+import kotlinx.coroutines.flow.mapNotNull
+import kotlinx.coroutines.launch
+
+/** Bind between the clock settings screen and its view model. */
+object ClockSettingsBinder {
+ fun bind(
+ view: View,
+ viewModel: ClockSettingsViewModel,
+ clockViewFactory: ClockViewFactory,
+ lifecycleOwner: LifecycleOwner,
+ ) {
+ val clockHostView: FrameLayout = view.requireViewById(R.id.clock_host_view)
+
+ val tabView: RecyclerView = view.requireViewById(R.id.tabs)
+ val tabAdapter = ClockSettingsTabAdapter()
+ tabView.adapter = tabAdapter
+ tabView.layoutManager = LinearLayoutManager(view.context, RecyclerView.HORIZONTAL, false)
+ tabView.addItemDecoration(ItemSpacing(ItemSpacing.TAB_ITEM_SPACING_DP))
+
+ val colorOptionContainerView: RecyclerView = view.requireViewById(R.id.color_options)
+ val colorOptionAdapter = ColorOptionAdapter()
+ colorOptionContainerView.adapter = colorOptionAdapter
+ colorOptionContainerView.layoutManager =
+ LinearLayoutManager(view.context, RecyclerView.HORIZONTAL, false)
+ colorOptionContainerView.addItemDecoration(ItemSpacing(ItemSpacing.ITEM_SPACING_DP))
+
+ val slider: SeekBar = view.requireViewById(R.id.slider)
+ slider.setOnSeekBarChangeListener(
+ object : SeekBar.OnSeekBarChangeListener {
+ override fun onProgressChanged(p0: SeekBar?, progress: Int, fromUser: Boolean) {
+ if (fromUser) {
+ viewModel.onSliderProgressChanged(progress)
+ }
+ }
+
+ override fun onStartTrackingTouch(seekBar: SeekBar?) = Unit
+ override fun onStopTrackingTouch(seekBar: SeekBar?) {
+ seekBar?.progress?.let { viewModel.onSliderProgressStop(it) }
+ }
+ }
+ )
+
+ 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 colorOptionContainer = view.requireViewById<View>(R.id.color_picker_container)
+ lifecycleOwner.lifecycleScope.launch {
+ lifecycleOwner.repeatOnLifecycle(Lifecycle.State.STARTED) {
+ launch {
+ viewModel.selectedClockId
+ .mapNotNull { it }
+ .collect { clockId ->
+ val clockView = clockViewFactory.getView(clockId)
+ (clockView.parent as? ViewGroup)?.removeView(clockView)
+ clockHostView.removeAllViews()
+ clockHostView.addView(clockView)
+ }
+ }
+
+ launch {
+ viewModel.seedColor.collect { seedColor ->
+ viewModel.selectedClockId.value?.let { selectedClockId ->
+ clockViewFactory.updateColor(selectedClockId, seedColor)
+ }
+ }
+ }
+
+ launch { viewModel.tabs.collect { tabAdapter.setItems(it) } }
+
+ launch {
+ viewModel.selectedTab.collect { tab ->
+ when (tab) {
+ ClockSettingsViewModel.Tab.COLOR -> {
+ colorOptionContainer.isVisible = true
+ sizeOptions.isInvisible = true
+ }
+ ClockSettingsViewModel.Tab.SIZE -> {
+ colorOptionContainer.isInvisible = true
+ sizeOptions.isVisible = true
+ }
+ }
+ }
+ }
+
+ launch {
+ viewModel.colorOptions.collect { colorOptions ->
+ colorOptionAdapter.setItems(colorOptions)
+ }
+ }
+
+ launch {
+ viewModel.selectedColorOptionPosition.collect { selectedPosition ->
+ if (selectedPosition != -1) {
+ // We use "post" because we need to give the adapter item a pass to
+ // update the view.
+ colorOptionContainerView.post {
+ colorOptionContainerView.smoothScrollToPosition(selectedPosition)
+ }
+ }
+ }
+ }
+
+ launch {
+ viewModel.selectedClockSize.collect { size ->
+ when (size) {
+ ClockSize.DYNAMIC -> {
+ sizeOptions.radioButtonDynamic.isChecked = true
+ sizeOptions.radioButtonSmall.isChecked = false
+ }
+ ClockSize.SMALL -> {
+ sizeOptions.radioButtonDynamic.isChecked = false
+ sizeOptions.radioButtonSmall.isChecked = true
+ }
+ }
+ }
+ }
+
+ launch {
+ viewModel.sliderProgress.collect { progress ->
+ slider.setProgress(progress, true)
+ }
+ }
+
+ launch {
+ viewModel.isSliderEnabled.collect { isEnabled -> slider.isEnabled = isEnabled }
+ }
+ }
+ }
+
+ lifecycleOwner.lifecycleScope.launch {
+ lifecycleOwner.repeatOnLifecycle(Lifecycle.State.RESUMED) {
+ clockViewFactory.registerTimeTicker()
+ }
+ // When paused
+ clockViewFactory.unregisterTimeTicker()
+ }
+ }
+}
diff --git a/src/com/android/customization/picker/clock/ui/fragment/ClockCustomDemoFragment.kt b/src/com/android/customization/picker/clock/ui/fragment/ClockCustomDemoFragment.kt
new file mode 100644
index 0000000..7e53ac4
--- /dev/null
+++ b/src/com/android/customization/picker/clock/ui/fragment/ClockCustomDemoFragment.kt
@@ -0,0 +1,93 @@
+package com.android.customization.picker.clock.ui.fragment
+
+import android.content.Context
+import android.os.Bundle
+import android.util.TypedValue
+import android.view.ContextThemeWrapper
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import android.view.ViewGroup.LayoutParams.MATCH_PARENT
+import android.view.ViewGroup.LayoutParams.WRAP_CONTENT
+import android.widget.FrameLayout
+import android.widget.TextView
+import android.widget.Toast
+import androidx.core.view.setPadding
+import androidx.recyclerview.widget.LinearLayoutManager
+import androidx.recyclerview.widget.RecyclerView
+import com.android.customization.module.ThemePickerInjector
+import com.android.internal.annotations.VisibleForTesting
+import com.android.systemui.plugins.ClockMetadata
+import com.android.systemui.shared.clocks.ClockRegistry
+import com.android.wallpaper.R
+import com.android.wallpaper.module.InjectorProvider
+import com.android.wallpaper.picker.AppbarFragment
+
+class ClockCustomDemoFragment : AppbarFragment() {
+ @VisibleForTesting lateinit var recyclerView: RecyclerView
+ @VisibleForTesting lateinit var clockRegistry: ClockRegistry
+
+ override fun onCreateView(
+ inflater: LayoutInflater,
+ container: ViewGroup?,
+ savedInstanceState: Bundle?
+ ): View {
+ val view = inflater.inflate(R.layout.fragment_clock_custom_picker_demo, container, false)
+ setUpToolbar(view)
+ clockRegistry =
+ (InjectorProvider.getInjector() as ThemePickerInjector).getClockRegistry(
+ requireContext()
+ )
+ val listInUse = clockRegistry.getClocks().filter { "NOT_IN_USE" !in it.clockId }
+
+ recyclerView = view.requireViewById(R.id.clock_preview_card_list_demo)
+ recyclerView.layoutManager = LinearLayoutManager(context, RecyclerView.VERTICAL, false)
+ recyclerView.adapter =
+ ClockRecyclerAdapter(listInUse, requireContext()) {
+ clockRegistry.currentClockId = it.clockId
+ Toast.makeText(context, "${it.name} selected", Toast.LENGTH_SHORT).show()
+ }
+ return view
+ }
+
+ override fun getDefaultTitle(): CharSequence {
+ return getString(R.string.clock_title)
+ }
+
+ internal class ClockRecyclerAdapter(
+ val list: List<ClockMetadata>,
+ val context: Context,
+ val onClockSelected: (ClockMetadata) -> Unit
+ ) : RecyclerView.Adapter<ClockRecyclerAdapter.ViewHolder>() {
+ class ViewHolder(val view: View, val textView: TextView, val onItemClicked: (Int) -> Unit) :
+ RecyclerView.ViewHolder(view) {
+ init {
+ itemView.setOnClickListener { onItemClicked(absoluteAdapterPosition) }
+ }
+ }
+
+ override fun onCreateViewHolder(viewGroup: ViewGroup, viewType: Int): ViewHolder {
+ val rootView = FrameLayout(viewGroup.context)
+ val textView =
+ TextView(ContextThemeWrapper(viewGroup.context, R.style.SectionTitleTextStyle))
+ textView.setPadding(ITEM_PADDING)
+ rootView.addView(textView)
+ val outValue = TypedValue()
+ context.theme.resolveAttribute(android.R.attr.selectableItemBackground, outValue, true)
+ rootView.setBackgroundResource(outValue.resourceId)
+ val lp = RecyclerView.LayoutParams(MATCH_PARENT, WRAP_CONTENT)
+ rootView.layoutParams = lp
+ return ViewHolder(rootView, textView) { onClockSelected(list[it]) }
+ }
+
+ override fun onBindViewHolder(viewHolder: ViewHolder, position: Int) {
+ viewHolder.textView.text = list[position].name
+ }
+
+ override fun getItemCount() = list.size
+
+ companion object {
+ val ITEM_PADDING = 40
+ }
+ }
+}
diff --git a/src/com/android/customization/picker/clock/ui/fragment/ClockSettingsFragment.kt b/src/com/android/customization/picker/clock/ui/fragment/ClockSettingsFragment.kt
new file mode 100644
index 0000000..c5cde53
--- /dev/null
+++ b/src/com/android/customization/picker/clock/ui/fragment/ClockSettingsFragment.kt
@@ -0,0 +1,135 @@
+/*
+ * 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.fragment
+
+import android.os.Bundle
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import androidx.cardview.widget.CardView
+import androidx.lifecycle.ViewModelProvider
+import androidx.lifecycle.get
+import com.android.customization.module.ThemePickerInjector
+import com.android.customization.picker.clock.ui.binder.ClockSettingsBinder
+import com.android.systemui.shared.clocks.shared.model.ClockPreviewConstants
+import com.android.wallpaper.R
+import com.android.wallpaper.module.InjectorProvider
+import com.android.wallpaper.picker.AppbarFragment
+import com.android.wallpaper.picker.customization.ui.binder.ScreenPreviewBinder
+import com.android.wallpaper.picker.customization.ui.viewmodel.ScreenPreviewViewModel
+import com.android.wallpaper.util.PreviewUtils
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.suspendCancellableCoroutine
+
+@OptIn(ExperimentalCoroutinesApi::class)
+class ClockSettingsFragment : AppbarFragment() {
+ companion object {
+ const val DESTINATION_ID = "clock_settings"
+
+ @JvmStatic
+ fun newInstance(): ClockSettingsFragment {
+ return ClockSettingsFragment()
+ }
+ }
+
+ override fun onCreateView(
+ inflater: LayoutInflater,
+ container: ViewGroup?,
+ savedInstanceState: Bundle?
+ ): View {
+ val view =
+ inflater.inflate(
+ R.layout.fragment_clock_settings,
+ container,
+ false,
+ )
+ setUpToolbar(view)
+
+ val context = requireContext()
+ val activity = requireActivity()
+ val injector = InjectorProvider.getInjector() as ThemePickerInjector
+
+ val lockScreenView: CardView = view.requireViewById(R.id.lock_preview)
+ val colorViewModel = injector.getWallpaperColorsViewModel()
+ val displayUtils = injector.getDisplayUtils(context)
+ ScreenPreviewBinder.bind(
+ activity = activity,
+ previewView = lockScreenView,
+ viewModel =
+ ScreenPreviewViewModel(
+ previewUtils =
+ PreviewUtils(
+ context = context,
+ authority =
+ resources.getString(
+ R.string.lock_screen_preview_provider_authority,
+ ),
+ ),
+ wallpaperInfoProvider = {
+ suspendCancellableCoroutine { continuation ->
+ injector
+ .getCurrentWallpaperInfoFactory(context)
+ .createCurrentWallpaperInfos(
+ { homeWallpaper, lockWallpaper, _ ->
+ continuation.resume(
+ homeWallpaper ?: lockWallpaper,
+ null,
+ )
+ },
+ /* forceRefresh= */ true,
+ )
+ }
+ },
+ onWallpaperColorChanged = { colors ->
+ colorViewModel.setLockWallpaperColors(colors)
+ },
+ initialExtrasProvider = {
+ Bundle().apply {
+ // Hide the clock from the system UI rendered preview so we can
+ // place the carousel on top of it.
+ putBoolean(
+ ClockPreviewConstants.KEY_HIDE_CLOCK,
+ true,
+ )
+ }
+ },
+ ),
+ lifecycleOwner = this,
+ offsetToStart = displayUtils.isSingleDisplayOrUnfoldedHorizontalHinge(activity),
+ )
+ .show()
+
+ ClockSettingsBinder.bind(
+ view,
+ ViewModelProvider(
+ requireActivity(),
+ injector.getClockSettingsViewModelFactory(
+ context,
+ injector.getWallpaperColorsViewModel(),
+ ),
+ )
+ .get(),
+ injector.getClockViewFactory(activity),
+ this@ClockSettingsFragment,
+ )
+
+ return view
+ }
+
+ override fun getDefaultTitle(): CharSequence {
+ return requireContext().getString(R.string.clock_settings_title)
+ }
+}
diff --git a/src/com/android/customization/picker/clock/ui/section/ClockSectionController.kt b/src/com/android/customization/picker/clock/ui/section/ClockSectionController.kt
new file mode 100644
index 0000000..b47c243
--- /dev/null
+++ b/src/com/android/customization/picker/clock/ui/section/ClockSectionController.kt
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2022 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.section
+
+import android.content.Context
+import android.view.LayoutInflater
+import androidx.lifecycle.LifecycleOwner
+import androidx.lifecycle.lifecycleScope
+import com.android.customization.picker.clock.ui.binder.ClockSectionViewBinder
+import com.android.customization.picker.clock.ui.fragment.ClockSettingsFragment
+import com.android.customization.picker.clock.ui.view.ClockSectionView
+import com.android.customization.picker.clock.ui.viewmodel.ClockSectionViewModel
+import com.android.wallpaper.R
+import com.android.wallpaper.config.BaseFlags
+import com.android.wallpaper.model.CustomizationSectionController
+import com.android.wallpaper.model.CustomizationSectionController.CustomizationSectionNavigationController
+import kotlinx.coroutines.launch
+
+/** A [CustomizationSectionController] for clock customization. */
+class ClockSectionController(
+ private val navigationController: CustomizationSectionNavigationController,
+ private val lifecycleOwner: LifecycleOwner,
+ private val flag: BaseFlags,
+ private val viewModel: ClockSectionViewModel,
+) : CustomizationSectionController<ClockSectionView> {
+
+ override fun isAvailable(context: Context): Boolean {
+ return flag.isCustomClocksEnabled(context!!)
+ }
+
+ override fun createView(context: Context): ClockSectionView {
+ val view =
+ LayoutInflater.from(context)
+ .inflate(
+ R.layout.clock_section_view,
+ null,
+ ) as ClockSectionView
+ lifecycleOwner.lifecycleScope.launch {
+ ClockSectionViewBinder.bind(
+ view = view,
+ viewModel = viewModel,
+ lifecycleOwner = lifecycleOwner
+ ) {
+ navigationController.navigateTo(ClockSettingsFragment())
+ }
+ }
+ return view
+ }
+}
diff --git a/src/com/android/customization/picker/clock/ui/view/ClockCarouselView.kt b/src/com/android/customization/picker/clock/ui/view/ClockCarouselView.kt
new file mode 100644
index 0000000..90d7c42
--- /dev/null
+++ b/src/com/android/customization/picker/clock/ui/view/ClockCarouselView.kt
@@ -0,0 +1,86 @@
+/*
+ * 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.view.ViewGroup
+import android.widget.FrameLayout
+import androidx.constraintlayout.helper.widget.Carousel
+import androidx.core.view.get
+import com.android.wallpaper.R
+
+class ClockCarouselView(
+ context: Context,
+ attrs: AttributeSet,
+) :
+ FrameLayout(
+ context,
+ attrs,
+ ) {
+
+ private val carousel: Carousel
+ private lateinit var adapter: ClockCarouselAdapter
+
+ init {
+ val view = LayoutInflater.from(context).inflate(R.layout.clock_carousel, this)
+ carousel = view.requireViewById(R.id.carousel)
+ }
+
+ fun setUpClockCarouselView(
+ clockIds: List<String>,
+ onGetClockPreview: (clockId: String) -> View,
+ onClockSelected: (clockId: String) -> Unit,
+ ) {
+ adapter = ClockCarouselAdapter(clockIds, onGetClockPreview, onClockSelected)
+ carousel.setAdapter(adapter)
+ carousel.refresh()
+ }
+
+ fun setSelectedClockIndex(
+ index: Int,
+ ) {
+ carousel.jumpToIndex(index)
+ }
+
+ class ClockCarouselAdapter(
+ val clockIds: List<String>,
+ val onGetClockPreview: (clockId: String) -> View,
+ val onClockSelected: (clockId: String) -> Unit,
+ ) : Carousel.Adapter {
+
+ override fun count(): Int {
+ return clockIds.size
+ }
+
+ override fun populate(view: View?, index: Int) {
+ val viewRoot = view as ViewGroup
+ val clockHostView = viewRoot[0] as ViewGroup
+ clockHostView.removeAllViews()
+ val clockView = onGetClockPreview(clockIds[index])
+ // The clock view might still be attached to an existing parent. Detach before adding to
+ // another parent.
+ (clockView.parent as? ViewGroup)?.removeView(clockView)
+ clockHostView.addView(clockView)
+ }
+
+ override fun onNewItem(index: Int) {
+ onClockSelected.invoke(clockIds[index])
+ }
+ }
+}
diff --git a/src/com/android/customization/picker/clock/ClockSectionView.kt b/src/com/android/customization/picker/clock/ui/view/ClockSectionView.kt
similarity index 93%
rename from src/com/android/customization/picker/clock/ClockSectionView.kt
rename to src/com/android/customization/picker/clock/ui/view/ClockSectionView.kt
index fac975a..cca107c 100644
--- a/src/com/android/customization/picker/clock/ClockSectionView.kt
+++ b/src/com/android/customization/picker/clock/ui/view/ClockSectionView.kt
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package com.android.customization.picker.clock
+package com.android.customization.picker.clock.ui.view
import android.content.Context
import android.util.AttributeSet
diff --git a/src/com/android/customization/picker/clock/ui/view/ClockSizeRadioButtonGroup.kt b/src/com/android/customization/picker/clock/ui/view/ClockSizeRadioButtonGroup.kt
new file mode 100644
index 0000000..909491a
--- /dev/null
+++ b/src/com/android/customization/picker/clock/ui/view/ClockSizeRadioButtonGroup.kt
@@ -0,0 +1,50 @@
+/*
+ * 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) }
+ }
+}
diff --git a/src/com/android/customization/picker/clock/ui/view/ClockViewFactory.kt b/src/com/android/customization/picker/clock/ui/view/ClockViewFactory.kt
new file mode 100644
index 0000000..7f480de
--- /dev/null
+++ b/src/com/android/customization/picker/clock/ui/view/ClockViewFactory.kt
@@ -0,0 +1,75 @@
+/*
+ * 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.app.Activity
+import android.view.View
+import androidx.annotation.ColorInt
+import com.android.systemui.plugins.ClockController
+import com.android.systemui.shared.clocks.ClockRegistry
+import com.android.wallpaper.R
+import com.android.wallpaper.util.ScreenSizeCalculator
+import com.android.wallpaper.util.TimeUtils.TimeTicker
+
+class ClockViewFactory(
+ private val activity: Activity,
+ private val registry: ClockRegistry,
+) {
+ private val clockControllers: HashMap<String, ClockController> = HashMap()
+ private var ticker: TimeTicker? = null
+
+ fun getView(clockId: String): View {
+ return (clockControllers[clockId] ?: initClockController(clockId)).largeClock.view
+ }
+
+ fun updateColorForAllClocks(@ColorInt seedColor: Int?) {
+ clockControllers.values.forEach { it.events.onSeedColorChanged(seedColor = seedColor) }
+ }
+
+ fun updateColor(clockId: String, @ColorInt seedColor: Int?) {
+ return (clockControllers[clockId] ?: initClockController(clockId))
+ .events
+ .onSeedColorChanged(seedColor)
+ }
+
+ fun registerTimeTicker() {
+ ticker =
+ TimeTicker.registerNewReceiver(activity.applicationContext) {
+ clockControllers.values.forEach { it.largeClock.events.onTimeTick() }
+ }
+ }
+
+ fun unregisterTimeTicker() {
+ activity.applicationContext.unregisterReceiver(ticker)
+ }
+
+ private fun initClockController(clockId: String): ClockController {
+ val controller =
+ registry.createExampleClock(clockId).also { it?.initialize(activity.resources, 0f, 0f) }
+ checkNotNull(controller)
+ val screenSizeCalculator = ScreenSizeCalculator.getInstance()
+ val screenSize = screenSizeCalculator.getScreenSize(activity.windowManager.defaultDisplay)
+ val ratio =
+ activity.resources.getDimensionPixelSize(R.dimen.screen_preview_height).toFloat() /
+ screenSize.y.toFloat()
+ controller.largeClock.events.onFontSettingChanged(
+ activity.resources.getDimensionPixelSize(R.dimen.large_clock_text_size).toFloat() *
+ ratio
+ )
+ clockControllers[clockId] = controller
+ return controller
+ }
+}
diff --git a/src/com/android/customization/picker/clock/ui/view/SaturationProgressDrawable.kt b/src/com/android/customization/picker/clock/ui/view/SaturationProgressDrawable.kt
new file mode 100644
index 0000000..9e1d789
--- /dev/null
+++ b/src/com/android/customization/picker/clock/ui/view/SaturationProgressDrawable.kt
@@ -0,0 +1,107 @@
+/*
+ * 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.pm.ActivityInfo
+import android.content.res.Resources
+import android.graphics.Rect
+import android.graphics.drawable.Drawable
+import android.graphics.drawable.DrawableWrapper
+import android.graphics.drawable.InsetDrawable
+
+/**
+ * [DrawableWrapper] to use in the progress of brightness slider.
+ *
+ * This drawable is used to change the bounds of the enclosed drawable depending on the level to
+ * simulate a sliding progress, instead of using clipping or scaling. That way, the shape of the
+ * edges is maintained.
+ *
+ * Meant to be used with a rounded ends background, it will also prevent deformation when the slider
+ * is meant to be smaller than the rounded corner. The background should have rounded corners that
+ * are half of the height.
+ *
+ * This class also assumes that a "thumb" icon exists within the end's edge of the progress
+ * drawable, and the slider's width, when interacted on, if offset by half the size of the thumb
+ * icon which puts the icon directly underneath the user's finger.
+ */
+class SaturationProgressDrawable @JvmOverloads constructor(drawable: Drawable? = null) :
+ InsetDrawable(drawable, 0) {
+
+ companion object {
+ private const val MAX_LEVEL = 10000
+ }
+
+ override fun onLayoutDirectionChanged(layoutDirection: Int): Boolean {
+ onLevelChange(level)
+ return super.onLayoutDirectionChanged(layoutDirection)
+ }
+
+ override fun onBoundsChange(bounds: Rect) {
+ super.onBoundsChange(bounds)
+ onLevelChange(level)
+ }
+
+ override fun onLevelChange(level: Int): Boolean {
+ val drawableBounds = drawable?.bounds!!
+
+ // The thumb offset shifts the sun icon directly under the user's thumb
+ val thumbOffset = bounds.height() / 2
+ val width = bounds.width() * level / MAX_LEVEL + thumbOffset
+
+ // On 0, the width is bounds.height (a circle), and on MAX_LEVEL, the width is bounds.width
+ // TODO (b/268541542) Test if RTL devices also works for the slider
+ drawable?.setBounds(
+ bounds.left,
+ drawableBounds.top,
+ width.coerceAtMost(bounds.width()).coerceAtLeast(bounds.height()),
+ drawableBounds.bottom
+ )
+ return super.onLevelChange(level)
+ }
+
+ override fun getConstantState(): ConstantState {
+ // This should not be null as it was created with a state in the constructor.
+ return RoundedCornerState(super.getConstantState()!!)
+ }
+
+ override fun getChangingConfigurations(): Int {
+ return super.getChangingConfigurations() or ActivityInfo.CONFIG_DENSITY
+ }
+
+ override fun canApplyTheme(): Boolean {
+ return (drawable?.canApplyTheme() ?: false) || super.canApplyTheme()
+ }
+
+ private class RoundedCornerState(private val wrappedState: ConstantState) : ConstantState() {
+ override fun newDrawable(): Drawable {
+ return newDrawable(null, null)
+ }
+
+ override fun newDrawable(res: Resources?, theme: Resources.Theme?): Drawable {
+ val wrapper = wrappedState.newDrawable(res, theme) as DrawableWrapper
+ return SaturationProgressDrawable(wrapper.drawable)
+ }
+
+ override fun getChangingConfigurations(): Int {
+ return wrappedState.changingConfigurations
+ }
+
+ override fun canApplyTheme(): Boolean {
+ return true
+ }
+ }
+}
diff --git a/src/com/android/customization/picker/clock/ui/viewmodel/ClockCarouselViewModel.kt b/src/com/android/customization/picker/clock/ui/viewmodel/ClockCarouselViewModel.kt
new file mode 100644
index 0000000..60a9e85
--- /dev/null
+++ b/src/com/android/customization/picker/clock/ui/viewmodel/ClockCarouselViewModel.kt
@@ -0,0 +1,98 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.customization.picker.clock.ui.viewmodel
+
+import com.android.customization.picker.clock.domain.interactor.ClockPickerInteractor
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.delay
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.MutableStateFlow
+import kotlinx.coroutines.flow.combine
+import kotlinx.coroutines.flow.distinctUntilChanged
+import kotlinx.coroutines.flow.flatMapLatest
+import kotlinx.coroutines.flow.map
+import kotlinx.coroutines.flow.mapLatest
+import kotlinx.coroutines.flow.mapNotNull
+
+/**
+ * Clock carousel view model that provides data for the carousel of clock previews. When there is
+ * only one item, we should show a single clock preview instead of a carousel.
+ */
+class ClockCarouselViewModel(
+ private val interactor: ClockPickerInteractor,
+) {
+ @OptIn(ExperimentalCoroutinesApi::class)
+ val allClockIds: Flow<List<String>> =
+ interactor.allClocks.mapLatest { allClocks ->
+ // Delay to avoid the case that the full list of clocks is not initiated.
+ delay(CLOCKS_EVENT_UPDATE_DELAY_MILLIS)
+ allClocks.map { it.clockId }
+ }
+
+ val seedColor: Flow<Int?> = interactor.seedColor
+
+ private val shouldShowCarousel = MutableStateFlow(false)
+ val isCarouselVisible: Flow<Boolean> =
+ combine(allClockIds.map { it.size > 1 }.distinctUntilChanged(), shouldShowCarousel) {
+ hasMoreThanOneClock,
+ shouldShowCarousel ->
+ hasMoreThanOneClock && shouldShowCarousel
+ }
+ .distinctUntilChanged()
+
+ @OptIn(ExperimentalCoroutinesApi::class)
+ val selectedIndex: Flow<Int> =
+ allClockIds
+ .flatMapLatest { allClockIds ->
+ interactor.selectedClockId.map { selectedClockId ->
+ val index = allClockIds.indexOf(selectedClockId)
+ if (index >= 0) {
+ index
+ } else {
+ null
+ }
+ }
+ }
+ .mapNotNull { it }
+
+ // Handle the case when there is only one clock in the carousel
+ private val shouldShowSingleClock = MutableStateFlow(false)
+ val isSingleClockViewVisible: Flow<Boolean> =
+ combine(allClockIds.map { it.size == 1 }.distinctUntilChanged(), shouldShowSingleClock) {
+ hasOneClock,
+ shouldShowSingleClock ->
+ hasOneClock && shouldShowSingleClock
+ }
+ .distinctUntilChanged()
+
+ val clockId: Flow<String> =
+ allClockIds
+ .map { allClockIds -> if (allClockIds.size == 1) allClockIds[0] else null }
+ .mapNotNull { it }
+
+ fun setSelectedClock(clockId: String) {
+ interactor.setSelectedClock(clockId)
+ }
+
+ fun showClockCarousel(shouldShow: Boolean) {
+ shouldShowCarousel.value = shouldShow
+ shouldShowSingleClock.value = shouldShow
+ }
+
+ companion object {
+ const val CLOCKS_EVENT_UPDATE_DELAY_MILLIS: Long = 100
+ }
+}
diff --git a/src/com/android/customization/picker/clock/ui/viewmodel/ClockColorViewModel.kt b/src/com/android/customization/picker/clock/ui/viewmodel/ClockColorViewModel.kt
new file mode 100644
index 0000000..ea60ae3
--- /dev/null
+++ b/src/com/android/customization/picker/clock/ui/viewmodel/ClockColorViewModel.kt
@@ -0,0 +1,69 @@
+/*
+ * 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.viewmodel
+
+import android.annotation.ColorInt
+import android.content.res.Resources
+import android.graphics.Color
+import com.android.wallpaper.R
+
+/** The view model that defines custom clock colors. */
+data class ClockColorViewModel(
+ val colorId: String,
+ val colorName: String?,
+ @ColorInt val color: Int,
+ private val colorToneMin: Double,
+ private val colorToneMax: Double,
+) {
+
+ fun getColorTone(progress: Int): Double {
+ return colorToneMin + (progress.toDouble() * (colorToneMax - colorToneMin)) / 100
+ }
+
+ companion object {
+ const val DEFAULT_COLOR_TONE_MIN = 0
+ const val DEFAULT_COLOR_TONE_MAX = 100
+
+ fun getPresetColorMap(resources: Resources): Map<String, ClockColorViewModel> {
+ val ids = resources.getStringArray(R.array.clock_color_ids)
+ val names = resources.obtainTypedArray(R.array.clock_color_names)
+ val colors = resources.obtainTypedArray(R.array.clock_colors)
+ val colorToneMinList = resources.obtainTypedArray(R.array.clock_color_tone_min)
+ val colorToneMaxList = resources.obtainTypedArray(R.array.clock_color_tone_max)
+ return buildList {
+ ids.indices.forEach { index ->
+ add(
+ ClockColorViewModel(
+ ids[index],
+ names.getString(index),
+ colors.getColor(index, Color.TRANSPARENT),
+ colorToneMinList.getInt(index, DEFAULT_COLOR_TONE_MIN).toDouble(),
+ colorToneMaxList.getInt(index, DEFAULT_COLOR_TONE_MAX).toDouble(),
+ )
+ )
+ }
+ }
+ .associateBy { it.colorId }
+ .also {
+ names.recycle()
+ colors.recycle()
+ colorToneMinList.recycle()
+ colorToneMaxList.recycle()
+ }
+ }
+ }
+}
diff --git a/src/com/android/customization/picker/clock/ui/viewmodel/ClockSectionViewModel.kt b/src/com/android/customization/picker/clock/ui/viewmodel/ClockSectionViewModel.kt
new file mode 100644
index 0000000..008a125
--- /dev/null
+++ b/src/com/android/customization/picker/clock/ui/viewmodel/ClockSectionViewModel.kt
@@ -0,0 +1,51 @@
+/*
+ * 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.viewmodel
+
+import android.content.Context
+import com.android.customization.picker.clock.domain.interactor.ClockPickerInteractor
+import com.android.customization.picker.clock.shared.ClockSize
+import com.android.wallpaper.R
+import java.util.Locale
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.combine
+import kotlinx.coroutines.flow.map
+
+/** View model for the clock section view on the lockscreen customization surface. */
+class ClockSectionViewModel(context: Context, interactor: ClockPickerInteractor) {
+ val appContext: Context = context.applicationContext
+ val clockColorMap: Map<String, ClockColorViewModel> =
+ ClockColorViewModel.getPresetColorMap(appContext.resources)
+ val selectedClockColorAndSizeText: Flow<String> =
+ combine(interactor.selectedColorId, interactor.selectedClockSize, ::Pair).map {
+ (selectedColorId, selectedClockSize) ->
+ val colorText =
+ clockColorMap[selectedColorId]?.colorName
+ ?: context.getString(R.string.default_theme_title)
+ val sizeText =
+ when (selectedClockSize) {
+ ClockSize.SMALL -> appContext.getString(R.string.clock_size_small)
+ ClockSize.DYNAMIC -> appContext.getString(R.string.clock_size_dynamic)
+ }
+ appContext
+ .getString(R.string.clock_color_and_size_description, colorText, sizeText)
+ .lowercase()
+ .replaceFirstChar {
+ if (it.isLowerCase()) it.titlecase(Locale.getDefault()) else it.toString()
+ }
+ }
+}
diff --git a/src/com/android/customization/picker/clock/ui/viewmodel/ClockSettingsTabViewModel.kt b/src/com/android/customization/picker/clock/ui/viewmodel/ClockSettingsTabViewModel.kt
new file mode 100644
index 0000000..7c30ca2
--- /dev/null
+++ b/src/com/android/customization/picker/clock/ui/viewmodel/ClockSettingsTabViewModel.kt
@@ -0,0 +1,28 @@
+/*
+ * 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.viewmodel
+
+/** View model for the tabs on the clock settings screen. */
+class ClockSettingsTabViewModel(
+ /** User-visible name for the tab. */
+ val name: String,
+
+ /** Whether this is the currently-selected tab in the picker. */
+ val isSelected: Boolean,
+
+ /** Notifies that the tab has been clicked by the user. */
+ val onClicked: (() -> Unit)?,
+)
diff --git a/src/com/android/customization/picker/clock/ui/viewmodel/ClockSettingsViewModel.kt b/src/com/android/customization/picker/clock/ui/viewmodel/ClockSettingsViewModel.kt
new file mode 100644
index 0000000..c3cd217
--- /dev/null
+++ b/src/com/android/customization/picker/clock/ui/viewmodel/ClockSettingsViewModel.kt
@@ -0,0 +1,309 @@
+/*
+ * 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.viewmodel
+
+import android.content.Context
+import androidx.core.graphics.ColorUtils
+import androidx.lifecycle.ViewModel
+import androidx.lifecycle.ViewModelProvider
+import androidx.lifecycle.viewModelScope
+import com.android.customization.model.color.ColorBundle
+import com.android.customization.model.color.ColorSeedOption
+import com.android.customization.picker.clock.domain.interactor.ClockPickerInteractor
+import com.android.customization.picker.clock.shared.ClockSize
+import com.android.customization.picker.clock.shared.model.ClockMetadataModel
+import com.android.customization.picker.color.domain.interactor.ColorPickerInteractor
+import com.android.customization.picker.color.shared.model.ColorType
+import com.android.customization.picker.color.ui.viewmodel.ColorOptionViewModel
+import com.android.wallpaper.R
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.delay
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.MutableStateFlow
+import kotlinx.coroutines.flow.SharingStarted
+import kotlinx.coroutines.flow.StateFlow
+import kotlinx.coroutines.flow.asStateFlow
+import kotlinx.coroutines.flow.combine
+import kotlinx.coroutines.flow.distinctUntilChanged
+import kotlinx.coroutines.flow.map
+import kotlinx.coroutines.flow.mapLatest
+import kotlinx.coroutines.flow.merge
+import kotlinx.coroutines.flow.stateIn
+import kotlinx.coroutines.launch
+
+/** View model for the clock settings screen. */
+class ClockSettingsViewModel
+private constructor(
+ context: Context,
+ private val clockPickerInteractor: ClockPickerInteractor,
+ private val colorPickerInteractor: ColorPickerInteractor,
+) : ViewModel() {
+
+ enum class Tab {
+ COLOR,
+ SIZE,
+ }
+
+ val colorMap = ClockColorViewModel.getPresetColorMap(context.resources)
+
+ val selectedClockId: StateFlow<String?> =
+ clockPickerInteractor.selectedClockId
+ .distinctUntilChanged()
+ .stateIn(viewModelScope, SharingStarted.Eagerly, null)
+
+ val selectedColorId: StateFlow<String?> =
+ clockPickerInteractor.selectedColorId.stateIn(viewModelScope, SharingStarted.Eagerly, null)
+
+ private val sliderColorToneProgress =
+ MutableStateFlow(ClockMetadataModel.DEFAULT_COLOR_TONE_PROGRESS)
+ val isSliderEnabled: Flow<Boolean> =
+ clockPickerInteractor.selectedColorId.map { it != null }.distinctUntilChanged()
+ val sliderProgress: Flow<Int> =
+ merge(clockPickerInteractor.colorToneProgress, sliderColorToneProgress)
+
+ private val _seedColor: MutableStateFlow<Int?> = MutableStateFlow(null)
+ val seedColor: Flow<Int?> = merge(clockPickerInteractor.seedColor, _seedColor)
+
+ /**
+ * The slider color tone updates are quick. Do not set color tone and the blended color to the
+ * settings until [onSliderProgressStop] is called. Update to a locally cached temporary
+ * [sliderColorToneProgress] and [_seedColor] instead.
+ */
+ fun onSliderProgressChanged(progress: Int) {
+ sliderColorToneProgress.value = progress
+ val selectedColorId = selectedColorId.value ?: return
+ val clockColorViewModel = colorMap[selectedColorId] ?: return
+ _seedColor.value =
+ blendColorWithTone(
+ color = clockColorViewModel.color,
+ colorTone = clockColorViewModel.getColorTone(progress),
+ )
+ }
+
+ fun onSliderProgressStop(progress: Int) {
+ val selectedColorId = selectedColorId.value ?: return
+ val clockColorViewModel = colorMap[selectedColorId] ?: return
+ clockPickerInteractor.setClockColor(
+ selectedColorId = selectedColorId,
+ colorToneProgress = progress,
+ seedColor =
+ blendColorWithTone(
+ color = clockColorViewModel.color,
+ colorTone = clockColorViewModel.getColorTone(progress),
+ )
+ )
+ }
+
+ @OptIn(ExperimentalCoroutinesApi::class)
+ val colorOptions: StateFlow<List<ColorOptionViewModel>> =
+ combine(colorPickerInteractor.colorOptions, clockPickerInteractor.selectedColorId, ::Pair)
+ .mapLatest { (colorOptions, selectedColorId) ->
+ // Use mapLatest and delay(100) here to prevent too many selectedClockColor update
+ // events from ClockRegistry upstream, caused by sliding the saturation level bar.
+ delay(COLOR_OPTIONS_EVENT_UPDATE_DELAY_MILLIS)
+ buildList {
+ val defaultThemeColorOptionViewModel =
+ (colorOptions[ColorType.WALLPAPER_COLOR]
+ ?.find { it.isSelected }
+ ?.colorOption as? ColorSeedOption)
+ ?.toColorOptionViewModel(
+ context,
+ selectedColorId,
+ )
+ ?: (colorOptions[ColorType.PRESET_COLOR]
+ ?.find { it.isSelected }
+ ?.colorOption as? ColorBundle)
+ ?.toColorOptionViewModel(
+ context,
+ selectedColorId,
+ )
+ if (defaultThemeColorOptionViewModel != null) {
+ add(defaultThemeColorOptionViewModel)
+ }
+
+ val selectedColorPosition = colorMap.keys.indexOf(selectedColorId)
+
+ colorMap.values.forEachIndexed { index, colorModel ->
+ val isSelected = selectedColorPosition == index
+ val colorToneProgress = ClockMetadataModel.DEFAULT_COLOR_TONE_PROGRESS
+ add(
+ ColorOptionViewModel(
+ color0 = colorModel.color,
+ color1 = colorModel.color,
+ color2 = colorModel.color,
+ color3 = colorModel.color,
+ contentDescription =
+ context.getString(
+ R.string.content_description_color_option,
+ index,
+ ),
+ isSelected = isSelected,
+ onClick =
+ if (isSelected) {
+ null
+ } else {
+ {
+ clockPickerInteractor.setClockColor(
+ selectedColorId = colorModel.colorId,
+ colorToneProgress = colorToneProgress,
+ seedColor =
+ blendColorWithTone(
+ color = colorModel.color,
+ colorTone =
+ colorModel.getColorTone(
+ colorToneProgress,
+ ),
+ ),
+ )
+ }
+ },
+ )
+ )
+ }
+ }
+ }
+ .stateIn(
+ scope = viewModelScope,
+ started = SharingStarted.WhileSubscribed(),
+ initialValue = emptyList(),
+ )
+
+ @OptIn(ExperimentalCoroutinesApi::class)
+ val selectedColorOptionPosition: Flow<Int> =
+ colorOptions.mapLatest { it.indexOfFirst { colorOption -> colorOption.isSelected } }
+
+ private fun ColorSeedOption.toColorOptionViewModel(
+ context: Context,
+ selectedColorId: String?,
+ ): ColorOptionViewModel {
+ val colors = previewInfo.resolveColors(context.resources)
+ return ColorOptionViewModel(
+ color0 = colors[0],
+ color1 = colors[1],
+ color2 = colors[2],
+ color3 = colors[3],
+ contentDescription = getContentDescription(context).toString(),
+ title = context.getString(R.string.default_theme_title),
+ isSelected = selectedColorId == null,
+ onClick =
+ if (selectedColorId == null) {
+ null
+ } else {
+ {
+ clockPickerInteractor.setClockColor(
+ selectedColorId = null,
+ colorToneProgress = ClockMetadataModel.DEFAULT_COLOR_TONE_PROGRESS,
+ seedColor = null,
+ )
+ }
+ },
+ )
+ }
+
+ private fun ColorBundle.toColorOptionViewModel(
+ context: Context,
+ selectedColorId: String?
+ ): ColorOptionViewModel {
+ val primaryColor = previewInfo.resolvePrimaryColor(context.resources)
+ val secondaryColor = previewInfo.resolveSecondaryColor(context.resources)
+ return ColorOptionViewModel(
+ color0 = primaryColor,
+ color1 = secondaryColor,
+ color2 = primaryColor,
+ color3 = secondaryColor,
+ contentDescription = getContentDescription(context).toString(),
+ title = context.getString(R.string.default_theme_title),
+ isSelected = selectedColorId == null,
+ onClick =
+ if (selectedColorId == null) {
+ null
+ } else {
+ {
+ clockPickerInteractor.setClockColor(
+ selectedColorId = null,
+ colorToneProgress = ClockMetadataModel.DEFAULT_COLOR_TONE_PROGRESS,
+ seedColor = null,
+ )
+ }
+ },
+ )
+ }
+
+ val selectedClockSize: Flow<ClockSize> = clockPickerInteractor.selectedClockSize
+
+ fun setClockSize(size: ClockSize) {
+ viewModelScope.launch { clockPickerInteractor.setClockSize(size) }
+ }
+
+ private val _selectedTabPosition = MutableStateFlow(Tab.COLOR)
+ val selectedTab: StateFlow<Tab> = _selectedTabPosition.asStateFlow()
+ val tabs: Flow<List<ClockSettingsTabViewModel>> =
+ selectedTab.map {
+ listOf(
+ ClockSettingsTabViewModel(
+ name = context.resources.getString(R.string.clock_color),
+ isSelected = it == Tab.COLOR,
+ onClicked =
+ if (it == Tab.COLOR) {
+ null
+ } else {
+ { _selectedTabPosition.tryEmit(Tab.COLOR) }
+ }
+ ),
+ ClockSettingsTabViewModel(
+ name = context.resources.getString(R.string.clock_size),
+ isSelected = it == Tab.SIZE,
+ onClicked =
+ if (it == Tab.SIZE) {
+ null
+ } else {
+ { _selectedTabPosition.tryEmit(Tab.SIZE) }
+ }
+ ),
+ )
+ }
+
+ companion object {
+ private val helperColorLab: DoubleArray by lazy { DoubleArray(3) }
+
+ fun blendColorWithTone(color: Int, colorTone: Double): Int {
+ ColorUtils.colorToLAB(color, helperColorLab)
+ return ColorUtils.LABToColor(
+ colorTone,
+ helperColorLab[1],
+ helperColorLab[2],
+ )
+ }
+
+ const val COLOR_OPTIONS_EVENT_UPDATE_DELAY_MILLIS: Long = 100
+ }
+
+ class Factory(
+ private val context: Context,
+ private val clockPickerInteractor: ClockPickerInteractor,
+ private val colorPickerInteractor: ColorPickerInteractor,
+ ) : ViewModelProvider.Factory {
+ override fun <T : ViewModel> create(modelClass: Class<T>): T {
+ @Suppress("UNCHECKED_CAST")
+ return ClockSettingsViewModel(
+ context = context,
+ clockPickerInteractor = clockPickerInteractor,
+ colorPickerInteractor = colorPickerInteractor,
+ )
+ as T
+ }
+ }
+}
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/data/repository/ColorPickerRepository.kt b/src/com/android/customization/picker/color/data/repository/ColorPickerRepository.kt
new file mode 100644
index 0000000..7cf9fd0
--- /dev/null
+++ b/src/com/android/customization/picker/color/data/repository/ColorPickerRepository.kt
@@ -0,0 +1,40 @@
+/*
+ * 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.data.repository
+
+import com.android.customization.picker.color.shared.model.ColorOptionModel
+import com.android.customization.picker.color.shared.model.ColorType
+import kotlinx.coroutines.flow.Flow
+
+/**
+ * Abstracts access to application state related to functionality for selecting, picking, or setting
+ * system color.
+ */
+interface ColorPickerRepository {
+
+ /** List of wallpaper and preset color options on the device, categorized by Color Type */
+ val colorOptions: Flow<Map<ColorType, List<ColorOptionModel>>>
+
+ /** Selects a color option with optimistic update */
+ suspend fun select(colorOptionModel: ColorOptionModel)
+
+ /** Returns the current selected color option based on system settings */
+ fun getCurrentColorOption(): ColorOptionModel
+
+ /** Returns the current selected color source based on system settings */
+ fun getCurrentColorSource(): String?
+}
diff --git a/src/com/android/customization/picker/color/data/repository/ColorPickerRepositoryImpl.kt b/src/com/android/customization/picker/color/data/repository/ColorPickerRepositoryImpl.kt
new file mode 100644
index 0000000..512a500
--- /dev/null
+++ b/src/com/android/customization/picker/color/data/repository/ColorPickerRepositoryImpl.kt
@@ -0,0 +1,146 @@
+/*
+ * 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.data.repository
+
+import android.app.WallpaperColors
+import android.util.Log
+import com.android.customization.model.CustomizationManager
+import com.android.customization.model.color.ColorBundle
+import com.android.customization.model.color.ColorCustomizationManager
+import com.android.customization.model.color.ColorOption
+import com.android.customization.model.color.ColorSeedOption
+import com.android.customization.picker.color.shared.model.ColorOptionModel
+import com.android.customization.picker.color.shared.model.ColorType
+import com.android.systemui.monet.Style
+import com.android.wallpaper.model.WallpaperColorsViewModel
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.StateFlow
+import kotlinx.coroutines.flow.combine
+import kotlinx.coroutines.flow.map
+import kotlinx.coroutines.suspendCancellableCoroutine
+
+// TODO (b/262924623): refactor to remove dependency on ColorCustomizationManager & ColorOption
+// TODO (b/268203200): Create test for ColorPickerRepositoryImpl
+class ColorPickerRepositoryImpl(
+ wallpaperColorsViewModel: WallpaperColorsViewModel,
+ private val colorManager: ColorCustomizationManager,
+) : ColorPickerRepository {
+
+ private val homeWallpaperColors: StateFlow<WallpaperColors?> =
+ wallpaperColorsViewModel.homeWallpaperColors
+ private val lockWallpaperColors: StateFlow<WallpaperColors?> =
+ wallpaperColorsViewModel.lockWallpaperColors
+
+ override val colorOptions: Flow<Map<ColorType, List<ColorOptionModel>>> =
+ combine(homeWallpaperColors, lockWallpaperColors) { homeColors, lockColors ->
+ homeColors to lockColors
+ }
+ .map { (homeColors, lockColors) ->
+ suspendCancellableCoroutine { continuation ->
+ colorManager.setWallpaperColors(homeColors, lockColors)
+ colorManager.fetchOptions(
+ object : CustomizationManager.OptionsFetchedListener<ColorOption?> {
+ override fun onOptionsLoaded(options: MutableList<ColorOption?>?) {
+ val wallpaperColorOptions: MutableList<ColorOptionModel> =
+ mutableListOf()
+ val presetColorOptions: MutableList<ColorOptionModel> =
+ mutableListOf()
+ options?.forEach { option ->
+ when (option) {
+ is ColorSeedOption ->
+ wallpaperColorOptions.add(option.toModel())
+ is ColorBundle -> presetColorOptions.add(option.toModel())
+ }
+ }
+ continuation.resumeWith(
+ Result.success(
+ mapOf(
+ ColorType.WALLPAPER_COLOR to wallpaperColorOptions,
+ ColorType.PRESET_COLOR to presetColorOptions
+ )
+ )
+ )
+ }
+
+ override fun onError(throwable: Throwable?) {
+ Log.e(TAG, "Error loading theme bundles", throwable)
+ continuation.resumeWith(
+ Result.failure(
+ throwable ?: Throwable("Error loading theme bundles")
+ )
+ )
+ }
+ },
+ /* reload= */ false
+ )
+ }
+ }
+
+ override suspend fun select(colorOptionModel: ColorOptionModel) =
+ suspendCancellableCoroutine { continuation ->
+ colorManager.apply(
+ colorOptionModel.colorOption,
+ object : CustomizationManager.Callback {
+ override fun onSuccess() {
+ continuation.resumeWith(Result.success(Unit))
+ }
+
+ override fun onError(throwable: Throwable?) {
+ Log.w(TAG, "Apply theme with error", throwable)
+ continuation.resumeWith(
+ Result.failure(throwable ?: Throwable("Error loading theme bundles"))
+ )
+ }
+ }
+ )
+ }
+
+ override fun getCurrentColorOption(): ColorOptionModel {
+ val overlays = colorManager.currentOverlays
+ val styleOrNull = colorManager.currentStyle
+ val style = styleOrNull?.let { Style.valueOf(it) } ?: Style.TONAL_SPOT
+ val colorOptionBuilder =
+ // Does not matter whether ColorSeedOption or ColorBundle builder is used here
+ // because to apply the color, one just needs a generic ColorOption
+ ColorSeedOption.Builder().setSource(colorManager.currentColorSource).setStyle(style)
+ for (overlay in overlays) {
+ colorOptionBuilder.addOverlayPackage(overlay.key, overlay.value)
+ }
+ val colorOption = colorOptionBuilder.build()
+ return ColorOptionModel(
+ key = "${colorOption.style}::${colorOption.serializedPackages}",
+ colorOption = colorOption,
+ isSelected = false,
+ )
+ }
+
+ override fun getCurrentColorSource(): String? {
+ return colorManager.currentColorSource
+ }
+
+ private fun ColorOption.toModel(): ColorOptionModel {
+ return ColorOptionModel(
+ key = "${this.style}::${this.serializedPackages}",
+ colorOption = this,
+ isSelected = isActive(colorManager),
+ )
+ }
+
+ companion object {
+ private const val TAG = "ColorPickerRepositoryImpl"
+ }
+}
diff --git a/src/com/android/customization/picker/color/data/repository/FakeColorPickerRepository.kt b/src/com/android/customization/picker/color/data/repository/FakeColorPickerRepository.kt
new file mode 100644
index 0000000..edbf6dc
--- /dev/null
+++ b/src/com/android/customization/picker/color/data/repository/FakeColorPickerRepository.kt
@@ -0,0 +1,182 @@
+/*
+ * 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.data.repository
+
+import android.content.Context
+import android.graphics.Color
+import android.text.TextUtils
+import com.android.customization.model.color.ColorBundle
+import com.android.customization.model.color.ColorOptionsProvider
+import com.android.customization.model.color.ColorSeedOption
+import com.android.customization.picker.color.shared.model.ColorOptionModel
+import com.android.customization.picker.color.shared.model.ColorType
+import kotlinx.coroutines.flow.MutableStateFlow
+import kotlinx.coroutines.flow.StateFlow
+import kotlinx.coroutines.flow.asStateFlow
+
+class FakeColorPickerRepository(private val context: Context) : ColorPickerRepository {
+
+ private lateinit var selectedColorOption: ColorOptionModel
+
+ private val _colorOptions =
+ MutableStateFlow(
+ mapOf<ColorType, List<ColorOptionModel>>(
+ ColorType.WALLPAPER_COLOR to listOf(),
+ ColorType.PRESET_COLOR to listOf()
+ )
+ )
+ override val colorOptions: StateFlow<Map<ColorType, List<ColorOptionModel>>> =
+ _colorOptions.asStateFlow()
+
+ init {
+ setOptions(4, 4, ColorType.WALLPAPER_COLOR, 0)
+ }
+
+ fun setOptions(
+ numWallpaperOptions: Int,
+ numPresetOptions: Int,
+ selectedColorOptionType: ColorType,
+ selectedColorOptionIndex: Int
+ ) {
+ _colorOptions.value =
+ mapOf(
+ ColorType.WALLPAPER_COLOR to
+ buildList {
+ repeat(times = numWallpaperOptions) { index ->
+ val isSelected =
+ selectedColorOptionType == ColorType.WALLPAPER_COLOR &&
+ selectedColorOptionIndex == index
+ val colorOption =
+ ColorOptionModel(
+ key = "${ColorType.WALLPAPER_COLOR}::$index",
+ colorOption = buildWallpaperOption(index),
+ isSelected = isSelected,
+ )
+ if (isSelected) {
+ selectedColorOption = colorOption
+ }
+ add(colorOption)
+ }
+ },
+ ColorType.PRESET_COLOR to
+ buildList {
+ repeat(times = numPresetOptions) { index ->
+ val isSelected =
+ selectedColorOptionType == ColorType.PRESET_COLOR &&
+ selectedColorOptionIndex == index
+ val colorOption =
+ ColorOptionModel(
+ key = "${ColorType.PRESET_COLOR}::$index",
+ colorOption = buildPresetOption(index),
+ isSelected =
+ selectedColorOptionType == ColorType.PRESET_COLOR &&
+ selectedColorOptionIndex == index,
+ )
+ if (isSelected) {
+ selectedColorOption = colorOption
+ }
+ add(colorOption)
+ }
+ }
+ )
+ }
+
+ private fun buildPresetOption(index: Int): ColorBundle {
+ return ColorBundle.Builder()
+ .addOverlayPackage("TEST_PACKAGE_TYPE", "preset_color")
+ .addOverlayPackage("TEST_PACKAGE_INDEX", "$index")
+ .setIndex(index)
+ .build(context)
+ }
+
+ private fun buildWallpaperOption(index: Int): ColorSeedOption {
+ return ColorSeedOption.Builder()
+ .setLightColors(
+ intArrayOf(
+ Color.TRANSPARENT,
+ Color.TRANSPARENT,
+ Color.TRANSPARENT,
+ Color.TRANSPARENT
+ )
+ )
+ .setDarkColors(
+ intArrayOf(
+ Color.TRANSPARENT,
+ Color.TRANSPARENT,
+ Color.TRANSPARENT,
+ Color.TRANSPARENT
+ )
+ )
+ .addOverlayPackage("TEST_PACKAGE_TYPE", "wallpaper_color")
+ .addOverlayPackage("TEST_PACKAGE_INDEX", "$index")
+ .setIndex(index)
+ .build()
+ }
+
+ override suspend fun select(colorOptionModel: ColorOptionModel) {
+ val colorOptions = _colorOptions.value
+ val wallpaperColorOptions = colorOptions[ColorType.WALLPAPER_COLOR]!!
+ val newWallpaperColorOptions = buildList {
+ wallpaperColorOptions.forEach { option ->
+ add(
+ ColorOptionModel(
+ key = option.key,
+ colorOption = option.colorOption,
+ isSelected = option.testEquals(colorOptionModel),
+ )
+ )
+ }
+ }
+ val basicColorOptions = colorOptions[ColorType.PRESET_COLOR]!!
+ val newBasicColorOptions = buildList {
+ basicColorOptions.forEach { option ->
+ add(
+ ColorOptionModel(
+ key = option.key,
+ colorOption = option.colorOption,
+ isSelected = option.testEquals(colorOptionModel),
+ )
+ )
+ }
+ }
+ _colorOptions.value =
+ mapOf(
+ ColorType.WALLPAPER_COLOR to newWallpaperColorOptions,
+ ColorType.PRESET_COLOR to newBasicColorOptions
+ )
+ }
+
+ override fun getCurrentColorOption(): ColorOptionModel = selectedColorOption
+
+ override fun getCurrentColorSource(): String? =
+ when (selectedColorOption.colorOption) {
+ is ColorSeedOption -> ColorOptionsProvider.COLOR_SOURCE_HOME
+ is ColorBundle -> ColorOptionsProvider.COLOR_SOURCE_PRESET
+ else -> null
+ }
+
+ private fun ColorOptionModel.testEquals(other: Any?): Boolean {
+ if (other == null) {
+ return false
+ }
+ return if (other is ColorOptionModel) {
+ TextUtils.equals(this.key, other.key)
+ } else {
+ false
+ }
+ }
+}
diff --git a/src/com/android/customization/picker/color/domain/interactor/ColorPickerInteractor.kt b/src/com/android/customization/picker/color/domain/interactor/ColorPickerInteractor.kt
new file mode 100644
index 0000000..8c7a4b7
--- /dev/null
+++ b/src/com/android/customization/picker/color/domain/interactor/ColorPickerInteractor.kt
@@ -0,0 +1,49 @@
+/*
+ * 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.domain.interactor
+
+import com.android.customization.picker.color.data.repository.ColorPickerRepository
+import com.android.customization.picker.color.shared.model.ColorOptionModel
+import javax.inject.Provider
+import kotlinx.coroutines.flow.MutableStateFlow
+
+/** Single entry-point for all application state and business logic related to system color. */
+class ColorPickerInteractor(
+ private val repository: ColorPickerRepository,
+ private val snapshotRestorer: Provider<ColorPickerSnapshotRestorer>,
+) {
+ /**
+ * The newly selected color option for overwriting the current active option during an
+ * optimistic update, the value is set to null when update fails
+ */
+ val activeColorOption = MutableStateFlow<ColorOptionModel?>(null)
+
+ /** List of wallpaper and preset color options on the device, categorized by Color Type */
+ val colorOptions = repository.colorOptions
+
+ suspend fun select(colorOptionModel: ColorOptionModel) {
+ activeColorOption.value = colorOptionModel
+ try {
+ repository.select(colorOptionModel)
+ snapshotRestorer.get().storeSnapshot(colorOptionModel)
+ } catch (e: Exception) {
+ activeColorOption.value = null
+ }
+ }
+
+ fun getCurrentColorOption(): ColorOptionModel = repository.getCurrentColorOption()
+}
diff --git a/src/com/android/customization/picker/color/domain/interactor/ColorPickerSnapshotRestorer.kt b/src/com/android/customization/picker/color/domain/interactor/ColorPickerSnapshotRestorer.kt
new file mode 100644
index 0000000..dce59eb
--- /dev/null
+++ b/src/com/android/customization/picker/color/domain/interactor/ColorPickerSnapshotRestorer.kt
@@ -0,0 +1,81 @@
+/*
+ * 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.domain.interactor
+
+import android.util.Log
+import com.android.customization.picker.color.shared.model.ColorOptionModel
+import com.android.wallpaper.picker.undo.domain.interactor.SnapshotRestorer
+import com.android.wallpaper.picker.undo.domain.interactor.SnapshotStore
+import com.android.wallpaper.picker.undo.shared.model.RestorableSnapshot
+
+/** Handles state restoration for the color picker system. */
+class ColorPickerSnapshotRestorer(
+ private val interactor: ColorPickerInteractor,
+) : SnapshotRestorer {
+
+ private var snapshotStore: SnapshotStore = SnapshotStore.NOOP
+ private var originalOption: ColorOptionModel? = null
+
+ fun storeSnapshot(colorOptionModel: ColorOptionModel) {
+ snapshotStore.store(snapshot(colorOptionModel))
+ }
+
+ override suspend fun setUpSnapshotRestorer(
+ store: SnapshotStore,
+ ): RestorableSnapshot {
+ snapshotStore = store
+ originalOption = interactor.getCurrentColorOption()
+ return snapshot(originalOption)
+ }
+
+ override suspend fun restoreToSnapshot(snapshot: RestorableSnapshot) {
+ val optionPackagesFromSnapshot: String? = snapshot.args[KEY_COLOR_OPTION_PACKAGES]
+ originalOption?.let { optionToRestore ->
+ if (
+ optionToRestore.colorOption.serializedPackages != optionPackagesFromSnapshot ||
+ optionToRestore.colorOption.style.toString() !=
+ snapshot.args[KEY_COLOR_OPTION_STYLE]
+ ) {
+ Log.wtf(
+ TAG,
+ """ Original packages does not match snapshot packages to restore to. The
+ | current implementation doesn't support undo, only a reset back to the
+ | original color option."""
+ .trimMargin(),
+ )
+ }
+
+ interactor.select(optionToRestore)
+ }
+ }
+
+ private fun snapshot(colorOptionModel: ColorOptionModel? = null): RestorableSnapshot {
+ val snapshotMap = mutableMapOf<String, String>()
+ colorOptionModel?.let {
+ snapshotMap[KEY_COLOR_OPTION_PACKAGES] = colorOptionModel.colorOption.serializedPackages
+ snapshotMap[KEY_COLOR_OPTION_STYLE] = colorOptionModel.colorOption.style.toString()
+ }
+ return RestorableSnapshot(snapshotMap)
+ }
+
+ companion object {
+ private const val TAG = "ColorPickerSnapshotRestorer"
+ private const val KEY_COLOR_OPTION_PACKAGES = "color_packages"
+ private const val KEY_COLOR_OPTION_STYLE = "color_style"
+ }
+}
diff --git a/src/com/android/customization/picker/color/shared/model/ColorOptionModel.kt b/src/com/android/customization/picker/color/shared/model/ColorOptionModel.kt
new file mode 100644
index 0000000..5fde08e
--- /dev/null
+++ b/src/com/android/customization/picker/color/shared/model/ColorOptionModel.kt
@@ -0,0 +1,31 @@
+/*
+ * 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.shared.model
+
+import com.android.customization.model.color.ColorOption
+
+/** Models application state for a color option in a picker experience. */
+data class ColorOptionModel(
+ val key: String,
+
+ /** Colors for the color option. */
+ val colorOption: ColorOption,
+
+ /** Whether this color option is selected. */
+ var isSelected: Boolean,
+)
diff --git a/src/com/android/customization/picker/clock/ClockSectionView.kt b/src/com/android/customization/picker/color/shared/model/ColorType.kt
similarity index 61%
copy from src/com/android/customization/picker/clock/ClockSectionView.kt
copy to src/com/android/customization/picker/color/shared/model/ColorType.kt
index fac975a..c9a01d0 100644
--- a/src/com/android/customization/picker/clock/ClockSectionView.kt
+++ b/src/com/android/customization/picker/color/shared/model/ColorType.kt
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2022 The Android Open Source Project
+ * 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.
@@ -12,12 +12,14 @@
* 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
+package com.android.customization.picker.color.shared.model
-import android.content.Context
-import android.util.AttributeSet
-import com.android.wallpaper.picker.SectionView
+enum class ColorType {
+ /** Colors generated based on the current wallpaper */
+ WALLPAPER_COLOR,
-/** The [SectionView] for app clock. */
-class ClockSectionView(context: Context?, attrs: AttributeSet?) : SectionView(context, attrs)
+ /** Preset colors */
+ PRESET_COLOR,
+}
diff --git a/src/com/android/customization/picker/color/ui/adapter/ColorOptionAdapter.kt b/src/com/android/customization/picker/color/ui/adapter/ColorOptionAdapter.kt
new file mode 100644
index 0000000..7aa390d
--- /dev/null
+++ b/src/com/android/customization/picker/color/ui/adapter/ColorOptionAdapter.kt
@@ -0,0 +1,103 @@
+/*
+ * 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.ui.adapter
+
+import android.graphics.BlendMode
+import android.graphics.BlendModeColorFilter
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import android.widget.ImageView
+import android.widget.TextView
+import androidx.core.view.isVisible
+import androidx.recyclerview.widget.RecyclerView
+import com.android.customization.picker.color.ui.viewmodel.ColorOptionViewModel
+import com.android.wallpaper.R
+
+/**
+ * Adapts between color option items and views.
+ *
+ * TODO (b/272109171): Remove after clock settings is refactored to use OptionItemAdapter
+ */
+class ColorOptionAdapter : RecyclerView.Adapter<ColorOptionAdapter.ViewHolder>() {
+
+ private val items = mutableListOf<ColorOptionViewModel>()
+ private var isTitleVisible = false
+
+ fun setItems(items: List<ColorOptionViewModel>) {
+ this.items.clear()
+ this.items.addAll(items)
+ isTitleVisible = items.any { item -> item.title != null }
+ notifyDataSetChanged()
+ }
+
+ class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
+ val borderView: View = itemView.requireViewById(R.id.selection_border)
+ val backgroundView: View = itemView.requireViewById(R.id.background)
+ val color0View: ImageView = itemView.requireViewById(R.id.color_preview_0)
+ val color1View: ImageView = itemView.requireViewById(R.id.color_preview_1)
+ val color2View: ImageView = itemView.requireViewById(R.id.color_preview_2)
+ val color3View: ImageView = itemView.requireViewById(R.id.color_preview_3)
+ val optionTitleView: TextView = itemView.requireViewById(R.id.option_title)
+ }
+
+ override fun getItemCount(): Int {
+ return items.size
+ }
+
+ override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
+ return ViewHolder(
+ LayoutInflater.from(parent.context)
+ .inflate(
+ R.layout.color_option_with_background,
+ parent,
+ false,
+ )
+ )
+ }
+
+ override fun onBindViewHolder(holder: ViewHolder, position: Int) {
+ val item = items[position]
+
+ holder.itemView.setOnClickListener(
+ if (item.onClick != null) {
+ View.OnClickListener { item.onClick.invoke() }
+ } else {
+ null
+ }
+ )
+ if (item.isSelected) {
+ holder.borderView.alpha = 1f
+ holder.borderView.scaleX = 1f
+ holder.borderView.scaleY = 1f
+ holder.backgroundView.scaleX = 0.86f
+ holder.backgroundView.scaleY = 0.86f
+ } else {
+ holder.borderView.alpha = 0f
+ holder.backgroundView.scaleX = 1f
+ holder.backgroundView.scaleY = 1f
+ }
+ holder.color0View.drawable.colorFilter = BlendModeColorFilter(item.color0, BlendMode.SRC)
+ holder.color1View.drawable.colorFilter = BlendModeColorFilter(item.color1, BlendMode.SRC)
+ holder.color2View.drawable.colorFilter = BlendModeColorFilter(item.color2, BlendMode.SRC)
+ holder.color3View.drawable.colorFilter = BlendModeColorFilter(item.color3, BlendMode.SRC)
+ holder.itemView.contentDescription = item.contentDescription
+ holder.optionTitleView.isVisible = isTitleVisible
+ holder.optionTitleView.text = item.title
+ }
+}
diff --git a/src/com/android/customization/picker/color/ui/adapter/ColorTypeTabAdapter.kt b/src/com/android/customization/picker/color/ui/adapter/ColorTypeTabAdapter.kt
new file mode 100644
index 0000000..bb9f082
--- /dev/null
+++ b/src/com/android/customization/picker/color/ui/adapter/ColorTypeTabAdapter.kt
@@ -0,0 +1,70 @@
+/*
+ * 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.ui.adapter
+
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import android.widget.TextView
+import androidx.recyclerview.widget.RecyclerView
+import com.android.customization.picker.color.ui.viewmodel.ColorTypeTabViewModel
+import com.android.wallpaper.R
+
+/** Adapts between color type items and views. */
+class ColorTypeTabAdapter : RecyclerView.Adapter<ColorTypeTabAdapter.ViewHolder>() {
+
+ private val items = mutableListOf<ColorTypeTabViewModel>()
+
+ fun setItems(items: List<ColorTypeTabViewModel>) {
+ this.items.clear()
+ this.items.addAll(items)
+ notifyDataSetChanged()
+ }
+
+ override fun getItemCount(): Int {
+ return items.size
+ }
+
+ override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
+ return ViewHolder(
+ LayoutInflater.from(parent.context)
+ .inflate(
+ R.layout.picker_fragment_tab,
+ parent,
+ false,
+ )
+ )
+ }
+
+ override fun onBindViewHolder(holder: ViewHolder, position: Int) {
+ val item = items[position]
+ holder.itemView.isSelected = item.isSelected
+ holder.textView.text = item.name
+ holder.textView.setOnClickListener(
+ if (item.onClick != null) {
+ View.OnClickListener { item.onClick.invoke() }
+ } else {
+ null
+ }
+ )
+ }
+
+ class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
+ val textView: TextView = itemView.requireViewById(R.id.text)
+ }
+}
diff --git a/src/com/android/customization/picker/color/ui/binder/ColorOptionIconBinder.kt b/src/com/android/customization/picker/color/ui/binder/ColorOptionIconBinder.kt
new file mode 100644
index 0000000..1478cc4
--- /dev/null
+++ b/src/com/android/customization/picker/color/ui/binder/ColorOptionIconBinder.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.ui.binder
+
+import android.graphics.BlendMode
+import android.graphics.BlendModeColorFilter
+import android.view.ViewGroup
+import android.widget.ImageView
+import com.android.customization.picker.color.ui.viewmodel.ColorOptionIconViewModel
+import com.android.wallpaper.R
+
+object ColorOptionIconBinder {
+ fun bind(
+ view: ViewGroup,
+ viewModel: ColorOptionIconViewModel,
+ ) {
+ val color0View: ImageView = view.requireViewById(R.id.color_preview_0)
+ val color1View: ImageView = view.requireViewById(R.id.color_preview_1)
+ val color2View: ImageView = view.requireViewById(R.id.color_preview_2)
+ val color3View: ImageView = view.requireViewById(R.id.color_preview_3)
+ color0View.drawable.colorFilter = BlendModeColorFilter(viewModel.color0, BlendMode.SRC)
+ color1View.drawable.colorFilter = BlendModeColorFilter(viewModel.color1, BlendMode.SRC)
+ color2View.drawable.colorFilter = BlendModeColorFilter(viewModel.color2, BlendMode.SRC)
+ color3View.drawable.colorFilter = BlendModeColorFilter(viewModel.color3, BlendMode.SRC)
+ }
+}
diff --git a/src/com/android/customization/picker/color/ui/binder/ColorPickerBinder.kt b/src/com/android/customization/picker/color/ui/binder/ColorPickerBinder.kt
new file mode 100644
index 0000000..7623048
--- /dev/null
+++ b/src/com/android/customization/picker/color/ui/binder/ColorPickerBinder.kt
@@ -0,0 +1,97 @@
+/*
+ * 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.ui.binder
+
+import android.view.View
+import android.view.ViewGroup
+import android.widget.TextView
+import androidx.lifecycle.Lifecycle
+import androidx.lifecycle.LifecycleOwner
+import androidx.lifecycle.lifecycleScope
+import androidx.lifecycle.repeatOnLifecycle
+import androidx.recyclerview.widget.LinearLayoutManager
+import androidx.recyclerview.widget.RecyclerView
+import com.android.customization.picker.color.ui.adapter.ColorTypeTabAdapter
+import com.android.customization.picker.color.ui.viewmodel.ColorOptionIconViewModel
+import com.android.customization.picker.color.ui.viewmodel.ColorPickerViewModel
+import com.android.customization.picker.common.ui.view.ItemSpacing
+import com.android.wallpaper.R
+import com.android.wallpaper.picker.option.ui.adapter.OptionItemAdapter
+import kotlinx.coroutines.flow.collect
+import kotlinx.coroutines.flow.map
+import kotlinx.coroutines.launch
+
+object ColorPickerBinder {
+
+ /**
+ * Binds view with view-model for a color picker experience. The view should include a Recycler
+ * View for color type tabs with id [R.id.color_type_tabs] and a Recycler View for color options
+ * with id [R.id.color_options]
+ */
+ @JvmStatic
+ fun bind(
+ view: View,
+ viewModel: ColorPickerViewModel,
+ lifecycleOwner: LifecycleOwner,
+ ) {
+ val colorTypeTabView: RecyclerView = view.requireViewById(R.id.color_type_tabs)
+ val colorTypeTabSubheaderView: TextView = view.requireViewById(R.id.color_type_tab_subhead)
+ val colorOptionContainerView: RecyclerView = view.requireViewById(R.id.color_options)
+
+ val colorTypeTabAdapter = ColorTypeTabAdapter()
+ colorTypeTabView.adapter = colorTypeTabAdapter
+ colorTypeTabView.layoutManager =
+ LinearLayoutManager(view.context, RecyclerView.HORIZONTAL, false)
+ colorTypeTabView.addItemDecoration(ItemSpacing(ItemSpacing.TAB_ITEM_SPACING_DP))
+ val colorOptionAdapter =
+ OptionItemAdapter(
+ layoutResourceId = R.layout.color_option_2,
+ lifecycleOwner = lifecycleOwner,
+ bindIcon = { foregroundView: View, colorIcon: ColorOptionIconViewModel ->
+ val viewGroup = foregroundView as? ViewGroup
+ viewGroup?.let { ColorOptionIconBinder.bind(viewGroup, colorIcon) }
+ }
+ )
+ colorOptionContainerView.adapter = colorOptionAdapter
+ colorOptionContainerView.layoutManager =
+ LinearLayoutManager(view.context, RecyclerView.HORIZONTAL, false)
+ colorOptionContainerView.addItemDecoration(ItemSpacing(ItemSpacing.ITEM_SPACING_DP))
+
+ lifecycleOwner.lifecycleScope.launch {
+ lifecycleOwner.repeatOnLifecycle(Lifecycle.State.STARTED) {
+ launch {
+ viewModel.colorTypeTabs
+ .map { colorTypeById -> colorTypeById.values }
+ .collect { colorTypes -> colorTypeTabAdapter.setItems(colorTypes.toList()) }
+ }
+
+ launch {
+ viewModel.colorTypeTabSubheader.collect { subhead ->
+ colorTypeTabSubheaderView.text = subhead
+ }
+ }
+
+ launch {
+ viewModel.colorOptions.collect { colorOptions ->
+ colorOptionAdapter.setItems(colorOptions)
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/src/com/android/customization/picker/color/ui/binder/ColorSectionViewBinder.kt b/src/com/android/customization/picker/color/ui/binder/ColorSectionViewBinder.kt
new file mode 100644
index 0000000..05b0916
--- /dev/null
+++ b/src/com/android/customization/picker/color/ui/binder/ColorSectionViewBinder.kt
@@ -0,0 +1,131 @@
+/*
+ * 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.ui.binder
+
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import android.widget.ImageView
+import android.widget.LinearLayout
+import androidx.core.view.isVisible
+import androidx.lifecycle.Lifecycle
+import androidx.lifecycle.LifecycleOwner
+import androidx.lifecycle.lifecycleScope
+import androidx.lifecycle.repeatOnLifecycle
+import com.android.customization.picker.color.ui.viewmodel.ColorOptionIconViewModel
+import com.android.customization.picker.color.ui.viewmodel.ColorPickerViewModel
+import com.android.wallpaper.R
+import com.android.wallpaper.picker.option.ui.viewmodel.OptionItemViewModel
+import kotlinx.coroutines.launch
+
+object ColorSectionViewBinder {
+
+ /**
+ * Binds view with view-model for color picker section. The view should include a linear layout
+ * with id [R.id.color_section_option_container]
+ */
+ @JvmStatic
+ fun bind(
+ view: View,
+ viewModel: ColorPickerViewModel,
+ lifecycleOwner: LifecycleOwner,
+ navigationOnClick: (View) -> Unit,
+ isConnectedHorizontallyToOtherSections: Boolean = false,
+ ) {
+ val optionContainer: LinearLayout =
+ view.requireViewById(R.id.color_section_option_container)
+ val moreColorsButton: View = view.requireViewById(R.id.more_colors)
+ if (isConnectedHorizontallyToOtherSections) {
+ moreColorsButton.isVisible = true
+ moreColorsButton.setOnClickListener(navigationOnClick)
+ } else {
+ moreColorsButton.isVisible = false
+ }
+ lifecycleOwner.lifecycleScope.launch {
+ lifecycleOwner.repeatOnLifecycle(Lifecycle.State.STARTED) {
+ launch {
+ viewModel.colorSectionOptions.collect { colorOptions ->
+ setOptions(
+ options = colorOptions,
+ view = optionContainer,
+ lifecycleOwner = lifecycleOwner,
+ addOverflowOption = !isConnectedHorizontallyToOtherSections,
+ overflowOnClick = navigationOnClick,
+ )
+ }
+ }
+ }
+ }
+ }
+
+ fun setOptions(
+ options: List<OptionItemViewModel<ColorOptionIconViewModel>>,
+ view: LinearLayout,
+ lifecycleOwner: LifecycleOwner,
+ addOverflowOption: Boolean = false,
+ overflowOnClick: (View) -> Unit = {},
+ ) {
+ view.removeAllViews()
+ // Color option slot size is the minimum between the color option size and the view column
+ // count. When having an overflow option, a slot is reserved for the overflow option.
+ val colorOptionSlotSize =
+ (if (addOverflowOption) {
+ minOf(view.weightSum.toInt() - 1, options.size)
+ } else {
+ minOf(view.weightSum.toInt(), options.size)
+ })
+ .let { if (it < 0) 0 else it }
+ options.subList(0, colorOptionSlotSize).forEach { item ->
+ val itemView =
+ LayoutInflater.from(view.context)
+ .inflate(R.layout.color_option_no_background, view, false)
+ item.payload?.let { ColorOptionIconBinder.bind(itemView as ViewGroup, item.payload) }
+ val optionSelectedView = itemView.findViewById<ImageView>(R.id.option_selected)
+
+ lifecycleOwner.lifecycleScope.launch {
+ lifecycleOwner.repeatOnLifecycle(Lifecycle.State.STARTED) {
+ launch {
+ item.isSelected.collect { isSelected ->
+ optionSelectedView.isVisible = isSelected
+ }
+ }
+ launch {
+ item.onClicked.collect { onClicked ->
+ itemView.setOnClickListener(
+ if (onClicked != null) {
+ View.OnClickListener { onClicked.invoke() }
+ } else {
+ null
+ }
+ )
+ }
+ }
+ }
+ }
+ view.addView(itemView)
+ }
+ // add overflow option
+ if (addOverflowOption) {
+ val itemView =
+ LayoutInflater.from(view.context)
+ .inflate(R.layout.color_option_overflow_no_background, view, false)
+ itemView.setOnClickListener(overflowOnClick)
+ view.addView(itemView)
+ }
+ }
+}
diff --git a/src/com/android/customization/picker/color/ui/fragment/ColorPickerFragment.kt b/src/com/android/customization/picker/color/ui/fragment/ColorPickerFragment.kt
new file mode 100644
index 0000000..c6b2023
--- /dev/null
+++ b/src/com/android/customization/picker/color/ui/fragment/ColorPickerFragment.kt
@@ -0,0 +1,164 @@
+/*
+ * 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.ui.fragment
+
+import android.os.Bundle
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import android.widget.FrameLayout
+import androidx.cardview.widget.CardView
+import androidx.lifecycle.ViewModelProvider
+import androidx.lifecycle.get
+import com.android.customization.model.mode.DarkModeSectionController
+import com.android.customization.module.ThemePickerInjector
+import com.android.customization.picker.color.ui.binder.ColorPickerBinder
+import com.android.wallpaper.R
+import com.android.wallpaper.module.InjectorProvider
+import com.android.wallpaper.picker.AppbarFragment
+import com.android.wallpaper.picker.customization.ui.binder.ScreenPreviewBinder
+import com.android.wallpaper.picker.customization.ui.viewmodel.ScreenPreviewViewModel
+import com.android.wallpaper.util.DisplayUtils
+import com.android.wallpaper.util.PreviewUtils
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.suspendCancellableCoroutine
+
+@OptIn(ExperimentalCoroutinesApi::class)
+class ColorPickerFragment : AppbarFragment() {
+ companion object {
+ @JvmStatic
+ fun newInstance(): ColorPickerFragment {
+ return ColorPickerFragment()
+ }
+ }
+
+ override fun onCreateView(
+ inflater: LayoutInflater,
+ container: ViewGroup?,
+ savedInstanceState: Bundle?
+ ): View {
+ val view =
+ inflater.inflate(
+ R.layout.fragment_color_picker,
+ container,
+ false,
+ )
+ setUpToolbar(view)
+ val injector = InjectorProvider.getInjector() as ThemePickerInjector
+ val lockScreenView: CardView = view.requireViewById(R.id.lock_preview)
+ val homeScreenView: CardView = view.requireViewById(R.id.home_preview)
+ val wallpaperInfoFactory = injector.getCurrentWallpaperInfoFactory(requireContext())
+ val displayUtils: DisplayUtils = injector.getDisplayUtils(requireContext())
+ val wcViewModel = injector.getWallpaperColorsViewModel()
+ ColorPickerBinder.bind(
+ view = view,
+ viewModel =
+ ViewModelProvider(
+ requireActivity(),
+ injector.getColorPickerViewModelFactory(
+ context = requireContext(),
+ wallpaperColorsViewModel = wcViewModel,
+ ),
+ )
+ .get(),
+ lifecycleOwner = this,
+ )
+ ScreenPreviewBinder.bind(
+ activity = requireActivity(),
+ previewView = lockScreenView,
+ viewModel =
+ ScreenPreviewViewModel(
+ previewUtils =
+ PreviewUtils(
+ context = requireContext(),
+ authority =
+ requireContext()
+ .getString(
+ R.string.lock_screen_preview_provider_authority,
+ ),
+ ),
+ wallpaperInfoProvider = {
+ suspendCancellableCoroutine { continuation ->
+ wallpaperInfoFactory.createCurrentWallpaperInfos(
+ { homeWallpaper, lockWallpaper, _ ->
+ continuation.resume(lockWallpaper ?: homeWallpaper, null)
+ },
+ /* forceRefresh= */ true,
+ )
+ }
+ },
+ onWallpaperColorChanged = { colors ->
+ wcViewModel.setLockWallpaperColors(colors)
+ },
+ ),
+ lifecycleOwner = this,
+ offsetToStart =
+ displayUtils.isSingleDisplayOrUnfoldedHorizontalHinge(requireActivity()),
+ )
+ ScreenPreviewBinder.bind(
+ activity = requireActivity(),
+ previewView = homeScreenView,
+ viewModel =
+ ScreenPreviewViewModel(
+ previewUtils =
+ PreviewUtils(
+ context = requireContext(),
+ authorityMetadataKey =
+ requireContext()
+ .getString(
+ R.string.grid_control_metadata_name,
+ ),
+ ),
+ wallpaperInfoProvider = {
+ suspendCancellableCoroutine { continuation ->
+ wallpaperInfoFactory.createCurrentWallpaperInfos(
+ { homeWallpaper, lockWallpaper, _ ->
+ continuation.resume(homeWallpaper ?: lockWallpaper, null)
+ },
+ /* forceRefresh= */ true,
+ )
+ }
+ },
+ onWallpaperColorChanged = { colors ->
+ wcViewModel.setLockWallpaperColors(colors)
+ },
+ ),
+ lifecycleOwner = this,
+ offsetToStart =
+ displayUtils.isSingleDisplayOrUnfoldedHorizontalHinge(requireActivity()),
+ )
+ val darkModeToggleContainerView: FrameLayout =
+ view.requireViewById(R.id.dark_mode_toggle_container)
+ val darkModeSectionView =
+ DarkModeSectionController(
+ context,
+ lifecycle,
+ injector.getDarkModeSnapshotRestorer(requireContext())
+ )
+ .createView(requireContext())
+ darkModeSectionView.background = null
+ darkModeToggleContainerView.addView(darkModeSectionView)
+ return view
+ }
+
+ override fun getDefaultTitle(): CharSequence {
+ return requireContext().getString(R.string.color_picker_title)
+ }
+
+ override fun getToolbarColorId(): Int {
+ return android.R.color.transparent
+ }
+}
diff --git a/src/com/android/customization/picker/color/ui/section/ColorSectionController2.kt b/src/com/android/customization/picker/color/ui/section/ColorSectionController2.kt
new file mode 100644
index 0000000..f1c982b
--- /dev/null
+++ b/src/com/android/customization/picker/color/ui/section/ColorSectionController2.kt
@@ -0,0 +1,67 @@
+/*
+ * 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.ui.section
+
+import android.content.Context
+import android.view.LayoutInflater
+import androidx.lifecycle.LifecycleOwner
+import com.android.customization.picker.color.ui.binder.ColorSectionViewBinder
+import com.android.customization.picker.color.ui.fragment.ColorPickerFragment
+import com.android.customization.picker.color.ui.view.ColorSectionView2
+import com.android.customization.picker.color.ui.viewmodel.ColorPickerViewModel
+import com.android.wallpaper.R
+import com.android.wallpaper.model.CustomizationSectionController
+import com.android.wallpaper.model.CustomizationSectionController.CustomizationSectionNavigationController as NavigationController
+
+class ColorSectionController2(
+ private val navigationController: NavigationController,
+ private val viewModel: ColorPickerViewModel,
+ private val lifecycleOwner: LifecycleOwner
+) : CustomizationSectionController<ColorSectionView2> {
+
+ override fun isAvailable(context: Context): Boolean {
+ return true
+ }
+
+ override fun createView(context: Context): ColorSectionView2 {
+ return createView(context, CustomizationSectionController.ViewCreationParams())
+ }
+
+ override fun createView(
+ context: Context,
+ params: CustomizationSectionController.ViewCreationParams
+ ): ColorSectionView2 {
+ @SuppressWarnings("It is fine to inflate with null parent for our need.")
+ val view =
+ LayoutInflater.from(context)
+ .inflate(
+ R.layout.color_section_view2,
+ null,
+ ) as ColorSectionView2
+ ColorSectionViewBinder.bind(
+ view = view,
+ viewModel = viewModel,
+ lifecycleOwner = lifecycleOwner,
+ navigationOnClick = {
+ navigationController.navigateTo(ColorPickerFragment.newInstance())
+ },
+ isConnectedHorizontallyToOtherSections = params.isConnectedHorizontallyToOtherSections,
+ )
+ return view
+ }
+}
diff --git a/src/com/android/customization/picker/clock/ClockSectionView.kt b/src/com/android/customization/picker/color/ui/view/ColorSectionView2.kt
similarity index 65%
copy from src/com/android/customization/picker/clock/ClockSectionView.kt
copy to src/com/android/customization/picker/color/ui/view/ColorSectionView2.kt
index fac975a..7a8f21a 100644
--- a/src/com/android/customization/picker/clock/ClockSectionView.kt
+++ b/src/com/android/customization/picker/color/ui/view/ColorSectionView2.kt
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2022 The Android Open Source Project
+ * 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.
@@ -13,11 +13,14 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package com.android.customization.picker.clock
+package com.android.customization.picker.color.ui.view
import android.content.Context
import android.util.AttributeSet
import com.android.wallpaper.picker.SectionView
-/** The [SectionView] for app clock. */
-class ClockSectionView(context: Context?, attrs: AttributeSet?) : SectionView(context, attrs)
+/**
+ * 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)
diff --git a/src/com/android/customization/picker/clock/ClockSectionView.kt b/src/com/android/customization/picker/color/ui/viewmodel/ColorOptionIconViewModel.kt
similarity index 61%
copy from src/com/android/customization/picker/clock/ClockSectionView.kt
copy to src/com/android/customization/picker/color/ui/viewmodel/ColorOptionIconViewModel.kt
index fac975a..d32538d 100644
--- a/src/com/android/customization/picker/clock/ClockSectionView.kt
+++ b/src/com/android/customization/picker/color/ui/viewmodel/ColorOptionIconViewModel.kt
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2022 The Android Open Source Project
+ * 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.
@@ -12,12 +12,16 @@
* 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
-import android.content.Context
-import android.util.AttributeSet
-import com.android.wallpaper.picker.SectionView
+package com.android.customization.picker.color.ui.viewmodel
-/** The [SectionView] for app clock. */
-class ClockSectionView(context: Context?, attrs: AttributeSet?) : SectionView(context, attrs)
+import android.annotation.ColorInt
+
+data class ColorOptionIconViewModel(
+ @ColorInt val color0: Int,
+ @ColorInt val color1: Int,
+ @ColorInt val color2: Int,
+ @ColorInt val color3: Int,
+)
diff --git a/src/com/android/customization/picker/color/ui/viewmodel/ColorOptionViewModel.kt b/src/com/android/customization/picker/color/ui/viewmodel/ColorOptionViewModel.kt
new file mode 100644
index 0000000..7af2aa5
--- /dev/null
+++ b/src/com/android/customization/picker/color/ui/viewmodel/ColorOptionViewModel.kt
@@ -0,0 +1,45 @@
+/*
+ * 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.ui.viewmodel
+
+import android.annotation.ColorInt
+
+/**
+ * Models UI state for a color options in a picker experience.
+ *
+ * TODO (b/272109171): Remove after clock settings is refactored to use OptionItemAdapter
+ */
+data class ColorOptionViewModel(
+ /** Colors for the color option. */
+ @ColorInt val color0: Int,
+ @ColorInt val color1: Int,
+ @ColorInt val color2: Int,
+ @ColorInt val color3: Int,
+
+ /** A content description for the color. */
+ val contentDescription: String,
+
+ /** Nullable option title. Null by default. */
+ val title: String? = null,
+
+ /** Whether this color is selected. */
+ val isSelected: Boolean,
+
+ /** Notifies that the color has been clicked by the user. */
+ val onClick: (() -> Unit)?,
+)
diff --git a/src/com/android/customization/picker/color/ui/viewmodel/ColorPickerViewModel.kt b/src/com/android/customization/picker/color/ui/viewmodel/ColorPickerViewModel.kt
new file mode 100644
index 0000000..81a5810
--- /dev/null
+++ b/src/com/android/customization/picker/color/ui/viewmodel/ColorPickerViewModel.kt
@@ -0,0 +1,253 @@
+/*
+ * 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.ui.viewmodel
+
+import android.content.Context
+import androidx.lifecycle.ViewModel
+import androidx.lifecycle.ViewModelProvider
+import androidx.lifecycle.viewModelScope
+import com.android.customization.model.color.ColorBundle
+import com.android.customization.model.color.ColorSeedOption
+import com.android.customization.picker.color.domain.interactor.ColorPickerInteractor
+import com.android.customization.picker.color.shared.model.ColorType
+import com.android.wallpaper.R
+import com.android.wallpaper.picker.common.text.ui.viewmodel.Text
+import com.android.wallpaper.picker.option.ui.viewmodel.OptionItemViewModel
+import kotlin.math.max
+import kotlin.math.min
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.MutableStateFlow
+import kotlinx.coroutines.flow.StateFlow
+import kotlinx.coroutines.flow.combine
+import kotlinx.coroutines.flow.map
+import kotlinx.coroutines.flow.stateIn
+import kotlinx.coroutines.launch
+
+/** Models UI state for a color picker experience. */
+class ColorPickerViewModel
+private constructor(
+ context: Context,
+ private val interactor: ColorPickerInteractor,
+) : ViewModel() {
+
+ private val selectedColorTypeTabId = MutableStateFlow<ColorType?>(null)
+
+ /** View-models for each color tab. */
+ val colorTypeTabs: Flow<Map<ColorType, ColorTypeTabViewModel>> =
+ combine(
+ interactor.colorOptions,
+ selectedColorTypeTabId,
+ ) { colorOptions, selectedColorTypeIdOrNull ->
+ colorOptions.keys
+ .mapIndexed { index, colorType ->
+ val isSelected =
+ (selectedColorTypeIdOrNull == null && index == 0) ||
+ selectedColorTypeIdOrNull == colorType
+ colorType to
+ ColorTypeTabViewModel(
+ name =
+ when (colorType) {
+ ColorType.WALLPAPER_COLOR ->
+ context.resources.getString(R.string.wallpaper_color_tab)
+ ColorType.PRESET_COLOR ->
+ context.resources.getString(R.string.preset_color_tab_2)
+ },
+ isSelected = isSelected,
+ onClick =
+ if (isSelected) {
+ null
+ } else {
+ { this.selectedColorTypeTabId.value = colorType }
+ },
+ )
+ }
+ .toMap()
+ }
+
+ /** View-models for each color tab subheader */
+ val colorTypeTabSubheader: Flow<String> =
+ selectedColorTypeTabId.map { selectedColorTypeIdOrNull ->
+ when (selectedColorTypeIdOrNull ?: ColorType.WALLPAPER_COLOR) {
+ ColorType.WALLPAPER_COLOR ->
+ context.resources.getString(R.string.wallpaper_color_subheader)
+ ColorType.PRESET_COLOR ->
+ context.resources.getString(R.string.preset_color_subheader)
+ }
+ }
+
+ /** The list of all color options mapped by their color type */
+ private val allColorOptions:
+ Flow<Map<ColorType, List<OptionItemViewModel<ColorOptionIconViewModel>>>> =
+ interactor.colorOptions.map { colorOptions ->
+ colorOptions
+ .map { colorOptionEntry ->
+ colorOptionEntry.key to
+ when (colorOptionEntry.key) {
+ ColorType.WALLPAPER_COLOR -> {
+ colorOptionEntry.value.map { colorOptionModel ->
+ val colorSeedOption: ColorSeedOption =
+ colorOptionModel.colorOption as ColorSeedOption
+ val colors =
+ colorSeedOption.previewInfo.resolveColors(context.resources)
+ val isSelectedFlow: StateFlow<Boolean> =
+ interactor.activeColorOption
+ .map {
+ it?.colorOption?.isEquivalent(
+ colorOptionModel.colorOption
+ )
+ ?: colorOptionModel.isSelected
+ }
+ .stateIn(viewModelScope)
+ OptionItemViewModel<ColorOptionIconViewModel>(
+ key =
+ MutableStateFlow(colorOptionModel.key)
+ as StateFlow<String>,
+ payload =
+ ColorOptionIconViewModel(
+ colors[0],
+ colors[1],
+ colors[2],
+ colors[3]
+ ),
+ text =
+ Text.Loaded(
+ colorSeedOption
+ .getContentDescription(context)
+ .toString()
+ ),
+ isSelected = isSelectedFlow,
+ onClicked =
+ isSelectedFlow.map { isSelected ->
+ if (isSelected) {
+ null
+ } else {
+ {
+ viewModelScope.launch {
+ interactor.select(colorOptionModel)
+ }
+ }
+ }
+ },
+ )
+ }
+ }
+ ColorType.PRESET_COLOR -> {
+ colorOptionEntry.value.map { colorOptionModel ->
+ val colorBundle: ColorBundle =
+ colorOptionModel.colorOption as ColorBundle
+ val primaryColor =
+ colorBundle.previewInfo.resolvePrimaryColor(
+ context.resources
+ )
+ val secondaryColor =
+ colorBundle.previewInfo.resolveSecondaryColor(
+ context.resources
+ )
+ val isSelectedFlow: StateFlow<Boolean> =
+ interactor.activeColorOption
+ .map {
+ it?.colorOption?.isEquivalent(
+ colorOptionModel.colorOption
+ )
+ ?: colorOptionModel.isSelected
+ }
+ .stateIn(viewModelScope)
+ OptionItemViewModel<ColorOptionIconViewModel>(
+ key =
+ MutableStateFlow(colorOptionModel.key)
+ as StateFlow<String>,
+ payload =
+ ColorOptionIconViewModel(
+ primaryColor,
+ secondaryColor,
+ primaryColor,
+ secondaryColor
+ ),
+ text =
+ Text.Loaded(
+ colorBundle
+ .getContentDescription(context)
+ .toString()
+ ),
+ isSelected = isSelectedFlow,
+ onClicked =
+ isSelectedFlow.map { isSelected ->
+ if (isSelected) {
+ null
+ } else {
+ {
+ viewModelScope.launch {
+ interactor.select(colorOptionModel)
+ }
+ }
+ }
+ },
+ )
+ }
+ }
+ }
+ }
+ .toMap()
+ }
+
+ /** The list of all available color options for the selected Color Type. */
+ val colorOptions: Flow<List<OptionItemViewModel<ColorOptionIconViewModel>>> =
+ combine(allColorOptions, selectedColorTypeTabId) {
+ allColorOptions: Map<ColorType, List<OptionItemViewModel<ColorOptionIconViewModel>>>,
+ selectedColorTypeIdOrNull ->
+ val selectedColorTypeId = selectedColorTypeIdOrNull ?: ColorType.WALLPAPER_COLOR
+ allColorOptions[selectedColorTypeId]!!
+ }
+
+ /** The list of color options for the color section */
+ val colorSectionOptions: Flow<List<OptionItemViewModel<ColorOptionIconViewModel>>> =
+ allColorOptions.map { allColorOptions ->
+ val wallpaperOptions = allColorOptions[ColorType.WALLPAPER_COLOR]
+ val presetOptions = allColorOptions[ColorType.PRESET_COLOR]
+ val subOptions =
+ wallpaperOptions!!.subList(0, min(COLOR_SECTION_OPTION_SIZE, wallpaperOptions.size))
+ // Add additional options based on preset colors if size of wallpaper color options is
+ // less than COLOR_SECTION_OPTION_SIZE
+ val additionalSubOptions =
+ presetOptions!!.subList(
+ 0,
+ min(
+ max(0, COLOR_SECTION_OPTION_SIZE - wallpaperOptions.size),
+ presetOptions.size,
+ )
+ )
+ subOptions + additionalSubOptions
+ }
+
+ class Factory(
+ private val context: Context,
+ private val interactor: ColorPickerInteractor,
+ ) : ViewModelProvider.Factory {
+ override fun <T : ViewModel> create(modelClass: Class<T>): T {
+ @Suppress("UNCHECKED_CAST")
+ return ColorPickerViewModel(
+ context = context,
+ interactor = interactor,
+ )
+ as T
+ }
+ }
+
+ companion object {
+ private const val COLOR_SECTION_OPTION_SIZE = 5
+ }
+}
diff --git a/src/com/android/customization/picker/color/ui/viewmodel/ColorTypeTabViewModel.kt b/src/com/android/customization/picker/color/ui/viewmodel/ColorTypeTabViewModel.kt
new file mode 100644
index 0000000..6a789cc
--- /dev/null
+++ b/src/com/android/customization/picker/color/ui/viewmodel/ColorTypeTabViewModel.kt
@@ -0,0 +1,30 @@
+/*
+ * 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.ui.viewmodel
+
+/** Models UI state for a single color type in a picker experience. */
+data class ColorTypeTabViewModel(
+ /** User-visible name for the color type. */
+ val name: String,
+
+ /** Whether this is the currently-selected color type in the picker. */
+ val isSelected: Boolean,
+
+ /** Notifies that the color type has been clicked by the user. */
+ val onClick: (() -> Unit)?,
+)
diff --git a/src/com/android/customization/picker/common/ui/view/ItemSpacing.kt b/src/com/android/customization/picker/common/ui/view/ItemSpacing.kt
new file mode 100644
index 0000000..ca689aa
--- /dev/null
+++ b/src/com/android/customization/picker/common/ui/view/ItemSpacing.kt
@@ -0,0 +1,49 @@
+/*
+ * 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.common.ui.view
+
+import android.graphics.Rect
+import androidx.core.view.ViewCompat
+import androidx.recyclerview.widget.RecyclerView
+
+/** Item spacing used by the RecyclerView. */
+class ItemSpacing(
+ private val itemSpacingDp: Int,
+) : RecyclerView.ItemDecoration() {
+ override fun getItemOffsets(outRect: Rect, itemPosition: Int, parent: RecyclerView) {
+ val addSpacingToStart = itemPosition > 0
+ val addSpacingToEnd = itemPosition < (parent.adapter?.itemCount ?: 0) - 1
+ val isRtl = parent.layoutManager?.layoutDirection == ViewCompat.LAYOUT_DIRECTION_RTL
+ val density = parent.context.resources.displayMetrics.density
+ val halfItemSpacingPx = itemSpacingDp.toPx(density) / 2
+ if (!isRtl) {
+ outRect.left = if (addSpacingToStart) halfItemSpacingPx else 0
+ outRect.right = if (addSpacingToEnd) halfItemSpacingPx else 0
+ } else {
+ outRect.left = if (addSpacingToEnd) halfItemSpacingPx else 0
+ outRect.right = if (addSpacingToStart) halfItemSpacingPx else 0
+ }
+ }
+
+ private fun Int.toPx(density: Float): Int {
+ return (this * density).toInt()
+ }
+
+ companion object {
+ const val TAB_ITEM_SPACING_DP = 12
+ const val ITEM_SPACING_DP = 8
+ }
+}
diff --git a/src/com/android/customization/picker/grid/GridFragment.java b/src/com/android/customization/picker/grid/GridFragment.java
index d60ebca..4de1dab 100644
--- a/src/com/android/customization/picker/grid/GridFragment.java
+++ b/src/com/android/customization/picker/grid/GridFragment.java
@@ -82,6 +82,7 @@
private final Callback mApplyGridCallback = new Callback() {
@Override
public void onSuccess() {
+ mGridManager.fetchOptions(unused -> {}, true);
Toast.makeText(getContext(), R.string.applied_grid_msg, Toast.LENGTH_SHORT).show();
getActivity().overridePendingTransition(R.anim.fade_in, R.anim.fade_out);
getActivity().finish();
@@ -157,7 +158,8 @@
SurfaceView wallpaperSurface = view.findViewById(R.id.wallpaper_preview_surface);
WallpaperPreviewer wallpaperPreviewer = new WallpaperPreviewer(getLifecycle(),
- getActivity(), view.findViewById(R.id.wallpaper_preview_image), wallpaperSurface);
+ getActivity(), view.findViewById(R.id.wallpaper_preview_image), wallpaperSurface,
+ view.findViewById(R.id.grid_fadein_scrim));
// Loads current Wallpaper.
CurrentWallpaperInfoFactory factory = InjectorProvider.getInjector()
.getCurrentWallpaperInfoFactory(getContext().getApplicationContext());
diff --git a/src/com/android/customization/picker/notifications/data/repository/NotificationsRepository.kt b/src/com/android/customization/picker/notifications/data/repository/NotificationsRepository.kt
new file mode 100644
index 0000000..c75ddce
--- /dev/null
+++ b/src/com/android/customization/picker/notifications/data/repository/NotificationsRepository.kt
@@ -0,0 +1,74 @@
+/*
+ * 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.notifications.data.repository
+
+import android.provider.Settings
+import com.android.customization.picker.notifications.shared.model.NotificationSettingsModel
+import com.android.wallpaper.settings.data.repository.SecureSettingsRepository
+import kotlinx.coroutines.CoroutineDispatcher
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.flow.SharedFlow
+import kotlinx.coroutines.flow.SharingStarted
+import kotlinx.coroutines.flow.map
+import kotlinx.coroutines.flow.shareIn
+import kotlinx.coroutines.withContext
+
+/** Provides access to state related to notifications. */
+class NotificationsRepository(
+ scope: CoroutineScope,
+ private val backgroundDispatcher: CoroutineDispatcher,
+ private val secureSettingsRepository: SecureSettingsRepository,
+) {
+ /** The current state of the notification setting. */
+ val settings: SharedFlow<NotificationSettingsModel> =
+ secureSettingsRepository
+ .intSetting(
+ name = Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS,
+ )
+ .map { lockScreenShowNotificationsInt ->
+ NotificationSettingsModel(
+ isShowNotificationsOnLockScreenEnabled = lockScreenShowNotificationsInt == 1,
+ )
+ }
+ .shareIn(
+ scope = scope,
+ started = SharingStarted.WhileSubscribed(),
+ replay = 1,
+ )
+
+ suspend fun getSettings(): NotificationSettingsModel {
+ return withContext(backgroundDispatcher) {
+ NotificationSettingsModel(
+ isShowNotificationsOnLockScreenEnabled =
+ secureSettingsRepository.get(
+ name = Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS,
+ defaultValue = 0,
+ ) == 1
+ )
+ }
+ }
+
+ suspend fun setSettings(model: NotificationSettingsModel) {
+ withContext(backgroundDispatcher) {
+ secureSettingsRepository.set(
+ name = Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS,
+ value = if (model.isShowNotificationsOnLockScreenEnabled) 1 else 0,
+ )
+ }
+ }
+}
diff --git a/src/com/android/customization/picker/notifications/domain/interactor/NotificationsInteractor.kt b/src/com/android/customization/picker/notifications/domain/interactor/NotificationsInteractor.kt
new file mode 100644
index 0000000..1f892f0
--- /dev/null
+++ b/src/com/android/customization/picker/notifications/domain/interactor/NotificationsInteractor.kt
@@ -0,0 +1,52 @@
+/*
+ * 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.notifications.domain.interactor
+
+import com.android.customization.picker.notifications.data.repository.NotificationsRepository
+import com.android.customization.picker.notifications.shared.model.NotificationSettingsModel
+import javax.inject.Provider
+import kotlinx.coroutines.flow.Flow
+
+/** Encapsulates business logic for interacting with notifications. */
+class NotificationsInteractor(
+ private val repository: NotificationsRepository,
+ private val snapshotRestorer: Provider<NotificationsSnapshotRestorer>,
+) {
+ /** The current state of the notification setting. */
+ val settings: Flow<NotificationSettingsModel> = repository.settings
+
+ /** Toggles the setting to show or hide notifications on the lock screen. */
+ suspend fun toggleShowNotificationsOnLockScreenEnabled() {
+ val currentModel = repository.getSettings()
+ setSettings(
+ currentModel.copy(
+ isShowNotificationsOnLockScreenEnabled =
+ !currentModel.isShowNotificationsOnLockScreenEnabled,
+ )
+ )
+ }
+
+ suspend fun setSettings(model: NotificationSettingsModel) {
+ repository.setSettings(model)
+ snapshotRestorer.get().storeSnapshot(model)
+ }
+
+ suspend fun getSettings(): NotificationSettingsModel {
+ return repository.getSettings()
+ }
+}
diff --git a/src/com/android/customization/picker/notifications/domain/interactor/NotificationsSnapshotRestorer.kt b/src/com/android/customization/picker/notifications/domain/interactor/NotificationsSnapshotRestorer.kt
new file mode 100644
index 0000000..c782b74
--- /dev/null
+++ b/src/com/android/customization/picker/notifications/domain/interactor/NotificationsSnapshotRestorer.kt
@@ -0,0 +1,66 @@
+/*
+ * 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.notifications.domain.interactor
+
+import com.android.customization.picker.notifications.shared.model.NotificationSettingsModel
+import com.android.wallpaper.picker.undo.domain.interactor.SnapshotRestorer
+import com.android.wallpaper.picker.undo.domain.interactor.SnapshotStore
+import com.android.wallpaper.picker.undo.shared.model.RestorableSnapshot
+
+/** Handles state restoration for notification settings. */
+class NotificationsSnapshotRestorer(
+ private val interactor: NotificationsInteractor,
+) : SnapshotRestorer {
+
+ private var snapshotStore: SnapshotStore = SnapshotStore.NOOP
+
+ fun storeSnapshot(model: NotificationSettingsModel) {
+ snapshotStore.store(snapshot(model))
+ }
+
+ override suspend fun setUpSnapshotRestorer(
+ store: SnapshotStore,
+ ): RestorableSnapshot {
+ snapshotStore = store
+ return snapshot(interactor.getSettings())
+ }
+
+ override suspend fun restoreToSnapshot(snapshot: RestorableSnapshot) {
+ val isShowNotificationsOnLockScreenEnabled =
+ snapshot.args[KEY_IS_SHOW_NOTIFICATIONS_ON_LOCK_SCREEN_ENABLED]?.toBoolean() ?: false
+ interactor.setSettings(
+ NotificationSettingsModel(
+ isShowNotificationsOnLockScreenEnabled = isShowNotificationsOnLockScreenEnabled,
+ )
+ )
+ }
+
+ private fun snapshot(model: NotificationSettingsModel): RestorableSnapshot {
+ return RestorableSnapshot(
+ mapOf(
+ KEY_IS_SHOW_NOTIFICATIONS_ON_LOCK_SCREEN_ENABLED to
+ model.isShowNotificationsOnLockScreenEnabled.toString(),
+ )
+ )
+ }
+
+ companion object {
+ private const val KEY_IS_SHOW_NOTIFICATIONS_ON_LOCK_SCREEN_ENABLED =
+ "is_show_notifications_on_lock_screen_enabled"
+ }
+}
diff --git a/src/com/android/customization/picker/clock/ClockSectionView.kt b/src/com/android/customization/picker/notifications/shared/model/NotificationSettingsModel.kt
similarity index 61%
copy from src/com/android/customization/picker/clock/ClockSectionView.kt
copy to src/com/android/customization/picker/notifications/shared/model/NotificationSettingsModel.kt
index fac975a..7ce388b 100644
--- a/src/com/android/customization/picker/clock/ClockSectionView.kt
+++ b/src/com/android/customization/picker/notifications/shared/model/NotificationSettingsModel.kt
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2022 The Android Open Source Project
+ * 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.
@@ -12,12 +12,13 @@
* 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
-import android.content.Context
-import android.util.AttributeSet
-import com.android.wallpaper.picker.SectionView
+package com.android.customization.picker.notifications.shared.model
-/** The [SectionView] for app clock. */
-class ClockSectionView(context: Context?, attrs: AttributeSet?) : SectionView(context, attrs)
+/** Models notification settings. */
+data class NotificationSettingsModel(
+ /** Whether notifications are shown on the lock screen. */
+ val isShowNotificationsOnLockScreenEnabled: Boolean = false,
+)
diff --git a/src/com/android/customization/picker/notifications/ui/binder/NotificationSectionBinder.kt b/src/com/android/customization/picker/notifications/ui/binder/NotificationSectionBinder.kt
new file mode 100644
index 0000000..54f9bf6
--- /dev/null
+++ b/src/com/android/customization/picker/notifications/ui/binder/NotificationSectionBinder.kt
@@ -0,0 +1,59 @@
+/*
+ * 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.notifications.ui.binder
+
+import android.annotation.SuppressLint
+import android.view.View
+import android.widget.Switch
+import android.widget.TextView
+import androidx.lifecycle.Lifecycle
+import androidx.lifecycle.LifecycleOwner
+import androidx.lifecycle.lifecycleScope
+import androidx.lifecycle.repeatOnLifecycle
+import com.android.customization.picker.notifications.ui.viewmodel.NotificationSectionViewModel
+import com.android.wallpaper.R
+import kotlinx.coroutines.launch
+
+/**
+ * Binds between view and view-model for a section that lets the user control notification settings.
+ */
+object NotificationSectionBinder {
+ @SuppressLint("UseSwitchCompatOrMaterialCode") // We're using Switch and that's okay for SysUI.
+ fun bind(
+ view: View,
+ viewModel: NotificationSectionViewModel,
+ lifecycleOwner: LifecycleOwner,
+ ) {
+ val subtitle: TextView = view.requireViewById(R.id.subtitle)
+ val switch: Switch = view.requireViewById(R.id.switcher)
+
+ view.setOnClickListener { viewModel.onClicked() }
+
+ lifecycleOwner.lifecycleScope.launch {
+ lifecycleOwner.repeatOnLifecycle(Lifecycle.State.STARTED) {
+ launch {
+ viewModel.subtitleStringResourceId.collect {
+ subtitle.text = view.context.getString(it)
+ }
+ }
+
+ launch { viewModel.isSwitchOn.collect { switch.isChecked = it } }
+ }
+ }
+ }
+}
diff --git a/src/com/android/customization/picker/notifications/ui/section/NotificationSectionController.kt b/src/com/android/customization/picker/notifications/ui/section/NotificationSectionController.kt
new file mode 100644
index 0000000..d35c382
--- /dev/null
+++ b/src/com/android/customization/picker/notifications/ui/section/NotificationSectionController.kt
@@ -0,0 +1,57 @@
+/*
+ * 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.notifications.ui.section
+
+import android.annotation.SuppressLint
+import android.content.Context
+import android.view.LayoutInflater
+import androidx.lifecycle.LifecycleOwner
+import com.android.customization.picker.notifications.ui.binder.NotificationSectionBinder
+import com.android.customization.picker.notifications.ui.view.NotificationSectionView
+import com.android.customization.picker.notifications.ui.viewmodel.NotificationSectionViewModel
+import com.android.wallpaper.R
+import com.android.wallpaper.model.CustomizationSectionController
+
+/** Controls a section with UI that lets the user toggle notification settings. */
+class NotificationSectionController(
+ private val viewModel: NotificationSectionViewModel,
+ private val lifecycleOwner: LifecycleOwner,
+) : CustomizationSectionController<NotificationSectionView> {
+
+ override fun isAvailable(context: Context): Boolean {
+ return true
+ }
+
+ @SuppressLint("InflateParams") // We don't care that the parent is null.
+ override fun createView(context: Context): NotificationSectionView {
+ val view =
+ LayoutInflater.from(context)
+ .inflate(
+ R.layout.notification_section,
+ /* parent= */ null,
+ ) as NotificationSectionView
+
+ NotificationSectionBinder.bind(
+ view = view,
+ viewModel = viewModel,
+ lifecycleOwner = lifecycleOwner,
+ )
+
+ return view
+ }
+}
diff --git a/src/com/android/customization/picker/clock/ClockSectionView.kt b/src/com/android/customization/picker/notifications/ui/view/NotificationSectionView.kt
similarity index 72%
copy from src/com/android/customization/picker/clock/ClockSectionView.kt
copy to src/com/android/customization/picker/notifications/ui/view/NotificationSectionView.kt
index fac975a..29cce0a 100644
--- a/src/com/android/customization/picker/clock/ClockSectionView.kt
+++ b/src/com/android/customization/picker/notifications/ui/view/NotificationSectionView.kt
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2022 The Android Open Source Project
+ * 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.
@@ -12,12 +12,20 @@
* 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
+
+package com.android.customization.picker.notifications.ui.view
import android.content.Context
import android.util.AttributeSet
import com.android.wallpaper.picker.SectionView
-/** The [SectionView] for app clock. */
-class ClockSectionView(context: Context?, attrs: AttributeSet?) : SectionView(context, attrs)
+class NotificationSectionView(
+ context: Context?,
+ attrs: AttributeSet?,
+) :
+ SectionView(
+ context,
+ attrs,
+ )
diff --git a/src/com/android/customization/picker/notifications/ui/viewmodel/NotificationSectionViewModel.kt b/src/com/android/customization/picker/notifications/ui/viewmodel/NotificationSectionViewModel.kt
new file mode 100644
index 0000000..97b0448
--- /dev/null
+++ b/src/com/android/customization/picker/notifications/ui/viewmodel/NotificationSectionViewModel.kt
@@ -0,0 +1,68 @@
+/*
+ * 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.notifications.ui.viewmodel
+
+import androidx.annotation.StringRes
+import androidx.annotation.VisibleForTesting
+import androidx.lifecycle.ViewModel
+import androidx.lifecycle.ViewModelProvider
+import androidx.lifecycle.viewModelScope
+import com.android.customization.picker.notifications.domain.interactor.NotificationsInteractor
+import com.android.wallpaper.R
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.map
+import kotlinx.coroutines.launch
+
+/** Models UI state for a section that lets the user control the notification settings. */
+class NotificationSectionViewModel
+@VisibleForTesting
+constructor(
+ private val interactor: NotificationsInteractor,
+) : ViewModel() {
+
+ /** A string resource ID for the subtitle. */
+ @StringRes
+ val subtitleStringResourceId: Flow<Int> =
+ interactor.settings.map { model ->
+ when (model.isShowNotificationsOnLockScreenEnabled) {
+ true -> R.string.show_notifications_on_lock_screen
+ false -> R.string.hide_notifications_on_lock_screen
+ }
+ }
+
+ /** Whether the switch should be on. */
+ val isSwitchOn: Flow<Boolean> =
+ interactor.settings.map { model -> model.isShowNotificationsOnLockScreenEnabled }
+
+ /** Notifies that the section has been clicked. */
+ fun onClicked() {
+ viewModelScope.launch { interactor.toggleShowNotificationsOnLockScreenEnabled() }
+ }
+
+ class Factory(
+ private val interactor: NotificationsInteractor,
+ ) : ViewModelProvider.Factory {
+ @Suppress("UNCHECKED_CAST")
+ override fun <T : ViewModel> create(modelClass: Class<T>): T {
+ return NotificationSectionViewModel(
+ interactor = interactor,
+ )
+ as T
+ }
+ }
+}
diff --git a/src/com/android/customization/picker/preview/ui/section/PreviewWithClockCarouselSectionController.kt b/src/com/android/customization/picker/preview/ui/section/PreviewWithClockCarouselSectionController.kt
new file mode 100644
index 0000000..a2afc81
--- /dev/null
+++ b/src/com/android/customization/picker/preview/ui/section/PreviewWithClockCarouselSectionController.kt
@@ -0,0 +1,103 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package com.android.customization.picker.preview.ui.section
+
+import android.app.Activity
+import android.content.Context
+import android.view.ViewGroup
+import android.view.ViewStub
+import androidx.lifecycle.LifecycleOwner
+import androidx.lifecycle.lifecycleScope
+import com.android.customization.picker.clock.ui.binder.ClockCarouselViewBinder
+import com.android.customization.picker.clock.ui.view.ClockCarouselView
+import com.android.customization.picker.clock.ui.view.ClockViewFactory
+import com.android.customization.picker.clock.ui.viewmodel.ClockCarouselViewModel
+import com.android.wallpaper.R
+import com.android.wallpaper.model.CustomizationSectionController
+import com.android.wallpaper.model.WallpaperColorsViewModel
+import com.android.wallpaper.module.CurrentWallpaperInfoFactory
+import com.android.wallpaper.module.CustomizationSections
+import com.android.wallpaper.picker.customization.domain.interactor.WallpaperInteractor
+import com.android.wallpaper.picker.customization.ui.section.ScreenPreviewSectionController
+import com.android.wallpaper.picker.customization.ui.section.ScreenPreviewView
+import com.android.wallpaper.util.DisplayUtils
+import kotlinx.coroutines.launch
+
+/** Controls the screen preview section. */
+class PreviewWithClockCarouselSectionController(
+ activity: Activity,
+ private val lifecycleOwner: LifecycleOwner,
+ private val initialScreen: CustomizationSections.Screen,
+ wallpaperInfoFactory: CurrentWallpaperInfoFactory,
+ colorViewModel: WallpaperColorsViewModel,
+ displayUtils: DisplayUtils,
+ private val clockCarouselViewModel: ClockCarouselViewModel,
+ private val clockViewFactory: ClockViewFactory,
+ navigator: CustomizationSectionController.CustomizationSectionNavigationController,
+ wallpaperInteractor: WallpaperInteractor,
+) :
+ ScreenPreviewSectionController(
+ activity,
+ lifecycleOwner,
+ initialScreen,
+ wallpaperInfoFactory,
+ colorViewModel,
+ displayUtils,
+ navigator,
+ wallpaperInteractor,
+ ) {
+
+ private var clockCarouselBinding: ClockCarouselViewBinder.Binding? = null
+
+ override val hideLockScreenClockPreview = true
+
+ override fun createView(context: Context): ScreenPreviewView {
+ val view = super.createView(context)
+ val carouselViewStub: ViewStub = view.requireViewById(R.id.clock_carousel_view_stub)
+ carouselViewStub.layoutResource = R.layout.clock_carousel_view
+ val carouselView = carouselViewStub.inflate() as ClockCarouselView
+
+ // TODO (b/270716937) We should handle the single clock case in the clock carousel itself
+ val singleClockViewStub: ViewStub = view.requireViewById(R.id.single_clock_view_stub)
+ singleClockViewStub.layoutResource = R.layout.single_clock_view
+ val singleClockView = singleClockViewStub.inflate() as ViewGroup
+ lifecycleOwner.lifecycleScope.launch {
+ clockCarouselBinding =
+ ClockCarouselViewBinder.bind(
+ carouselView = carouselView,
+ singleClockView = singleClockView,
+ viewModel = clockCarouselViewModel,
+ clockViewFactory = clockViewFactory,
+ lifecycleOwner = lifecycleOwner,
+ )
+ onScreenSwitched(
+ isOnLockScreen = initialScreen == CustomizationSections.Screen.LOCK_SCREEN
+ )
+ }
+ return view
+ }
+
+ override fun onScreenSwitched(isOnLockScreen: Boolean) {
+ super.onScreenSwitched(isOnLockScreen)
+ if (isOnLockScreen) {
+ clockCarouselBinding?.show()
+ } else {
+ clockCarouselBinding?.hide()
+ }
+ }
+}
diff --git a/src/com/android/customization/picker/quickaffordance/data/repository/KeyguardQuickAffordancePickerRepository.kt b/src/com/android/customization/picker/quickaffordance/data/repository/KeyguardQuickAffordancePickerRepository.kt
index fd553fe..c432bd9 100644
--- a/src/com/android/customization/picker/quickaffordance/data/repository/KeyguardQuickAffordancePickerRepository.kt
+++ b/src/com/android/customization/picker/quickaffordance/data/repository/KeyguardQuickAffordancePickerRepository.kt
@@ -83,6 +83,7 @@
enablementInstructions = enablementInstructions ?: emptyList(),
enablementActionText = enablementActionText,
enablementActionComponentName = enablementActionComponentName,
+ configureIntent = configureIntent,
)
}
diff --git a/src/com/android/customization/picker/quickaffordance/domain/interactor/KeyguardQuickAffordancePickerInteractor.kt b/src/com/android/customization/picker/quickaffordance/domain/interactor/KeyguardQuickAffordancePickerInteractor.kt
index fbe303b..f154de6 100644
--- a/src/com/android/customization/picker/quickaffordance/domain/interactor/KeyguardQuickAffordancePickerInteractor.kt
+++ b/src/com/android/customization/picker/quickaffordance/domain/interactor/KeyguardQuickAffordancePickerInteractor.kt
@@ -63,16 +63,6 @@
snapshotRestorer.get().storeSnapshot()
}
- /** Unselects an affordance with the given ID from the slot with the given ID. */
- suspend fun unselect(slotId: String, affordanceId: String) {
- client.deleteSelection(
- slotId = slotId,
- affordanceId = affordanceId,
- )
-
- snapshotRestorer.get().storeSnapshot()
- }
-
/** Unselects all affordances from the slot with the given ID. */
suspend fun unselectAll(slotId: String) {
client.deleteAllSelections(
diff --git a/src/com/android/customization/picker/quickaffordance/domain/interactor/KeyguardQuickAffordanceSnapshotRestorer.kt b/src/com/android/customization/picker/quickaffordance/domain/interactor/KeyguardQuickAffordanceSnapshotRestorer.kt
index cb2dbdc..3c7928c 100644
--- a/src/com/android/customization/picker/quickaffordance/domain/interactor/KeyguardQuickAffordanceSnapshotRestorer.kt
+++ b/src/com/android/customization/picker/quickaffordance/domain/interactor/KeyguardQuickAffordanceSnapshotRestorer.kt
@@ -19,6 +19,7 @@
import com.android.systemui.shared.customization.data.content.CustomizationProviderClient
import com.android.wallpaper.picker.undo.domain.interactor.SnapshotRestorer
+import com.android.wallpaper.picker.undo.domain.interactor.SnapshotStore
import com.android.wallpaper.picker.undo.shared.model.RestorableSnapshot
/** Handles state restoration for the quick affordances system. */
@@ -27,16 +28,16 @@
private val client: CustomizationProviderClient,
) : SnapshotRestorer {
- private lateinit var snapshotUpdater: (RestorableSnapshot) -> Unit
+ private var snapshotStore: SnapshotStore = SnapshotStore.NOOP
suspend fun storeSnapshot() {
- snapshotUpdater(snapshot())
+ snapshotStore.store(snapshot())
}
override suspend fun setUpSnapshotRestorer(
- updater: (RestorableSnapshot) -> Unit,
+ store: SnapshotStore,
): RestorableSnapshot {
- snapshotUpdater = updater
+ snapshotStore = store
return snapshot()
}
diff --git a/src/com/android/customization/picker/quickaffordance/shared/model/KeyguardQuickAffordancePickerAffordanceModel.kt b/src/com/android/customization/picker/quickaffordance/shared/model/KeyguardQuickAffordancePickerAffordanceModel.kt
index 1b18af7..7b04ff1 100644
--- a/src/com/android/customization/picker/quickaffordance/shared/model/KeyguardQuickAffordancePickerAffordanceModel.kt
+++ b/src/com/android/customization/picker/quickaffordance/shared/model/KeyguardQuickAffordancePickerAffordanceModel.kt
@@ -17,6 +17,7 @@
package com.android.customization.picker.quickaffordance.shared.model
+import android.content.Intent
import androidx.annotation.DrawableRes
/** Models a quick affordance. */
@@ -42,4 +43,6 @@
* user to a destination where they can re-enable it.
*/
val enablementActionComponentName: String?,
+ /** Optional [Intent] to use to start an activity to configure this affordance. */
+ val configureIntent: Intent?,
)
diff --git a/src/com/android/customization/picker/quickaffordance/ui/adapter/AffordancesAdapter.kt b/src/com/android/customization/picker/quickaffordance/ui/adapter/AffordancesAdapter.kt
deleted file mode 100644
index b0dc350..0000000
--- a/src/com/android/customization/picker/quickaffordance/ui/adapter/AffordancesAdapter.kt
+++ /dev/null
@@ -1,95 +0,0 @@
-/*
- * Copyright (C) 2022 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.quickaffordance.ui.adapter
-
-import android.view.LayoutInflater
-import android.view.View
-import android.view.ViewGroup
-import android.widget.ImageView
-import android.widget.TextView
-import androidx.recyclerview.widget.RecyclerView
-import com.android.customization.picker.quickaffordance.ui.viewmodel.KeyguardQuickAffordanceViewModel
-import com.android.wallpaper.R
-
-/** Adapts between lock screen quick affordance items and views. */
-class AffordancesAdapter : RecyclerView.Adapter<AffordancesAdapter.ViewHolder>() {
-
- private val items = mutableListOf<KeyguardQuickAffordanceViewModel>()
-
- fun setItems(items: List<KeyguardQuickAffordanceViewModel>) {
- this.items.clear()
- this.items.addAll(items)
- notifyDataSetChanged()
- }
-
- class ViewHolder(itemView: View) : RecyclerView.ViewHolder(itemView) {
- val iconContainerView: View = itemView.requireViewById(R.id.icon_container)
- val iconView: ImageView = itemView.requireViewById(R.id.icon)
- val nameView: TextView = itemView.requireViewById(R.id.name)
- }
-
- override fun getItemCount(): Int {
- return items.size
- }
-
- override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder {
- return ViewHolder(
- LayoutInflater.from(parent.context)
- .inflate(
- R.layout.keyguard_quick_affordance,
- parent,
- false,
- )
- )
- }
-
- override fun onBindViewHolder(holder: ViewHolder, position: Int) {
- val item = items[position]
- holder.itemView.alpha =
- if (item.isEnabled) {
- ALPHA_ENABLED
- } else {
- ALPHA_DISABLED
- }
-
- holder.itemView.setOnClickListener(
- if (item.onClicked != null) {
- View.OnClickListener { item.onClicked.invoke() }
- } else {
- null
- }
- )
- holder.iconContainerView.setBackgroundResource(
- if (item.isSelected) {
- R.drawable.keyguard_quick_affordance_icon_container_background_selected
- } else {
- R.drawable.keyguard_quick_affordance_icon_container_background
- }
- )
- holder.iconView.isSelected = item.isSelected
- holder.nameView.isSelected = item.isSelected
- holder.iconView.setImageDrawable(item.icon)
- holder.nameView.text = item.contentDescription
- holder.nameView.isSelected = item.isSelected
- }
-
- companion object {
- private const val ALPHA_ENABLED = 1f
- private const val ALPHA_DISABLED = 0.3f
- }
-}
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/picker/quickaffordance/ui/binder/KeyguardQuickAffordanceEnablementDialogBinder.kt b/src/com/android/customization/picker/quickaffordance/ui/binder/KeyguardQuickAffordanceEnablementDialogBinder.kt
deleted file mode 100644
index 809e09d..0000000
--- a/src/com/android/customization/picker/quickaffordance/ui/binder/KeyguardQuickAffordanceEnablementDialogBinder.kt
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Copyright (C) 2022 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.quickaffordance.ui.binder
-
-import android.view.View
-import android.widget.ImageView
-import android.widget.TextView
-import com.android.customization.picker.quickaffordance.ui.viewmodel.KeyguardQuickAffordancePickerViewModel
-import com.android.wallpaper.R
-
-object KeyguardQuickAffordanceEnablementDialogBinder {
-
- fun bind(
- view: View,
- viewModel: KeyguardQuickAffordancePickerViewModel.DialogViewModel,
- onDismissed: () -> Unit,
- ) {
- view.requireViewById<ImageView>(R.id.icon).setImageDrawable(viewModel.icon)
- view.requireViewById<TextView>(R.id.title).text =
- view.context.getString(
- R.string.keyguard_affordance_enablement_dialog_title,
- viewModel.name
- )
- view.requireViewById<TextView>(R.id.message).text = buildString {
- viewModel.instructions.forEachIndexed { index, instruction ->
- append(instruction)
- if (index < viewModel.instructions.size - 1) {
- append("\n")
- }
- }
- }
- view.requireViewById<TextView>(R.id.button).apply {
- text = viewModel.actionText
- setOnClickListener {
- if (viewModel.intent != null) {
- view.context.startActivity(viewModel.intent)
- } else {
- onDismissed()
- }
- }
- }
- }
-}
diff --git a/src/com/android/customization/picker/quickaffordance/ui/binder/KeyguardQuickAffordancePickerBinder.kt b/src/com/android/customization/picker/quickaffordance/ui/binder/KeyguardQuickAffordancePickerBinder.kt
index 389f8f6..4395f5e 100644
--- a/src/com/android/customization/picker/quickaffordance/ui/binder/KeyguardQuickAffordancePickerBinder.kt
+++ b/src/com/android/customization/picker/quickaffordance/ui/binder/KeyguardQuickAffordancePickerBinder.kt
@@ -17,27 +17,33 @@
package com.android.customization.picker.quickaffordance.ui.binder
-import android.app.AlertDialog
import android.app.Dialog
import android.content.Context
-import android.graphics.Rect
-import android.view.LayoutInflater
import android.view.View
-import androidx.core.view.ViewCompat
+import android.widget.ImageView
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.lifecycleScope
import androidx.lifecycle.repeatOnLifecycle
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
-import com.android.customization.picker.quickaffordance.ui.adapter.AffordancesAdapter
+import com.android.customization.picker.common.ui.view.ItemSpacing
import com.android.customization.picker.quickaffordance.ui.adapter.SlotTabAdapter
import com.android.customization.picker.quickaffordance.ui.viewmodel.KeyguardQuickAffordancePickerViewModel
import com.android.wallpaper.R
+import com.android.wallpaper.picker.common.dialog.ui.viewbinder.DialogViewBinder
+import com.android.wallpaper.picker.common.dialog.ui.viewmodel.DialogViewModel
+import com.android.wallpaper.picker.common.icon.ui.viewbinder.IconViewBinder
+import com.android.wallpaper.picker.common.icon.ui.viewmodel.Icon
+import com.android.wallpaper.picker.option.ui.adapter.OptionItemAdapter
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.flow.combine
import kotlinx.coroutines.flow.distinctUntilChanged
+import kotlinx.coroutines.flow.flatMapLatest
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.launch
+@OptIn(ExperimentalCoroutinesApi::class)
object KeyguardQuickAffordancePickerBinder {
/** Binds view with view-model for a lock screen quick affordance picker experience. */
@@ -54,12 +60,20 @@
slotTabView.adapter = slotTabAdapter
slotTabView.layoutManager =
LinearLayoutManager(view.context, RecyclerView.HORIZONTAL, false)
- slotTabView.addItemDecoration(ItemSpacing())
- val affordancesAdapter = AffordancesAdapter()
+ slotTabView.addItemDecoration(ItemSpacing(ItemSpacing.TAB_ITEM_SPACING_DP))
+ val affordancesAdapter =
+ OptionItemAdapter(
+ layoutResourceId = R.layout.keyguard_quick_affordance,
+ lifecycleOwner = lifecycleOwner,
+ bindIcon = { foregroundView: View, gridIcon: Icon ->
+ val imageView = foregroundView as? ImageView
+ imageView?.let { IconViewBinder.bind(imageView, gridIcon) }
+ }
+ )
affordancesView.adapter = affordancesAdapter
affordancesView.layoutManager =
LinearLayoutManager(view.context, RecyclerView.HORIZONTAL, false)
- affordancesView.addItemDecoration(ItemSpacing())
+ affordancesView.addItemDecoration(ItemSpacing(ItemSpacing.ITEM_SPACING_DP))
var dialog: Dialog? = null
@@ -78,6 +92,26 @@
}
launch {
+ viewModel.quickAffordances
+ .flatMapLatest { affordances ->
+ combine(affordances.map { affordance -> affordance.isSelected }) {
+ selectedFlags ->
+ selectedFlags.indexOfFirst { it }
+ }
+ }
+ .collect { selectedPosition ->
+ // Scroll the view to show the first selected affordance.
+ if (selectedPosition != -1) {
+ // We use "post" because we need to give the adapter item a pass to
+ // update the view.
+ affordancesView.post {
+ affordancesView.smoothScrollToPosition(selectedPosition)
+ }
+ }
+ }
+ }
+
+ launch {
viewModel.dialog.distinctUntilChanged().collect { dialogRequest ->
dialog?.dismiss()
dialog =
@@ -98,48 +132,13 @@
private fun showDialog(
context: Context,
- request: KeyguardQuickAffordancePickerViewModel.DialogViewModel,
+ request: DialogViewModel,
onDismissed: () -> Unit,
): Dialog {
- val view: View =
- LayoutInflater.from(context)
- .inflate(
- R.layout.keyguard_quick_affordance_enablement_dialog,
- null,
- )
- KeyguardQuickAffordanceEnablementDialogBinder.bind(
- view = view,
+ return DialogViewBinder.show(
+ context = context,
viewModel = request,
onDismissed = onDismissed,
)
-
- return AlertDialog.Builder(context, R.style.LightDialogTheme)
- .setView(view)
- .setOnDismissListener { onDismissed() }
- .show()
- }
-
- private class ItemSpacing : RecyclerView.ItemDecoration() {
- override fun getItemOffsets(outRect: Rect, itemPosition: Int, parent: RecyclerView) {
- val addSpacingToStart = itemPosition > 0
- val addSpacingToEnd = itemPosition < (parent.adapter?.itemCount ?: 0) - 1
- val isRtl = parent.layoutManager?.layoutDirection == ViewCompat.LAYOUT_DIRECTION_RTL
- val density = parent.context.resources.displayMetrics.density
- if (!isRtl) {
- outRect.left = if (addSpacingToStart) ITEM_SPACING_DP.toPx(density) else 0
- outRect.right = if (addSpacingToEnd) ITEM_SPACING_DP.toPx(density) else 0
- } else {
- outRect.left = if (addSpacingToEnd) ITEM_SPACING_DP.toPx(density) else 0
- outRect.right = if (addSpacingToStart) ITEM_SPACING_DP.toPx(density) else 0
- }
- }
-
- private fun Int.toPx(density: Float): Int {
- return (this * density).toInt()
- }
-
- companion object {
- private const val ITEM_SPACING_DP = 8
- }
}
}
diff --git a/src/com/android/customization/picker/quickaffordance/ui/binder/KeyguardQuickAffordancePreviewBinder.kt b/src/com/android/customization/picker/quickaffordance/ui/binder/KeyguardQuickAffordancePreviewBinder.kt
index 9248d66..58a082d 100644
--- a/src/com/android/customization/picker/quickaffordance/ui/binder/KeyguardQuickAffordancePreviewBinder.kt
+++ b/src/com/android/customization/picker/quickaffordance/ui/binder/KeyguardQuickAffordancePreviewBinder.kt
@@ -48,6 +48,7 @@
viewModel = viewModel.preview,
lifecycleOwner = lifecycleOwner,
offsetToStart = offsetToStart,
+ dimWallpaper = true,
)
previewView.contentDescription =
diff --git a/src/com/android/customization/picker/quickaffordance/ui/binder/KeyguardQuickAffordanceSectionViewBinder.kt b/src/com/android/customization/picker/quickaffordance/ui/binder/KeyguardQuickAffordanceSectionViewBinder.kt
index c8880b9..28ad51a 100644
--- a/src/com/android/customization/picker/quickaffordance/ui/binder/KeyguardQuickAffordanceSectionViewBinder.kt
+++ b/src/com/android/customization/picker/quickaffordance/ui/binder/KeyguardQuickAffordanceSectionViewBinder.kt
@@ -27,6 +27,8 @@
import androidx.lifecycle.lifecycleScope
import com.android.customization.picker.quickaffordance.ui.viewmodel.KeyguardQuickAffordancePickerViewModel
import com.android.wallpaper.R
+import com.android.wallpaper.picker.common.icon.ui.viewbinder.IconViewBinder
+import com.android.wallpaper.picker.common.text.ui.viewbinder.TextViewBinder
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.launch
@@ -48,12 +50,25 @@
viewModel.summary
.flowWithLifecycle(lifecycleOwner.lifecycle, Lifecycle.State.RESUMED)
.collectLatest { summary ->
- descriptionView.text = summary.description
+ TextViewBinder.bind(
+ view = descriptionView,
+ viewModel = summary.description,
+ )
- icon1.setImageDrawable(summary.icon1)
+ if (summary.icon1 != null) {
+ IconViewBinder.bind(
+ view = icon1,
+ viewModel = summary.icon1,
+ )
+ }
icon1.isVisible = summary.icon1 != null
- icon2.setImageDrawable(summary.icon2)
+ if (summary.icon2 != null) {
+ IconViewBinder.bind(
+ view = icon2,
+ viewModel = summary.icon2,
+ )
+ }
icon2.isVisible = summary.icon2 != null
}
}
diff --git a/src/com/android/customization/picker/quickaffordance/ui/fragment/KeyguardQuickAffordancePickerFragment.kt b/src/com/android/customization/picker/quickaffordance/ui/fragment/KeyguardQuickAffordancePickerFragment.kt
index 51b98ef..d5f0d33 100644
--- a/src/com/android/customization/picker/quickaffordance/ui/fragment/KeyguardQuickAffordancePickerFragment.kt
+++ b/src/com/android/customization/picker/quickaffordance/ui/fragment/KeyguardQuickAffordancePickerFragment.kt
@@ -30,7 +30,6 @@
import com.android.wallpaper.R
import com.android.wallpaper.module.InjectorProvider
import com.android.wallpaper.picker.AppbarFragment
-import com.android.wallpaper.picker.undo.ui.binder.RevertToolbarButtonBinder
import kotlinx.coroutines.ExperimentalCoroutinesApi
@OptIn(ExperimentalCoroutinesApi::class)
@@ -62,12 +61,6 @@
injector.getKeyguardQuickAffordancePickerViewModelFactory(requireContext()),
)
.get()
- setUpToolbarMenu(R.menu.undoable_customization_menu)
- RevertToolbarButtonBinder.bind(
- view = view.requireViewById(toolbarId),
- viewModel = viewModel.undo,
- lifecycleOwner = this,
- )
KeyguardQuickAffordancePreviewBinder.bind(
activity = requireActivity(),
@@ -75,7 +68,9 @@
viewModel = viewModel,
lifecycleOwner = this,
offsetToStart =
- injector.getDisplayUtils(requireActivity()).isOnWallpaperDisplay(requireActivity())
+ requireActivity().let {
+ injector.getDisplayUtils(it).isSingleDisplayOrUnfoldedHorizontalHinge(it)
+ }
)
KeyguardQuickAffordancePickerBinder.bind(
view = view,
@@ -88,4 +83,8 @@
override fun getDefaultTitle(): CharSequence {
return requireContext().getString(R.string.keyguard_quick_affordance_title)
}
+
+ override fun getToolbarColorId(): Int {
+ return android.R.color.transparent
+ }
}
diff --git a/src/com/android/customization/picker/quickaffordance/ui/section/KeyguardQuickAffordanceSectionController.kt b/src/com/android/customization/picker/quickaffordance/ui/section/KeyguardQuickAffordanceSectionController.kt
index 6b35d7c..e0beeff 100644
--- a/src/com/android/customization/picker/quickaffordance/ui/section/KeyguardQuickAffordanceSectionController.kt
+++ b/src/com/android/customization/picker/quickaffordance/ui/section/KeyguardQuickAffordanceSectionController.kt
@@ -39,11 +39,11 @@
private val isFeatureEnabled: Boolean = runBlocking { interactor.isFeatureEnabled() }
- override fun isAvailable(context: Context?): Boolean {
+ override fun isAvailable(context: Context): Boolean {
return isFeatureEnabled
}
- override fun createView(context: Context?): KeyguardQuickAffordanceSectionView {
+ override fun createView(context: Context): KeyguardQuickAffordanceSectionView {
val view =
LayoutInflater.from(context)
.inflate(
diff --git a/src/com/android/customization/picker/quickaffordance/ui/viewmodel/KeyguardQuickAffordancePickerViewModel.kt b/src/com/android/customization/picker/quickaffordance/ui/viewmodel/KeyguardQuickAffordancePickerViewModel.kt
index d879045..14b6acc 100644
--- a/src/com/android/customization/picker/quickaffordance/ui/viewmodel/KeyguardQuickAffordancePickerViewModel.kt
+++ b/src/com/android/customization/picker/quickaffordance/ui/viewmodel/KeyguardQuickAffordancePickerViewModel.kt
@@ -32,17 +32,25 @@
import com.android.systemui.shared.quickaffordance.shared.model.KeyguardQuickAffordancePreviewConstants
import com.android.wallpaper.R
import com.android.wallpaper.module.CurrentWallpaperInfoFactory
+import com.android.wallpaper.picker.common.button.ui.viewmodel.ButtonStyle
+import com.android.wallpaper.picker.common.button.ui.viewmodel.ButtonViewModel
+import com.android.wallpaper.picker.common.dialog.ui.viewmodel.DialogViewModel
+import com.android.wallpaper.picker.common.icon.ui.viewmodel.Icon
+import com.android.wallpaper.picker.common.text.ui.viewmodel.Text
import com.android.wallpaper.picker.customization.ui.viewmodel.ScreenPreviewViewModel
-import com.android.wallpaper.picker.undo.domain.interactor.UndoInteractor
-import com.android.wallpaper.picker.undo.ui.viewmodel.UndoViewModel
+import com.android.wallpaper.picker.option.ui.viewmodel.OptionItemViewModel
import com.android.wallpaper.util.PreviewUtils
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.MutableStateFlow
+import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.flow.combine
+import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.flow.map
+import kotlinx.coroutines.flow.shareIn
+import kotlinx.coroutines.flow.stateIn
import kotlinx.coroutines.launch
import kotlinx.coroutines.suspendCancellableCoroutine
@@ -52,8 +60,8 @@
private constructor(
context: Context,
private val quickAffordanceInteractor: KeyguardQuickAffordancePickerInteractor,
- undoInteractor: UndoInteractor,
private val wallpaperInfoFactory: CurrentWallpaperInfoFactory,
+ activityStarter: (Intent) -> Unit,
) : ViewModel() {
@SuppressLint("StaticFieldLeak") private val applicationContext = context.applicationContext
@@ -74,6 +82,10 @@
KeyguardQuickAffordancePreviewConstants.KEY_INITIALLY_SELECTED_SLOT_ID,
selectedSlotId.value,
)
+ putBoolean(
+ KeyguardQuickAffordancePreviewConstants.KEY_HIGHLIGHT_QUICK_AFFORDANCES,
+ true,
+ )
}
},
wallpaperInfoProvider = {
@@ -88,13 +100,27 @@
},
)
- val undo: UndoViewModel =
- UndoViewModel(
- interactor = undoInteractor,
- )
-
+ /** A locally-selected slot, if the user ever switched from the original one. */
private val _selectedSlotId = MutableStateFlow<String?>(null)
- val selectedSlotId: StateFlow<String?> = _selectedSlotId.asStateFlow()
+ /** The ID of the selected slot. */
+ val selectedSlotId: StateFlow<String> =
+ combine(
+ quickAffordanceInteractor.slots,
+ _selectedSlotId,
+ ) { slots, selectedSlotIdOrNull ->
+ if (selectedSlotIdOrNull != null) {
+ slots.first { slot -> slot.id == selectedSlotIdOrNull }
+ } else {
+ // If we haven't yet selected a new slot locally, default to the first slot.
+ slots[0]
+ }
+ }
+ .map { selectedSlot -> selectedSlot.id }
+ .stateIn(
+ scope = viewModelScope,
+ started = SharingStarted.WhileSubscribed(),
+ initialValue = "",
+ )
/** View-models for each slot, keyed by slot ID. */
val slots: Flow<Map<String, KeyguardQuickAffordanceSlotViewModel>> =
@@ -103,94 +129,132 @@
quickAffordanceInteractor.affordances,
quickAffordanceInteractor.selections,
selectedSlotId,
- ) { slots, affordances, selections, selectedSlotIdOrNull ->
- slots
- .mapIndexed { index, slot ->
- val selectedAffordanceIds =
- selections
- .filter { selection -> selection.slotId == slot.id }
- .map { selection -> selection.affordanceId }
- .toSet()
- val selectedAffordances =
- affordances.filter { affordance ->
- selectedAffordanceIds.contains(affordance.id)
- }
- val isSelected =
- (selectedSlotIdOrNull == null && index == 0) ||
- selectedSlotIdOrNull == slot.id
- slot.id to
- KeyguardQuickAffordanceSlotViewModel(
- name = getSlotName(slot.id),
- isSelected = isSelected,
- selectedQuickAffordances =
- selectedAffordances.map { affordanceModel ->
- KeyguardQuickAffordanceViewModel(
- icon = getAffordanceIcon(affordanceModel.iconResourceId),
- contentDescription = affordanceModel.name,
- isSelected = true,
- onClicked = null,
- isEnabled = affordanceModel.isEnabled,
- )
- },
- maxSelectedQuickAffordances = slot.maxSelectedQuickAffordances,
- onClicked =
- if (isSelected) {
- null
- } else {
- { _selectedSlotId.tryEmit(slot.id) }
- },
- )
- }
- .toMap()
+ ) { slots, affordances, selections, selectedSlotId ->
+ slots.associate { slot ->
+ val selectedAffordanceIds =
+ selections
+ .filter { selection -> selection.slotId == slot.id }
+ .map { selection -> selection.affordanceId }
+ .toSet()
+ val selectedAffordances =
+ affordances.filter { affordance ->
+ selectedAffordanceIds.contains(affordance.id)
+ }
+ val isSelected = selectedSlotId == slot.id
+ slot.id to
+ KeyguardQuickAffordanceSlotViewModel(
+ name = getSlotName(slot.id),
+ isSelected = isSelected,
+ selectedQuickAffordances =
+ selectedAffordances.map { affordanceModel ->
+ OptionItemViewModel<Icon>(
+ key =
+ MutableStateFlow("${slot.id}::${affordanceModel.id}")
+ as StateFlow<String>,
+ payload =
+ Icon.Loaded(
+ drawable =
+ getAffordanceIcon(affordanceModel.iconResourceId),
+ contentDescription = null,
+ ),
+ text = Text.Loaded(affordanceModel.name),
+ isSelected = MutableStateFlow(true) as StateFlow<Boolean>,
+ onClicked = flowOf(null),
+ onLongClicked = null,
+ isEnabled = true,
+ )
+ },
+ maxSelectedQuickAffordances = slot.maxSelectedQuickAffordances,
+ onClicked =
+ if (isSelected) {
+ null
+ } else {
+ { _selectedSlotId.tryEmit(slot.id) }
+ },
+ )
+ }
}
- /** The list of all available quick affordances for the selected slot. */
- val quickAffordances: Flow<List<KeyguardQuickAffordanceViewModel>> =
+ /**
+ * The set of IDs of the currently-selected affordances. These change with user selection of new
+ * or different affordances in the currently-selected slot or when slot selection changes.
+ */
+ private val selectedAffordanceIds: Flow<Set<String>> =
combine(
- quickAffordanceInteractor.slots,
- quickAffordanceInteractor.affordances,
- quickAffordanceInteractor.selections,
- selectedSlotId,
- ) { slots, affordances, selections, selectedSlotIdOrNull ->
- val selectedSlot =
- selectedSlotIdOrNull?.let { slots.find { slot -> slot.id == it } } ?: slots.first()
- val selectedAffordanceIds =
+ quickAffordanceInteractor.selections,
+ selectedSlotId,
+ ) { selections, selectedSlotId ->
selections
- .filter { selection -> selection.slotId == selectedSlot.id }
+ .filter { selection -> selection.slotId == selectedSlotId }
.map { selection -> selection.affordanceId }
.toSet()
+ }
+ .shareIn(
+ scope = viewModelScope,
+ started = SharingStarted.WhileSubscribed(),
+ replay = 1,
+ )
+
+ /** The list of all available quick affordances for the selected slot. */
+ val quickAffordances: Flow<List<OptionItemViewModel<Icon>>> =
+ quickAffordanceInteractor.affordances.map { affordances ->
+ val isNoneSelected = selectedAffordanceIds.map { it.isEmpty() }.stateIn(viewModelScope)
listOf(
none(
- slotId = selectedSlot.id,
- isSelected = selectedAffordanceIds.isEmpty(),
- )
- ) +
- affordances.map { affordance ->
- val isSelected = selectedAffordanceIds.contains(affordance.id)
- val affordanceIcon = getAffordanceIcon(affordance.iconResourceId)
- KeyguardQuickAffordanceViewModel(
- icon = affordanceIcon,
- contentDescription = affordance.name,
- isSelected = isSelected,
- onClicked =
- if (affordance.isEnabled) {
+ slotId = selectedSlotId,
+ isSelected = isNoneSelected,
+ onSelected =
+ combine(
+ isNoneSelected,
+ selectedSlotId,
+ ) { isSelected, selectedSlotId ->
+ if (!isSelected) {
{
viewModelScope.launch {
- if (isSelected) {
- quickAffordanceInteractor.unselect(
- slotId = selectedSlot.id,
- affordanceId = affordance.id,
- )
- } else {
- quickAffordanceInteractor.select(
- slotId = selectedSlot.id,
- affordanceId = affordance.id,
- )
- }
+ quickAffordanceInteractor.unselectAll(selectedSlotId)
}
}
} else {
- {
+ null
+ }
+ }
+ )
+ ) +
+ affordances.map { affordance ->
+ val affordanceIcon = getAffordanceIcon(affordance.iconResourceId)
+ val isSelectedFlow: StateFlow<Boolean> =
+ selectedAffordanceIds
+ .map { it.contains(affordance.id) }
+ .stateIn(viewModelScope)
+ OptionItemViewModel<Icon>(
+ key =
+ selectedSlotId
+ .map { slotId -> "$slotId::${affordance.id}" }
+ .stateIn(viewModelScope),
+ payload = Icon.Loaded(drawable = affordanceIcon, contentDescription = null),
+ text = Text.Loaded(affordance.name),
+ isSelected = isSelectedFlow,
+ onClicked =
+ if (affordance.isEnabled) {
+ combine(
+ isSelectedFlow,
+ selectedSlotId,
+ ) { isSelected, selectedSlotId ->
+ if (!isSelected) {
+ {
+ viewModelScope.launch {
+ quickAffordanceInteractor.select(
+ slotId = selectedSlotId,
+ affordanceId = affordance.id,
+ )
+ }
+ }
+ } else {
+ null
+ }
+ }
+ } else {
+ flowOf {
showEnablementDialog(
icon = affordanceIcon,
name = affordance.name,
@@ -201,6 +265,12 @@
)
}
},
+ onLongClicked =
+ if (affordance.configureIntent != null) {
+ { activityStarter(affordance.configureIntent) }
+ } else {
+ null
+ },
isEnabled = affordance.isEnabled,
)
}
@@ -210,21 +280,24 @@
val summary: Flow<KeyguardQuickAffordanceSummaryViewModel> =
slots.map { slots ->
val icon2 =
- slots[KeyguardQuickAffordanceSlots.SLOT_ID_BOTTOM_END]
- ?.selectedQuickAffordances
- ?.firstOrNull()
- ?.icon
+ (slots[KeyguardQuickAffordanceSlots.SLOT_ID_BOTTOM_END]
+ ?.selectedQuickAffordances
+ ?.firstOrNull())
+ ?.payload
val icon1 =
- slots[KeyguardQuickAffordanceSlots.SLOT_ID_BOTTOM_START]
- ?.selectedQuickAffordances
- ?.firstOrNull()
- ?.icon
+ (slots[KeyguardQuickAffordanceSlots.SLOT_ID_BOTTOM_START]
+ ?.selectedQuickAffordances
+ ?.firstOrNull())
+ ?.payload
KeyguardQuickAffordanceSummaryViewModel(
description = toDescriptionText(context, slots),
icon1 = icon1
?: if (icon2 == null) {
- context.getDrawable(R.drawable.link_off)
+ Icon.Resource(
+ res = R.drawable.link_off,
+ contentDescription = null,
+ )
} else {
null
},
@@ -254,28 +327,58 @@
) {
_dialog.value =
DialogViewModel(
- icon = icon,
- name = name,
- instructions = instructions,
- actionText = actionText
- ?: applicationContext.getString(
- R.string.keyguard_affordance_enablement_dialog_dismiss_button
+ icon =
+ Icon.Loaded(
+ drawable = icon,
+ contentDescription = null,
+ ),
+ title = Text.Loaded(name),
+ message =
+ Text.Loaded(
+ buildString {
+ instructions.forEachIndexed { index, instruction ->
+ if (index > 0) {
+ append('\n')
+ }
+
+ append(instruction)
+ }
+ }
+ ),
+ buttons =
+ listOf(
+ ButtonViewModel(
+ text = actionText?.let { Text.Loaded(actionText) }
+ ?: Text.Resource(
+ R.string
+ .keyguard_affordance_enablement_dialog_dismiss_button,
+ ),
+ style = ButtonStyle.Primary,
+ onClicked = {
+ actionComponentName.toIntent()?.let { intent ->
+ applicationContext.startActivity(intent)
+ }
+ }
),
- intent = actionComponentName.toIntent(),
+ ),
)
}
+ /** Returns a view-model for the special "None" option. */
@SuppressLint("UseCompatLoadingForDrawables")
- private fun none(
- slotId: String,
- isSelected: Boolean,
- ): KeyguardQuickAffordanceViewModel {
- return KeyguardQuickAffordanceViewModel.none(
- context = applicationContext,
+ private suspend fun none(
+ slotId: StateFlow<String>,
+ isSelected: StateFlow<Boolean>,
+ onSelected: Flow<(() -> Unit)?>,
+ ): OptionItemViewModel<Icon> {
+ return OptionItemViewModel<Icon>(
+ key = slotId.map { "$it::none" }.stateIn(viewModelScope),
+ payload = Icon.Resource(res = R.drawable.link_off, contentDescription = null),
+ text = Text.Resource(res = R.string.keyguard_affordance_none),
isSelected = isSelected,
- onSelected = {
- viewModelScope.launch { quickAffordanceInteractor.unselectAll(slotId) }
- },
+ onClicked = onSelected,
+ onLongClicked = null,
+ isEnabled = true,
)
}
@@ -318,70 +421,50 @@
}
}
- /** Encapsulates a request to show a dialog. */
- data class DialogViewModel(
- /** An icon to show. */
- val icon: Drawable,
-
- /** Name of the affordance. */
- val name: String,
-
- /** The set of instructions to show below the header. */
- val instructions: List<String>,
-
- /** Label for the dialog button. */
- val actionText: String,
-
- /**
- * Optional [Intent] to use to start an activity when the dialog button is clicked. If
- * `null`, the dialog should be dismissed.
- */
- val intent: Intent?,
- )
-
private fun toDescriptionText(
context: Context,
slots: Map<String, KeyguardQuickAffordanceSlotViewModel>,
- ): String {
+ ): Text {
val bottomStartAffordanceName =
slots[KeyguardQuickAffordanceSlots.SLOT_ID_BOTTOM_START]
?.selectedQuickAffordances
?.firstOrNull()
- ?.contentDescription
+ ?.text
val bottomEndAffordanceName =
slots[KeyguardQuickAffordanceSlots.SLOT_ID_BOTTOM_END]
?.selectedQuickAffordances
?.firstOrNull()
- ?.contentDescription
+ ?.text
return when {
- !bottomStartAffordanceName.isNullOrEmpty() &&
- !bottomEndAffordanceName.isNullOrEmpty() -> {
- context.getString(
- R.string.keyguard_quick_affordance_two_selected_template,
- bottomStartAffordanceName,
- bottomEndAffordanceName,
+ bottomStartAffordanceName != null && bottomEndAffordanceName != null -> {
+ Text.Loaded(
+ context.getString(
+ R.string.keyguard_quick_affordance_two_selected_template,
+ bottomStartAffordanceName.asString(context),
+ bottomEndAffordanceName.asString(context),
+ )
)
}
- !bottomStartAffordanceName.isNullOrEmpty() -> bottomStartAffordanceName
- !bottomEndAffordanceName.isNullOrEmpty() -> bottomEndAffordanceName
- else -> context.getString(R.string.keyguard_quick_affordance_none_selected)
+ bottomStartAffordanceName != null -> bottomStartAffordanceName
+ bottomEndAffordanceName != null -> bottomEndAffordanceName
+ else -> Text.Resource(R.string.keyguard_quick_affordance_none_selected)
}
}
class Factory(
private val context: Context,
private val quickAffordanceInteractor: KeyguardQuickAffordancePickerInteractor,
- private val undoInteractor: UndoInteractor,
private val wallpaperInfoFactory: CurrentWallpaperInfoFactory,
+ private val activityStarter: (Intent) -> Unit,
) : ViewModelProvider.Factory {
override fun <T : ViewModel> create(modelClass: Class<T>): T {
@Suppress("UNCHECKED_CAST")
return KeyguardQuickAffordancePickerViewModel(
context = context,
quickAffordanceInteractor = quickAffordanceInteractor,
- undoInteractor = undoInteractor,
wallpaperInfoFactory = wallpaperInfoFactory,
+ activityStarter = activityStarter,
)
as T
}
diff --git a/src/com/android/customization/picker/quickaffordance/ui/viewmodel/KeyguardQuickAffordanceSlotViewModel.kt b/src/com/android/customization/picker/quickaffordance/ui/viewmodel/KeyguardQuickAffordanceSlotViewModel.kt
index bb9b29b..4d11346 100644
--- a/src/com/android/customization/picker/quickaffordance/ui/viewmodel/KeyguardQuickAffordanceSlotViewModel.kt
+++ b/src/com/android/customization/picker/quickaffordance/ui/viewmodel/KeyguardQuickAffordanceSlotViewModel.kt
@@ -17,6 +17,9 @@
package com.android.customization.picker.quickaffordance.ui.viewmodel
+import com.android.wallpaper.picker.common.icon.ui.viewmodel.Icon
+import com.android.wallpaper.picker.option.ui.viewmodel.OptionItemViewModel
+
/** Models UI state for a single lock screen quick affordance slot in a picker experience. */
data class KeyguardQuickAffordanceSlotViewModel(
/** User-visible name for the slot. */
@@ -30,7 +33,7 @@
*
* Useful for preview.
*/
- val selectedQuickAffordances: List<KeyguardQuickAffordanceViewModel>,
+ val selectedQuickAffordances: List<OptionItemViewModel<Icon>>,
/**
* The maximum number of quick affordances that can be selected for this slot.
diff --git a/src/com/android/customization/picker/quickaffordance/ui/viewmodel/KeyguardQuickAffordanceSummaryViewModel.kt b/src/com/android/customization/picker/quickaffordance/ui/viewmodel/KeyguardQuickAffordanceSummaryViewModel.kt
index d5fc79b..ee89d3e 100644
--- a/src/com/android/customization/picker/quickaffordance/ui/viewmodel/KeyguardQuickAffordanceSummaryViewModel.kt
+++ b/src/com/android/customization/picker/quickaffordance/ui/viewmodel/KeyguardQuickAffordanceSummaryViewModel.kt
@@ -17,10 +17,11 @@
package com.android.customization.picker.quickaffordance.ui.viewmodel
-import android.graphics.drawable.Drawable
+import com.android.wallpaper.picker.common.icon.ui.viewmodel.Icon
+import com.android.wallpaper.picker.common.text.ui.viewmodel.Text
data class KeyguardQuickAffordanceSummaryViewModel(
- val description: String,
- val icon1: Drawable?,
- val icon2: Drawable?,
+ val description: Text,
+ val icon1: Icon?,
+ val icon2: Icon?,
)
diff --git a/src/com/android/customization/picker/quickaffordance/ui/viewmodel/KeyguardQuickAffordanceViewModel.kt b/src/com/android/customization/picker/quickaffordance/ui/viewmodel/KeyguardQuickAffordanceViewModel.kt
deleted file mode 100644
index d720b0c..0000000
--- a/src/com/android/customization/picker/quickaffordance/ui/viewmodel/KeyguardQuickAffordanceViewModel.kt
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Copyright (C) 2022 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.quickaffordance.ui.viewmodel
-
-import android.annotation.SuppressLint
-import android.content.Context
-import android.graphics.drawable.Drawable
-import com.android.wallpaper.R
-
-/** Models UI state for a single lock screen quick affordance in a picker experience. */
-data class KeyguardQuickAffordanceViewModel(
- /** An icon for the quick affordance. */
- val icon: Drawable,
-
- /** A content description for the icon. */
- val contentDescription: String,
-
- /** Whether this quick affordance is selected in its slot. */
- val isSelected: Boolean,
-
- /** Whether this quick affordance is enabled. */
- val isEnabled: Boolean,
-
- /** Notifies that the quick affordance has been clicked by the user. */
- val onClicked: (() -> Unit)?,
-) {
- companion object {
- @SuppressLint("UseCompatLoadingForDrawables")
- fun none(
- context: Context,
- isSelected: Boolean,
- onSelected: () -> Unit,
- ): KeyguardQuickAffordanceViewModel {
- return KeyguardQuickAffordanceViewModel(
- icon = checkNotNull(context.getDrawable(R.drawable.link_off)),
- contentDescription = context.getString(R.string.keyguard_affordance_none),
- isSelected = isSelected,
- onClicked =
- if (isSelected) {
- null
- } else {
- onSelected
- },
- isEnabled = true,
- )
- }
- }
-}
diff --git a/src/com/android/customization/picker/settings/ui/section/MoreSettingsSectionController.kt b/src/com/android/customization/picker/settings/ui/section/MoreSettingsSectionController.kt
new file mode 100644
index 0000000..5e890cd
--- /dev/null
+++ b/src/com/android/customization/picker/settings/ui/section/MoreSettingsSectionController.kt
@@ -0,0 +1,45 @@
+/*
+ * 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.settings.ui.section
+
+import android.annotation.SuppressLint
+import android.content.Context
+import android.content.Intent
+import android.provider.Settings
+import android.view.LayoutInflater
+import com.android.customization.picker.settings.ui.view.MoreSettingsSectionView
+import com.android.wallpaper.R
+import com.android.wallpaper.model.CustomizationSectionController
+
+class MoreSettingsSectionController : CustomizationSectionController<MoreSettingsSectionView> {
+
+ override fun isAvailable(context: Context): Boolean {
+ return true
+ }
+
+ @SuppressLint("InflateParams") // We're okay not providing a parent view.
+ override fun createView(context: Context): MoreSettingsSectionView {
+ return LayoutInflater.from(context)
+ .inflate(R.layout.more_settings_section_view, null)
+ .apply {
+ setOnClickListener {
+ context.startActivity(Intent(Settings.ACTION_LOCKSCREEN_SETTINGS))
+ }
+ } as MoreSettingsSectionView
+ }
+}
diff --git a/src/com/android/customization/picker/clock/ClockSectionView.kt b/src/com/android/customization/picker/settings/ui/view/MoreSettingsSectionView.kt
similarity index 72%
copy from src/com/android/customization/picker/clock/ClockSectionView.kt
copy to src/com/android/customization/picker/settings/ui/view/MoreSettingsSectionView.kt
index fac975a..5de856e 100644
--- a/src/com/android/customization/picker/clock/ClockSectionView.kt
+++ b/src/com/android/customization/picker/settings/ui/view/MoreSettingsSectionView.kt
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2022 The Android Open Source Project
+ * 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.
@@ -12,12 +12,20 @@
* 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
+
+package com.android.customization.picker.settings.ui.view
import android.content.Context
import android.util.AttributeSet
import com.android.wallpaper.picker.SectionView
-/** The [SectionView] for app clock. */
-class ClockSectionView(context: Context?, attrs: AttributeSet?) : SectionView(context, attrs)
+class MoreSettingsSectionView(
+ context: Context,
+ attrs: AttributeSet?,
+) :
+ SectionView(
+ context,
+ attrs,
+ )
diff --git a/src/com/android/customization/widget/OptionSelectorController.java b/src/com/android/customization/widget/OptionSelectorController.java
index 8805caf..8c7af00 100644
--- a/src/com/android/customization/widget/OptionSelectorController.java
+++ b/src/com/android/customization/widget/OptionSelectorController.java
@@ -78,7 +78,7 @@
int CENTER_CHANGE_COLOR_WHEN_NOT_SELECTED = 3;
}
- private float mLinearLayoutHorizontalDisplayOptionsMax;
+ private final float mLinearLayoutHorizontalDisplayOptionsMax;
private final RecyclerView mContainer;
private final List<T> mOptions;
@@ -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);
}
diff --git a/tests/robotests/Android.bp b/tests/robotests/Android.bp
index e0a37c2..4416e1c 100644
--- a/tests/robotests/Android.bp
+++ b/tests/robotests/Android.bp
@@ -13,5 +13,8 @@
"androidx.test.core",
"androidx.test.runner",
],
+
+ upstream: true,
+
instrumentation_for: "ThemePicker",
}
diff --git a/tests/robotests/src/com/android/customization/picker/clock/ClockCustomDemoFragmentTest.kt b/tests/robotests/src/com/android/customization/picker/clock/ClockCustomDemoFragmentTest.kt
deleted file mode 100644
index ad3dd1c..0000000
--- a/tests/robotests/src/com/android/customization/picker/clock/ClockCustomDemoFragmentTest.kt
+++ /dev/null
@@ -1,99 +0,0 @@
-package com.android.customization.picker.clock
-
-import android.os.Handler
-import android.os.UserHandle
-import android.view.View
-import androidx.appcompat.app.AppCompatActivity
-import androidx.recyclerview.widget.LinearLayoutManager
-import androidx.recyclerview.widget.RecyclerView
-import com.android.systemui.plugins.ClockId
-import com.android.systemui.plugins.ClockMetadata
-import com.android.systemui.plugins.ClockProvider
-import com.android.systemui.plugins.ClockProviderPlugin
-import com.android.systemui.plugins.PluginManager
-import com.android.systemui.shared.clocks.ClockRegistry
-import org.junit.Assert
-import org.junit.Before
-import org.junit.Test
-import org.junit.runner.RunWith
-import org.mockito.Mock
-import org.mockito.Mockito
-import org.mockito.MockitoAnnotations
-import org.robolectric.Robolectric
-import org.robolectric.RobolectricTestRunner
-import org.robolectric.annotation.Config
-
-/** Tests of [ClockCustomDemoFragment]. */
-@RunWith(RobolectricTestRunner::class)
-@Config(manifest = Config.NONE)
-class ClockCustomDemoFragmentTest {
- private lateinit var mActivity: AppCompatActivity
- private var mClockCustomDemoFragment: ClockCustomDemoFragment? = null
- private lateinit var registry: ClockRegistry
- @Mock private lateinit var mockPluginManager: PluginManager
- @Mock private lateinit var mockHandler: Handler
- @Mock private lateinit var fakePlugin: ClockProviderPlugin
- @Mock private lateinit var defaultClockProvider: ClockProvider
-
- private var settingValue: String = ""
-
- @Before
- fun setUp() {
- MockitoAnnotations.initMocks(this)
- mActivity = Robolectric.buildActivity(AppCompatActivity::class.java).get()
- mClockCustomDemoFragment = ClockCustomDemoFragment()
- Mockito.`when`(defaultClockProvider.getClocks())
- .thenReturn(listOf(ClockMetadata("DEFAULT", "Default Clock")))
- registry =
- object :
- ClockRegistry(
- mActivity,
- mockPluginManager,
- mockHandler,
- isEnabled = true,
- userHandle = UserHandle.USER_ALL,
- defaultClockProvider = defaultClockProvider
- ) {
- override var currentClockId: ClockId
- get() = settingValue
- set(value) {
- settingValue = value
- }
-
- override fun getClocks(): List<ClockMetadata> {
- return defaultClockProvider.getClocks() +
- listOf(
- ClockMetadata("CLOCK_1", "Clock 1"),
- ClockMetadata("CLOCK_2", "Clock 2"),
- ClockMetadata("CLOCK_NOT_IN_USE", "Clock not in use")
- )
- }
- }
-
- mClockCustomDemoFragment!!.clockRegistry = registry
- mClockCustomDemoFragment!!.recyclerView = RecyclerView(mActivity)
- mClockCustomDemoFragment!!.recyclerView.layoutManager =
- LinearLayoutManager(mActivity, RecyclerView.VERTICAL, false)
- mClockCustomDemoFragment!!.pluginListener.onPluginConnected(fakePlugin, mActivity)
- }
-
- @Test
- fun testItemCount_getCorrectClockCount() {
- Assert.assertEquals(3, mClockCustomDemoFragment!!.recyclerView.adapter!!.itemCount)
- }
-
- @Test
- fun testClick_setCorrectClockId() {
- mClockCustomDemoFragment!!
- .recyclerView
- .measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED)
- mClockCustomDemoFragment!!.recyclerView.layout(0, 0, 100, 10000)
- val testPosition = 1
- mClockCustomDemoFragment!!
- .recyclerView
- .findViewHolderForAdapterPosition(testPosition)
- ?.itemView
- ?.performClick()
- Assert.assertEquals("CLOCK_1", settingValue)
- }
-}
diff --git a/tests/robotests/src/com/android/customization/picker/clock/ui/fragment/ClockCustomDemoFragmentTest.kt b/tests/robotests/src/com/android/customization/picker/clock/ui/fragment/ClockCustomDemoFragmentTest.kt
new file mode 100644
index 0000000..0a54312
--- /dev/null
+++ b/tests/robotests/src/com/android/customization/picker/clock/ui/fragment/ClockCustomDemoFragmentTest.kt
@@ -0,0 +1,75 @@
+package com.android.customization.picker.clock.ui.fragment
+
+import android.view.View
+import androidx.appcompat.app.AppCompatActivity
+import androidx.recyclerview.widget.LinearLayoutManager
+import androidx.recyclerview.widget.RecyclerView
+import com.android.systemui.plugins.ClockMetadata
+import com.android.systemui.plugins.ClockSettings
+import com.android.systemui.plugins.PluginManager
+import com.android.systemui.shared.clocks.ClockRegistry
+import org.junit.Assert
+import org.junit.Before
+import org.junit.Ignore
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.Mock
+import org.mockito.Mockito.verify
+import org.mockito.Mockito.`when` as whenever
+import org.mockito.MockitoAnnotations
+import org.robolectric.Robolectric
+import org.robolectric.RobolectricTestRunner
+import org.robolectric.annotation.Config
+
+/** Tests of [ClockCustomDemoFragment]. */
+@RunWith(RobolectricTestRunner::class)
+@Config(manifest = Config.NONE)
+@Ignore("b/270606895")
+class ClockCustomDemoFragmentTest {
+ private lateinit var mActivity: AppCompatActivity
+ private var mClockCustomDemoFragment: ClockCustomDemoFragment? = null
+ @Mock private lateinit var registry: ClockRegistry
+ @Mock private lateinit var mockPluginManager: PluginManager
+
+ private var settingValue: ClockSettings? = null
+
+ @Before
+ fun setUp() {
+ MockitoAnnotations.initMocks(this)
+ mActivity = Robolectric.buildActivity(AppCompatActivity::class.java).get()
+ mClockCustomDemoFragment = ClockCustomDemoFragment()
+ whenever(registry.getClocks())
+ .thenReturn(
+ listOf(
+ ClockMetadata("CLOCK_1", "Clock 1"),
+ ClockMetadata("CLOCK_2", "Clock 2"),
+ ClockMetadata("CLOCK_NOT_IN_USE", "Clock not in use")
+ )
+ )
+
+ mClockCustomDemoFragment!!.clockRegistry = registry
+ mClockCustomDemoFragment!!.recyclerView = RecyclerView(mActivity)
+ mClockCustomDemoFragment!!.recyclerView.layoutManager =
+ LinearLayoutManager(mActivity, RecyclerView.VERTICAL, false)
+ }
+
+ @Test
+ fun testItemCount_getCorrectClockCount() {
+ Assert.assertEquals(3, mClockCustomDemoFragment!!.recyclerView.adapter!!.itemCount)
+ }
+
+ @Test
+ fun testClick_setCorrectClockId() {
+ mClockCustomDemoFragment!!
+ .recyclerView
+ .measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED)
+ mClockCustomDemoFragment!!.recyclerView.layout(0, 0, 100, 10000)
+ val testPosition = 1
+ mClockCustomDemoFragment!!
+ .recyclerView
+ .findViewHolderForAdapterPosition(testPosition)
+ ?.itemView
+ ?.performClick()
+ verify(registry).currentClockId = "CLOCK_1"
+ }
+}
diff --git a/tests/src/com/android/customization/model/grid/data/repository/FakeGridRepository.kt b/tests/src/com/android/customization/model/grid/data/repository/FakeGridRepository.kt
new file mode 100644
index 0000000..5953937
--- /dev/null
+++ b/tests/src/com/android/customization/model/grid/data/repository/FakeGridRepository.kt
@@ -0,0 +1,91 @@
+/*
+ * 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.grid.data.repository
+
+import com.android.customization.model.grid.shared.model.GridOptionItemModel
+import com.android.customization.model.grid.shared.model.GridOptionItemsModel
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.channels.BufferOverflow
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.MutableSharedFlow
+import kotlinx.coroutines.flow.MutableStateFlow
+import kotlinx.coroutines.flow.SharingStarted
+import kotlinx.coroutines.flow.asSharedFlow
+import kotlinx.coroutines.flow.map
+import kotlinx.coroutines.flow.stateIn
+
+class FakeGridRepository(
+ private val scope: CoroutineScope,
+ initialOptionCount: Int,
+ var available: Boolean = true
+) : GridRepository {
+ private val _optionChanges =
+ MutableSharedFlow<Unit>(
+ replay = 1,
+ onBufferOverflow = BufferOverflow.DROP_OLDEST,
+ )
+
+ override suspend fun isAvailable(): Boolean = available
+
+ override fun getOptionChanges(): Flow<Unit> = _optionChanges.asSharedFlow()
+
+ private val selectedOptionIndex = MutableStateFlow(0)
+ private var options: GridOptionItemsModel = createOptions(count = initialOptionCount)
+
+ override suspend fun getOptions(): GridOptionItemsModel {
+ return options
+ }
+
+ fun setOptions(
+ count: Int,
+ selectedIndex: Int = 0,
+ ) {
+ options = createOptions(count, selectedIndex)
+ _optionChanges.tryEmit(Unit)
+ }
+
+ private fun createOptions(
+ count: Int,
+ selectedIndex: Int = 0,
+ ): GridOptionItemsModel {
+ selectedOptionIndex.value = selectedIndex
+ return GridOptionItemsModel.Loaded(
+ options =
+ buildList {
+ repeat(times = count) { index ->
+ add(
+ GridOptionItemModel(
+ name = "option_$index",
+ cols = 4,
+ rows = index * 2,
+ isSelected =
+ selectedOptionIndex
+ .map { it == index }
+ .stateIn(
+ scope = scope,
+ started = SharingStarted.Eagerly,
+ initialValue = false,
+ ),
+ onSelected = { selectedOptionIndex.value = index },
+ )
+ )
+ }
+ }
+ )
+ }
+}
diff --git a/tests/src/com/android/customization/model/grid/domain/interactor/GridInteractorTest.kt b/tests/src/com/android/customization/model/grid/domain/interactor/GridInteractorTest.kt
new file mode 100644
index 0000000..f73d5a3
--- /dev/null
+++ b/tests/src/com/android/customization/model/grid/domain/interactor/GridInteractorTest.kt
@@ -0,0 +1,146 @@
+/*
+ * 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.grid.domain.interactor
+
+import androidx.test.filters.SmallTest
+import com.android.customization.model.grid.data.repository.FakeGridRepository
+import com.android.customization.model.grid.shared.model.GridOptionItemsModel
+import com.android.wallpaper.testing.FakeSnapshotStore
+import com.android.wallpaper.testing.collectLastValue
+import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.runBlocking
+import kotlinx.coroutines.test.TestScope
+import kotlinx.coroutines.test.runCurrent
+import kotlinx.coroutines.test.runTest
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.JUnit4
+
+@OptIn(ExperimentalCoroutinesApi::class)
+@SmallTest
+@RunWith(JUnit4::class)
+class GridInteractorTest {
+
+ private lateinit var underTest: GridInteractor
+ private lateinit var testScope: TestScope
+ private lateinit var repository: FakeGridRepository
+ private lateinit var store: FakeSnapshotStore
+
+ @Before
+ fun setUp() {
+ testScope = TestScope()
+ repository =
+ FakeGridRepository(
+ scope = testScope.backgroundScope,
+ initialOptionCount = 3,
+ )
+ store = FakeSnapshotStore()
+ underTest =
+ GridInteractor(
+ applicationScope = testScope.backgroundScope,
+ repository = repository,
+ snapshotRestorer = {
+ GridSnapshotRestorer(
+ interactor = underTest,
+ )
+ .apply {
+ runBlocking {
+ setUpSnapshotRestorer(
+ store = store,
+ )
+ }
+ }
+ },
+ )
+ }
+
+ @Test
+ fun selectingOptionThroughModel_updatesOptions() =
+ testScope.runTest {
+ val options = collectLastValue(underTest.options)
+ assertThat(options()).isInstanceOf(GridOptionItemsModel.Loaded::class.java)
+ (options() as? GridOptionItemsModel.Loaded)?.let { loaded ->
+ assertThat(loaded.options).hasSize(3)
+ assertThat(loaded.options[0].isSelected.value).isTrue()
+ assertThat(loaded.options[1].isSelected.value).isFalse()
+ assertThat(loaded.options[2].isSelected.value).isFalse()
+ }
+
+ val storedSnapshot = store.retrieve()
+ (options() as? GridOptionItemsModel.Loaded)?.let { loaded ->
+ loaded.options[1].onSelected()
+ }
+
+ assertThat(options()).isInstanceOf(GridOptionItemsModel.Loaded::class.java)
+ (options() as? GridOptionItemsModel.Loaded)?.let { loaded ->
+ assertThat(loaded.options).hasSize(3)
+ assertThat(loaded.options[0].isSelected.value).isFalse()
+ assertThat(loaded.options[1].isSelected.value).isTrue()
+ assertThat(loaded.options[2].isSelected.value).isFalse()
+ }
+ assertThat(store.retrieve()).isNotEqualTo(storedSnapshot)
+ }
+
+ @Test
+ fun selectingOptionThroughSetter_returnsSelectedOptionFromGetter() =
+ testScope.runTest {
+ val options = collectLastValue(underTest.options)
+ assertThat(options()).isInstanceOf(GridOptionItemsModel.Loaded::class.java)
+ (options() as? GridOptionItemsModel.Loaded)?.let { loaded ->
+ assertThat(loaded.options).hasSize(3)
+ }
+
+ val storedSnapshot = store.retrieve()
+ (options() as? GridOptionItemsModel.Loaded)?.let { loaded ->
+ underTest.setSelectedOption(loaded.options[1])
+ runCurrent()
+ assertThat(underTest.getSelectedOption()?.name).isEqualTo(loaded.options[1].name)
+ assertThat(store.retrieve()).isNotEqualTo(storedSnapshot)
+ }
+ }
+
+ @Test
+ fun externalUpdates_reloadInvoked() =
+ testScope.runTest {
+ val options = collectLastValue(underTest.options)
+ assertThat(options()).isInstanceOf(GridOptionItemsModel.Loaded::class.java)
+ (options() as? GridOptionItemsModel.Loaded)?.let { loaded ->
+ assertThat(loaded.options).hasSize(3)
+ }
+
+ val storedSnapshot = store.retrieve()
+ repository.setOptions(4)
+
+ assertThat(options()).isInstanceOf(GridOptionItemsModel.Loaded::class.java)
+ (options() as? GridOptionItemsModel.Loaded)?.let { loaded ->
+ assertThat(loaded.options).hasSize(4)
+ }
+ // External updates do not record a new snapshot with the undo system.
+ assertThat(store.retrieve()).isEqualTo(storedSnapshot)
+ }
+
+ @Test
+ fun unavailableRepository_emptyOptions() =
+ testScope.runTest {
+ repository.available = false
+ val options = collectLastValue(underTest.options)
+ assertThat(options()).isNull()
+ }
+}
diff --git a/tests/src/com/android/customization/model/grid/domain/interactor/GridSnapshotRestorerTest.kt b/tests/src/com/android/customization/model/grid/domain/interactor/GridSnapshotRestorerTest.kt
new file mode 100644
index 0000000..c2712b1
--- /dev/null
+++ b/tests/src/com/android/customization/model/grid/domain/interactor/GridSnapshotRestorerTest.kt
@@ -0,0 +1,111 @@
+/*
+ * 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.grid.domain.interactor
+
+import androidx.test.filters.SmallTest
+import com.android.customization.model.grid.data.repository.FakeGridRepository
+import com.android.customization.model.grid.shared.model.GridOptionItemsModel
+import com.android.wallpaper.testing.FakeSnapshotStore
+import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.test.TestScope
+import kotlinx.coroutines.test.runCurrent
+import kotlinx.coroutines.test.runTest
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.JUnit4
+
+@OptIn(ExperimentalCoroutinesApi::class)
+@SmallTest
+@RunWith(JUnit4::class)
+class GridSnapshotRestorerTest {
+
+ private lateinit var underTest: GridSnapshotRestorer
+ private lateinit var testScope: TestScope
+ private lateinit var repository: FakeGridRepository
+ private lateinit var store: FakeSnapshotStore
+
+ @Before
+ fun setUp() {
+ testScope = TestScope()
+ repository =
+ FakeGridRepository(
+ scope = testScope.backgroundScope,
+ initialOptionCount = 4,
+ )
+ underTest =
+ GridSnapshotRestorer(
+ interactor =
+ GridInteractor(
+ applicationScope = testScope.backgroundScope,
+ repository = repository,
+ snapshotRestorer = { underTest },
+ )
+ )
+ store = FakeSnapshotStore()
+ }
+
+ @Test
+ fun restoreToSnapshot_noCallsToStore_restoresToInitialSnapshot() =
+ testScope.runTest {
+ runCurrent()
+ val initialSnapshot = underTest.setUpSnapshotRestorer(store = store)
+ assertThat(initialSnapshot.args).isNotEmpty()
+ repository.setOptions(
+ count = 4,
+ selectedIndex = 2,
+ )
+ runCurrent()
+ assertThat(getSelectedIndex()).isEqualTo(2)
+
+ underTest.restoreToSnapshot(initialSnapshot)
+ runCurrent()
+
+ assertThat(getSelectedIndex()).isEqualTo(0)
+ }
+
+ @Test
+ fun restoreToSnapshot_withCallToStore_restoresToInitialSnapshot() =
+ testScope.runTest {
+ runCurrent()
+ val initialSnapshot = underTest.setUpSnapshotRestorer(store = store)
+ assertThat(initialSnapshot.args).isNotEmpty()
+ repository.setOptions(
+ count = 4,
+ selectedIndex = 2,
+ )
+ runCurrent()
+ assertThat(getSelectedIndex()).isEqualTo(2)
+ underTest.store((repository.getOptions() as GridOptionItemsModel.Loaded).options[1])
+ runCurrent()
+
+ underTest.restoreToSnapshot(initialSnapshot)
+ runCurrent()
+
+ assertThat(getSelectedIndex()).isEqualTo(0)
+ }
+
+ private suspend fun getSelectedIndex(): Int {
+ return (repository.getOptions() as? GridOptionItemsModel.Loaded)?.options?.indexOfFirst {
+ optionItem ->
+ optionItem.isSelected.value
+ }
+ ?: -1
+ }
+}
diff --git a/tests/src/com/android/customization/model/grid/ui/viewmodel/GridScreenViewModelTest.kt b/tests/src/com/android/customization/model/grid/ui/viewmodel/GridScreenViewModelTest.kt
new file mode 100644
index 0000000..58c5d99
--- /dev/null
+++ b/tests/src/com/android/customization/model/grid/ui/viewmodel/GridScreenViewModelTest.kt
@@ -0,0 +1,110 @@
+/*
+ * 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.grid.ui.viewmodel
+
+import androidx.test.filters.SmallTest
+import androidx.test.platform.app.InstrumentationRegistry
+import com.android.customization.model.grid.data.repository.FakeGridRepository
+import com.android.customization.model.grid.domain.interactor.GridInteractor
+import com.android.customization.model.grid.domain.interactor.GridSnapshotRestorer
+import com.android.wallpaper.picker.option.ui.viewmodel.OptionItemViewModel
+import com.android.wallpaper.testing.FakeSnapshotStore
+import com.android.wallpaper.testing.collectLastValue
+import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.runBlocking
+import kotlinx.coroutines.test.TestScope
+import kotlinx.coroutines.test.runTest
+import org.junit.Before
+import org.junit.Ignore
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.JUnit4
+
+@OptIn(ExperimentalCoroutinesApi::class)
+@SmallTest
+@RunWith(JUnit4::class)
+class GridScreenViewModelTest {
+
+ private lateinit var underTest: GridScreenViewModel
+ private lateinit var testScope: TestScope
+ private lateinit var interactor: GridInteractor
+ private lateinit var store: FakeSnapshotStore
+
+ @Before
+ fun setUp() {
+ testScope = TestScope()
+ store = FakeSnapshotStore()
+ interactor =
+ GridInteractor(
+ applicationScope = testScope.backgroundScope,
+ repository =
+ FakeGridRepository(
+ scope = testScope.backgroundScope,
+ initialOptionCount = 4,
+ ),
+ snapshotRestorer = {
+ GridSnapshotRestorer(
+ interactor = interactor,
+ )
+ .apply { runBlocking { setUpSnapshotRestorer(store) } }
+ }
+ )
+
+ underTest =
+ GridScreenViewModel(
+ context = InstrumentationRegistry.getInstrumentation().targetContext,
+ interactor = interactor,
+ )
+ }
+
+ @Test
+ @Ignore("b/270371382")
+ fun clickOnItem_itGetsSelected() =
+ testScope.runTest {
+ val optionItemsValueProvider = collectLastValue(underTest.optionItems)
+ var optionItemsValue = checkNotNull(optionItemsValueProvider.invoke())
+ assertThat(optionItemsValue).hasSize(4)
+ assertThat(getSelectedIndex(optionItemsValue)).isEqualTo(0)
+ assertThat(getOnClick(optionItemsValue[0])).isNull()
+
+ val item1OnClickedValue = getOnClick(optionItemsValue[1])
+ assertThat(item1OnClickedValue).isNotNull()
+ item1OnClickedValue?.invoke()
+
+ optionItemsValue = checkNotNull(optionItemsValueProvider.invoke())
+ assertThat(optionItemsValue).hasSize(4)
+ assertThat(getSelectedIndex(optionItemsValue)).isEqualTo(1)
+ assertThat(getOnClick(optionItemsValue[0])).isNotNull()
+ assertThat(getOnClick(optionItemsValue[1])).isNull()
+ }
+
+ private fun TestScope.getSelectedIndex(
+ optionItems: List<OptionItemViewModel<GridIconViewModel>>
+ ): Int {
+ return optionItems.indexOfFirst { optionItem ->
+ collectLastValue(optionItem.isSelected).invoke() == true
+ }
+ }
+
+ private fun TestScope.getOnClick(
+ optionItem: OptionItemViewModel<GridIconViewModel>
+ ): (() -> Unit)? {
+ return collectLastValue(optionItem.onClicked).invoke()
+ }
+}
diff --git a/tests/src/com/android/customization/model/mode/DarkModeSnapshotRestorerTest.kt b/tests/src/com/android/customization/model/mode/DarkModeSnapshotRestorerTest.kt
new file mode 100644
index 0000000..38067b7
--- /dev/null
+++ b/tests/src/com/android/customization/model/mode/DarkModeSnapshotRestorerTest.kt
@@ -0,0 +1,107 @@
+/*
+ * 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.mode
+
+import androidx.test.filters.SmallTest
+import com.android.wallpaper.testing.FakeSnapshotStore
+import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.test.StandardTestDispatcher
+import kotlinx.coroutines.test.TestScope
+import kotlinx.coroutines.test.runTest
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.JUnit4
+
+@OptIn(ExperimentalCoroutinesApi::class)
+@SmallTest
+@RunWith(JUnit4::class)
+class DarkModeSnapshotRestorerTest {
+
+ private lateinit var underTest: DarkModeSnapshotRestorer
+ private lateinit var testScope: TestScope
+
+ private var isActive = false
+
+ @Before
+ fun setUp() {
+ val testDispatcher = StandardTestDispatcher()
+ testScope = TestScope(testDispatcher)
+ underTest =
+ DarkModeSnapshotRestorer(
+ backgroundDispatcher = testDispatcher,
+ isActive = { isActive },
+ setActive = { isActive = it },
+ )
+ }
+
+ @Test
+ fun `set up and restore - active`() =
+ testScope.runTest {
+ isActive = true
+
+ val store = FakeSnapshotStore()
+ store.store(underTest.setUpSnapshotRestorer(store = store))
+ val storedSnapshot = store.retrieve()
+
+ underTest.restoreToSnapshot(snapshot = storedSnapshot)
+ assertThat(isActive).isTrue()
+ }
+
+ @Test
+ fun `set up and restore - inactive`() =
+ testScope.runTest {
+ isActive = false
+
+ val store = FakeSnapshotStore()
+ store.store(underTest.setUpSnapshotRestorer(store = store))
+ val storedSnapshot = store.retrieve()
+
+ underTest.restoreToSnapshot(snapshot = storedSnapshot)
+ assertThat(isActive).isFalse()
+ }
+
+ @Test
+ fun `set up - deactivate - restore to active`() =
+ testScope.runTest {
+ isActive = true
+ val store = FakeSnapshotStore()
+ store.store(underTest.setUpSnapshotRestorer(store = store))
+ val initialSnapshot = store.retrieve()
+
+ underTest.store(isActivated = false)
+
+ underTest.restoreToSnapshot(snapshot = initialSnapshot)
+ assertThat(isActive).isTrue()
+ }
+
+ @Test
+ fun `set up - activate - restore to inactive`() =
+ testScope.runTest {
+ isActive = false
+ val store = FakeSnapshotStore()
+ store.store(underTest.setUpSnapshotRestorer(store = store))
+ val initialSnapshot = store.retrieve()
+
+ underTest.store(isActivated = true)
+
+ underTest.restoreToSnapshot(snapshot = initialSnapshot)
+ assertThat(isActive).isFalse()
+ }
+}
diff --git a/tests/src/com/android/customization/model/picker/color/domain/interactor/ColorPickerInteractorTest.kt b/tests/src/com/android/customization/model/picker/color/domain/interactor/ColorPickerInteractorTest.kt
new file mode 100644
index 0000000..cbf1365
--- /dev/null
+++ b/tests/src/com/android/customization/model/picker/color/domain/interactor/ColorPickerInteractorTest.kt
@@ -0,0 +1,118 @@
+/*
+ * 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.picker.color.domain.interactor
+
+import android.content.Context
+import androidx.test.filters.SmallTest
+import androidx.test.platform.app.InstrumentationRegistry
+import com.android.customization.picker.color.data.repository.FakeColorPickerRepository
+import com.android.customization.picker.color.domain.interactor.ColorPickerInteractor
+import com.android.customization.picker.color.domain.interactor.ColorPickerSnapshotRestorer
+import com.android.customization.picker.color.shared.model.ColorType
+import com.android.wallpaper.testing.FakeSnapshotStore
+import com.android.wallpaper.testing.collectLastValue
+import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.runBlocking
+import kotlinx.coroutines.test.runTest
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.JUnit4
+
+@OptIn(ExperimentalCoroutinesApi::class)
+@SmallTest
+@RunWith(JUnit4::class)
+class ColorPickerInteractorTest {
+ private lateinit var underTest: ColorPickerInteractor
+ private lateinit var repository: FakeColorPickerRepository
+ private lateinit var store: FakeSnapshotStore
+
+ private lateinit var context: Context
+
+ @Before
+ fun setUp() {
+ context = InstrumentationRegistry.getInstrumentation().targetContext
+ repository = FakeColorPickerRepository(context = context)
+ store = FakeSnapshotStore()
+ underTest =
+ ColorPickerInteractor(
+ repository = repository,
+ snapshotRestorer = {
+ ColorPickerSnapshotRestorer(interactor = underTest).apply {
+ runBlocking { setUpSnapshotRestorer(store = store) }
+ }
+ },
+ )
+ repository.setOptions(4, 4, ColorType.WALLPAPER_COLOR, 0)
+ }
+
+ @Test
+ fun select() = runTest {
+ val colorOptions = collectLastValue(underTest.colorOptions)
+
+ val wallpaperColorOptionModelBefore = colorOptions()?.get(ColorType.WALLPAPER_COLOR)?.get(2)
+ assertThat(wallpaperColorOptionModelBefore?.isSelected).isFalse()
+
+ wallpaperColorOptionModelBefore?.let { underTest.select(colorOptionModel = it) }
+ val wallpaperColorOptionModelAfter = colorOptions()?.get(ColorType.WALLPAPER_COLOR)?.get(2)
+ assertThat(wallpaperColorOptionModelAfter?.isSelected).isTrue()
+
+ val presetColorOptionModelBefore = colorOptions()?.get(ColorType.PRESET_COLOR)?.get(1)
+ assertThat(presetColorOptionModelBefore?.isSelected).isFalse()
+
+ presetColorOptionModelBefore?.let { underTest.select(colorOptionModel = it) }
+ val presetColorOptionModelAfter = colorOptions()?.get(ColorType.PRESET_COLOR)?.get(1)
+ assertThat(presetColorOptionModelAfter?.isSelected).isTrue()
+ }
+
+ @Test
+ fun snapshotRestorer_updatesSnapshot() = runTest {
+ val colorOptions = collectLastValue(underTest.colorOptions)
+ val wallpaperColorOptionModel0 = colorOptions()?.get(ColorType.WALLPAPER_COLOR)?.get(0)
+ val wallpaperColorOptionModel1 = colorOptions()?.get(ColorType.WALLPAPER_COLOR)?.get(1)
+ assertThat(wallpaperColorOptionModel0?.isSelected).isTrue()
+ assertThat(wallpaperColorOptionModel1?.isSelected).isFalse()
+
+ val storedSnapshot = store.retrieve()
+ wallpaperColorOptionModel1?.let { underTest.select(it) }
+ val wallpaperColorOptionModel0After = colorOptions()?.get(ColorType.WALLPAPER_COLOR)?.get(0)
+ val wallpaperColorOptionModel1After = colorOptions()?.get(ColorType.WALLPAPER_COLOR)?.get(1)
+ assertThat(wallpaperColorOptionModel0After?.isSelected).isFalse()
+ assertThat(wallpaperColorOptionModel1After?.isSelected).isTrue()
+
+ assertThat(store.retrieve()).isNotEqualTo(storedSnapshot)
+ }
+
+ @Test
+ fun snapshotRestorer_doesNotUpdateSnapshotOnExternalUpdates() = runTest {
+ val colorOptions = collectLastValue(underTest.colorOptions)
+ val wallpaperColorOptionModel0 = colorOptions()?.get(ColorType.WALLPAPER_COLOR)?.get(0)
+ val wallpaperColorOptionModel1 = colorOptions()?.get(ColorType.WALLPAPER_COLOR)?.get(1)
+ assertThat(wallpaperColorOptionModel0?.isSelected).isTrue()
+ assertThat(wallpaperColorOptionModel1?.isSelected).isFalse()
+
+ val storedSnapshot = store.retrieve()
+ repository.setOptions(4, 4, ColorType.WALLPAPER_COLOR, 1)
+ val wallpaperColorOptionModel0After = colorOptions()?.get(ColorType.WALLPAPER_COLOR)?.get(0)
+ val wallpaperColorOptionModel1After = colorOptions()?.get(ColorType.WALLPAPER_COLOR)?.get(1)
+ assertThat(wallpaperColorOptionModel0After?.isSelected).isFalse()
+ assertThat(wallpaperColorOptionModel1After?.isSelected).isTrue()
+
+ assertThat(store.retrieve()).isEqualTo(storedSnapshot)
+ }
+}
diff --git a/tests/src/com/android/customization/model/picker/color/domain/interactor/ColorPickerSnapshotRestorerTest.kt b/tests/src/com/android/customization/model/picker/color/domain/interactor/ColorPickerSnapshotRestorerTest.kt
new file mode 100644
index 0000000..71a8f23
--- /dev/null
+++ b/tests/src/com/android/customization/model/picker/color/domain/interactor/ColorPickerSnapshotRestorerTest.kt
@@ -0,0 +1,138 @@
+/*
+ * 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.picker.color.domain.interactor
+
+import android.content.Context
+import androidx.test.filters.SmallTest
+import androidx.test.platform.app.InstrumentationRegistry
+import com.android.customization.picker.color.data.repository.FakeColorPickerRepository
+import com.android.customization.picker.color.domain.interactor.ColorPickerInteractor
+import com.android.customization.picker.color.domain.interactor.ColorPickerSnapshotRestorer
+import com.android.customization.picker.color.shared.model.ColorOptionModel
+import com.android.customization.picker.color.shared.model.ColorType
+import com.android.wallpaper.testing.FakeSnapshotStore
+import com.android.wallpaper.testing.collectLastValue
+import com.google.common.truth.Truth
+import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.test.runTest
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.JUnit4
+
+@OptIn(ExperimentalCoroutinesApi::class)
+@SmallTest
+@RunWith(JUnit4::class)
+class ColorPickerSnapshotRestorerTest {
+
+ private lateinit var underTest: ColorPickerSnapshotRestorer
+ private lateinit var repository: FakeColorPickerRepository
+ private lateinit var store: FakeSnapshotStore
+
+ private lateinit var context: Context
+
+ @Before
+ fun setUp() {
+ context = InstrumentationRegistry.getInstrumentation().targetContext
+ repository = FakeColorPickerRepository(context = context)
+ underTest =
+ ColorPickerSnapshotRestorer(
+ interactor =
+ ColorPickerInteractor(
+ repository = repository,
+ snapshotRestorer = { underTest },
+ )
+ )
+ store = FakeSnapshotStore()
+ }
+
+ @Test
+ fun restoreToSnapshot_noCallsToStore_restoresToInitialSnapshot() = runTest {
+ val colorOptions = collectLastValue(repository.colorOptions)
+
+ repository.setOptions(4, 4, ColorType.WALLPAPER_COLOR, 2)
+ val initialSnapshot = underTest.setUpSnapshotRestorer(store = store)
+ assertThat(initialSnapshot.args).isNotEmpty()
+
+ val colorOptionToSelect = colorOptions()?.get(ColorType.PRESET_COLOR)?.get(3)
+ colorOptionToSelect?.let { repository.select(it) }
+ assertState(colorOptions(), ColorType.PRESET_COLOR, 3)
+
+ underTest.restoreToSnapshot(initialSnapshot)
+ assertState(colorOptions(), ColorType.WALLPAPER_COLOR, 2)
+ }
+
+ @Test
+ fun restoreToSnapshot_withCallToStore_restoresToInitialSnapshot() = runTest {
+ val colorOptions = collectLastValue(repository.colorOptions)
+
+ repository.setOptions(4, 4, ColorType.WALLPAPER_COLOR, 2)
+ val initialSnapshot = underTest.setUpSnapshotRestorer(store = store)
+ assertThat(initialSnapshot.args).isNotEmpty()
+
+ val colorOptionToSelect = colorOptions()?.get(ColorType.PRESET_COLOR)?.get(3)
+ colorOptionToSelect?.let { repository.select(it) }
+ assertState(colorOptions(), ColorType.PRESET_COLOR, 3)
+
+ val colorOptionToStore = colorOptions()?.get(ColorType.PRESET_COLOR)?.get(1)
+ colorOptionToStore?.let { underTest.storeSnapshot(colorOptionToStore) }
+
+ underTest.restoreToSnapshot(initialSnapshot)
+ assertState(colorOptions(), ColorType.WALLPAPER_COLOR, 2)
+ }
+
+ private fun assertState(
+ colorOptions: Map<ColorType, List<ColorOptionModel>>?,
+ selectedColorType: ColorType,
+ selectedColorIndex: Int
+ ) {
+ var foundSelectedColorOption = false
+ assertThat(colorOptions).isNotNull()
+ val optionsOfSelectedColorType = colorOptions?.get(selectedColorType)
+ assertThat(optionsOfSelectedColorType).isNotNull()
+ if (optionsOfSelectedColorType != null) {
+ for (i in optionsOfSelectedColorType.indices) {
+ val colorOptionHasSelectedIndex = i == selectedColorIndex
+ Truth.assertWithMessage(
+ "Expected color option with index \"${i}\" to have" +
+ " isSelected=$colorOptionHasSelectedIndex but it was" +
+ " ${optionsOfSelectedColorType[i].isSelected}, num options: ${colorOptions.size}"
+ )
+ .that(optionsOfSelectedColorType[i].isSelected)
+ .isEqualTo(colorOptionHasSelectedIndex)
+ foundSelectedColorOption = foundSelectedColorOption || colorOptionHasSelectedIndex
+ }
+ if (selectedColorIndex == -1) {
+ Truth.assertWithMessage(
+ "Expected no color options to be selected, but a color option is" +
+ " selected"
+ )
+ .that(foundSelectedColorOption)
+ .isFalse()
+ } else {
+ Truth.assertWithMessage(
+ "Expected a color option to be selected, but no color option is" +
+ " selected"
+ )
+ .that(foundSelectedColorOption)
+ .isTrue()
+ }
+ }
+ }
+}
diff --git a/tests/src/com/android/customization/model/picker/color/ui/viewmodel/ColorPickerViewModelTest.kt b/tests/src/com/android/customization/model/picker/color/ui/viewmodel/ColorPickerViewModelTest.kt
new file mode 100644
index 0000000..1d9457a
--- /dev/null
+++ b/tests/src/com/android/customization/model/picker/color/ui/viewmodel/ColorPickerViewModelTest.kt
@@ -0,0 +1,262 @@
+/*
+ * 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.picker.color.ui.viewmodel
+
+import android.content.Context
+import androidx.test.filters.SmallTest
+import androidx.test.platform.app.InstrumentationRegistry
+import com.android.customization.picker.color.data.repository.FakeColorPickerRepository
+import com.android.customization.picker.color.domain.interactor.ColorPickerInteractor
+import com.android.customization.picker.color.domain.interactor.ColorPickerSnapshotRestorer
+import com.android.customization.picker.color.shared.model.ColorType
+import com.android.customization.picker.color.ui.viewmodel.ColorOptionIconViewModel
+import com.android.customization.picker.color.ui.viewmodel.ColorPickerViewModel
+import com.android.customization.picker.color.ui.viewmodel.ColorTypeTabViewModel
+import com.android.wallpaper.picker.option.ui.viewmodel.OptionItemViewModel
+import com.android.wallpaper.testing.FakeSnapshotStore
+import com.android.wallpaper.testing.collectLastValue
+import com.google.common.truth.Truth.assertThat
+import com.google.common.truth.Truth.assertWithMessage
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.runBlocking
+import kotlinx.coroutines.test.StandardTestDispatcher
+import kotlinx.coroutines.test.TestScope
+import kotlinx.coroutines.test.resetMain
+import kotlinx.coroutines.test.runTest
+import kotlinx.coroutines.test.setMain
+import org.junit.After
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.JUnit4
+
+@OptIn(ExperimentalCoroutinesApi::class)
+@SmallTest
+@RunWith(JUnit4::class)
+class ColorPickerViewModelTest {
+ private lateinit var underTest: ColorPickerViewModel
+ private lateinit var repository: FakeColorPickerRepository
+ private lateinit var interactor: ColorPickerInteractor
+ private lateinit var store: FakeSnapshotStore
+
+ private lateinit var context: Context
+ private lateinit var testScope: TestScope
+
+ @Before
+ fun setUp() {
+ context = InstrumentationRegistry.getInstrumentation().targetContext
+ val testDispatcher = StandardTestDispatcher()
+ testScope = TestScope(testDispatcher)
+ Dispatchers.setMain(testDispatcher)
+ repository = FakeColorPickerRepository(context = context)
+ store = FakeSnapshotStore()
+
+ interactor =
+ ColorPickerInteractor(
+ repository = repository,
+ snapshotRestorer = {
+ ColorPickerSnapshotRestorer(interactor = interactor).apply {
+ runBlocking { setUpSnapshotRestorer(store = store) }
+ }
+ },
+ )
+
+ underTest =
+ ColorPickerViewModel.Factory(context = context, interactor = interactor)
+ .create(ColorPickerViewModel::class.java)
+
+ repository.setOptions(4, 4, ColorType.WALLPAPER_COLOR, 0)
+ }
+
+ @After
+ fun tearDown() {
+ Dispatchers.resetMain()
+ }
+
+ @Test
+ fun `Select a color section color`() =
+ testScope.runTest {
+ val colorSectionOptions = collectLastValue(underTest.colorSectionOptions)
+
+ assertColorOptionUiState(
+ colorOptions = colorSectionOptions(),
+ selectedColorOptionIndex = 0
+ )
+
+ selectColorOption(colorSectionOptions, 2)
+ assertColorOptionUiState(
+ colorOptions = colorSectionOptions(),
+ selectedColorOptionIndex = 2
+ )
+
+ selectColorOption(colorSectionOptions, 4)
+ assertColorOptionUiState(
+ colorOptions = colorSectionOptions(),
+ selectedColorOptionIndex = 4
+ )
+ }
+
+ @Test
+ fun `Select a preset color`() =
+ testScope.runTest {
+ val colorTypes = collectLastValue(underTest.colorTypeTabs)
+ val colorOptions = collectLastValue(underTest.colorOptions)
+
+ // Initially, the wallpaper color tab should be selected
+ assertPickerUiState(
+ colorTypes = colorTypes(),
+ colorOptions = colorOptions(),
+ selectedColorTypeText = "Wallpaper colors",
+ selectedColorOptionIndex = 0
+ )
+
+ // Select "Basic colors" tab
+ colorTypes()?.get(ColorType.PRESET_COLOR)?.onClick?.invoke()
+ assertPickerUiState(
+ colorTypes = colorTypes(),
+ colorOptions = colorOptions(),
+ selectedColorTypeText = "Basic colors",
+ selectedColorOptionIndex = -1
+ )
+
+ // Select a color option
+ selectColorOption(colorOptions, 2)
+
+ // Check original option is no longer selected
+ colorTypes()?.get(ColorType.WALLPAPER_COLOR)?.onClick?.invoke()
+ assertPickerUiState(
+ colorTypes = colorTypes(),
+ colorOptions = colorOptions(),
+ selectedColorTypeText = "Wallpaper colors",
+ selectedColorOptionIndex = -1
+ )
+
+ // Check new option is selected
+ colorTypes()?.get(ColorType.PRESET_COLOR)?.onClick?.invoke()
+ assertPickerUiState(
+ colorTypes = colorTypes(),
+ colorOptions = colorOptions(),
+ selectedColorTypeText = "Basic colors",
+ selectedColorOptionIndex = 2
+ )
+ }
+
+ /** Simulates a user selecting the affordance at the given index, if that is clickable. */
+ private fun TestScope.selectColorOption(
+ colorOptions: () -> List<OptionItemViewModel<ColorOptionIconViewModel>>?,
+ index: Int,
+ ) {
+ val onClickedFlow = colorOptions()?.get(index)?.onClicked
+ val onClickedLastValueOrNull: (() -> (() -> Unit)?)? =
+ onClickedFlow?.let { collectLastValue(it) }
+ onClickedLastValueOrNull?.let { onClickedLastValue ->
+ val onClickedOrNull: (() -> Unit)? = onClickedLastValue()
+ onClickedOrNull?.let { onClicked -> onClicked() }
+ }
+ }
+
+ /**
+ * Asserts the entire picker UI state is what is expected. This includes the color type tabs and
+ * the color options list.
+ *
+ * @param colorTypes The observed color type view-models, keyed by ColorType
+ * @param colorOptions The observed color options
+ * @param selectedColorTypeText The text of the color type that's expected to be selected
+ * @param selectedColorOptionIndex The index of the color option that's expected to be selected,
+ * -1 stands for no color option should be selected
+ */
+ private fun TestScope.assertPickerUiState(
+ colorTypes: Map<ColorType, ColorTypeTabViewModel>?,
+ colorOptions: List<OptionItemViewModel<ColorOptionIconViewModel>>?,
+ selectedColorTypeText: String,
+ selectedColorOptionIndex: Int,
+ ) {
+ assertColorTypeTabUiState(
+ colorTypes = colorTypes,
+ colorTypeId = ColorType.WALLPAPER_COLOR,
+ isSelected = "Wallpaper colors" == selectedColorTypeText,
+ )
+ assertColorTypeTabUiState(
+ colorTypes = colorTypes,
+ colorTypeId = ColorType.PRESET_COLOR,
+ isSelected = "Basic colors" == selectedColorTypeText,
+ )
+ assertColorOptionUiState(colorOptions, selectedColorOptionIndex)
+ }
+
+ /**
+ * Asserts the picker section UI state is what is expected.
+ *
+ * @param colorOptions The observed color options
+ * @param selectedColorOptionIndex The index of the color option that's expected to be selected,
+ * -1 stands for no color option should be selected
+ */
+ private fun TestScope.assertColorOptionUiState(
+ colorOptions: List<OptionItemViewModel<ColorOptionIconViewModel>>?,
+ selectedColorOptionIndex: Int,
+ ) {
+ var foundSelectedColorOption = false
+ assertThat(colorOptions).isNotNull()
+ if (colorOptions != null) {
+ for (i in colorOptions.indices) {
+ val colorOptionHasSelectedIndex = i == selectedColorOptionIndex
+ val isSelected: Boolean? = collectLastValue(colorOptions[i].isSelected).invoke()
+ assertWithMessage(
+ "Expected color option with index \"${i}\" to have" +
+ " isSelected=$colorOptionHasSelectedIndex but it was" +
+ " ${isSelected}, num options: ${colorOptions.size}"
+ )
+ .that(isSelected)
+ .isEqualTo(colorOptionHasSelectedIndex)
+ foundSelectedColorOption = foundSelectedColorOption || colorOptionHasSelectedIndex
+ }
+ if (selectedColorOptionIndex == -1) {
+ assertWithMessage(
+ "Expected no color options to be selected, but a color option is" +
+ " selected"
+ )
+ .that(foundSelectedColorOption)
+ .isFalse()
+ } else {
+ assertWithMessage(
+ "Expected a color option to be selected, but no color option is" +
+ " selected"
+ )
+ .that(foundSelectedColorOption)
+ .isTrue()
+ }
+ }
+ }
+
+ /**
+ * Asserts that a color type tab has the correct UI state.
+ *
+ * @param colorTypes The observed color type view-models, keyed by ColorType enum
+ * @param colorTypeId the ID of the color type to assert
+ * @param isSelected Whether that color type should be selected
+ */
+ private fun assertColorTypeTabUiState(
+ colorTypes: Map<ColorType, ColorTypeTabViewModel>?,
+ colorTypeId: ColorType,
+ isSelected: Boolean,
+ ) {
+ val viewModel =
+ colorTypes?.get(colorTypeId) ?: error("No color type with ID \"$colorTypeId\"!")
+ assertThat(viewModel.isSelected).isEqualTo(isSelected)
+ }
+}
diff --git a/tests/src/com/android/customization/model/picker/quickaffordance/domain/interactor/KeyguardQuickAffordancePickerInteractorTest.kt b/tests/src/com/android/customization/model/picker/quickaffordance/domain/interactor/KeyguardQuickAffordancePickerInteractorTest.kt
index 9a2a0af..fea94dc 100644
--- a/tests/src/com/android/customization/model/picker/quickaffordance/domain/interactor/KeyguardQuickAffordancePickerInteractorTest.kt
+++ b/tests/src/com/android/customization/model/picker/quickaffordance/domain/interactor/KeyguardQuickAffordancePickerInteractorTest.kt
@@ -24,6 +24,7 @@
import com.android.customization.picker.quickaffordance.shared.model.KeyguardQuickAffordancePickerSelectionModel
import com.android.systemui.shared.customization.data.content.FakeCustomizationProviderClient
import com.android.systemui.shared.keyguard.shared.model.KeyguardQuickAffordanceSlots
+import com.android.wallpaper.testing.FakeSnapshotStore
import com.android.wallpaper.testing.collectLastValue
import com.google.common.truth.Truth.assertThat
import kotlinx.coroutines.Dispatchers
@@ -69,7 +70,7 @@
interactor = underTest,
client = client,
)
- .apply { runBlocking { setUpSnapshotRestorer {} } }
+ .apply { runBlocking { setUpSnapshotRestorer(FakeSnapshotStore()) } }
},
)
}
@@ -114,23 +115,6 @@
}
@Test
- fun unselect() =
- testScope.runTest {
- val selections = collectLastValue(underTest.selections)
- underTest.select(
- slotId = KeyguardQuickAffordanceSlots.SLOT_ID_BOTTOM_START,
- affordanceId = FakeCustomizationProviderClient.AFFORDANCE_1,
- )
-
- underTest.unselect(
- slotId = KeyguardQuickAffordanceSlots.SLOT_ID_BOTTOM_START,
- affordanceId = FakeCustomizationProviderClient.AFFORDANCE_1,
- )
-
- assertThat(selections()).isEmpty()
- }
-
- @Test
fun unselectAll() =
testScope.runTest {
client.setSlotCapacity(KeyguardQuickAffordanceSlots.SLOT_ID_BOTTOM_END, 3)
diff --git a/tests/src/com/android/customization/model/picker/quickaffordance/ui/viewmodel/KeyguardQuickAffordancePickerViewModelTest.kt b/tests/src/com/android/customization/model/picker/quickaffordance/ui/viewmodel/KeyguardQuickAffordancePickerViewModelTest.kt
index d1214c1..103ae84 100644
--- a/tests/src/com/android/customization/model/picker/quickaffordance/ui/viewmodel/KeyguardQuickAffordancePickerViewModelTest.kt
+++ b/tests/src/com/android/customization/model/picker/quickaffordance/ui/viewmodel/KeyguardQuickAffordancePickerViewModelTest.kt
@@ -18,6 +18,7 @@
package com.android.customization.model.picker.quickaffordance.ui.viewmodel
import android.content.Context
+import android.content.Intent
import androidx.test.filters.SmallTest
import androidx.test.platform.app.InstrumentationRegistry
import com.android.customization.picker.quickaffordance.data.repository.KeyguardQuickAffordancePickerRepository
@@ -26,14 +27,15 @@
import com.android.customization.picker.quickaffordance.ui.viewmodel.KeyguardQuickAffordancePickerViewModel
import com.android.customization.picker.quickaffordance.ui.viewmodel.KeyguardQuickAffordanceSlotViewModel
import com.android.customization.picker.quickaffordance.ui.viewmodel.KeyguardQuickAffordanceSummaryViewModel
-import com.android.customization.picker.quickaffordance.ui.viewmodel.KeyguardQuickAffordanceViewModel
import com.android.systemui.shared.customization.data.content.CustomizationProviderClient
import com.android.systemui.shared.customization.data.content.FakeCustomizationProviderClient
import com.android.systemui.shared.keyguard.shared.model.KeyguardQuickAffordanceSlots
+import com.android.wallpaper.R
import com.android.wallpaper.module.InjectorProvider
-import com.android.wallpaper.picker.undo.data.repository.UndoRepository
-import com.android.wallpaper.picker.undo.domain.interactor.UndoInteractor
-import com.android.wallpaper.testing.FAKE_RESTORERS
+import com.android.wallpaper.picker.common.icon.ui.viewmodel.Icon
+import com.android.wallpaper.picker.common.text.ui.viewmodel.Text
+import com.android.wallpaper.picker.option.ui.viewmodel.OptionItemViewModel
+import com.android.wallpaper.testing.FakeSnapshotStore
import com.android.wallpaper.testing.TestCurrentWallpaperInfoFactory
import com.android.wallpaper.testing.TestInjector
import com.android.wallpaper.testing.collectLastValue
@@ -65,6 +67,8 @@
private lateinit var client: FakeCustomizationProviderClient
private lateinit var quickAffordanceInteractor: KeyguardQuickAffordancePickerInteractor
+ private var latestStartedActivityIntent: Intent? = null
+
@Before
fun setUp() {
InjectorProvider.setInjector(TestInjector())
@@ -87,21 +91,15 @@
interactor = quickAffordanceInteractor,
client = client,
)
- .apply { runBlocking { setUpSnapshotRestorer {} } }
+ .apply { runBlocking { setUpSnapshotRestorer(FakeSnapshotStore()) } }
},
)
- val undoInteractor =
- UndoInteractor(
- scope = testScope.backgroundScope,
- repository = UndoRepository(),
- restorerByOwnerId = FAKE_RESTORERS,
- )
underTest =
KeyguardQuickAffordancePickerViewModel.Factory(
context = context,
quickAffordanceInteractor = quickAffordanceInteractor,
- undoInteractor = undoInteractor,
wallpaperInfoFactory = TestCurrentWallpaperInfoFactory(context),
+ activityStarter = { intent -> latestStartedActivityIntent = intent },
)
.create(KeyguardQuickAffordancePickerViewModel::class.java)
}
@@ -134,7 +132,7 @@
)
// Select "affordance 1" for the first slot.
- quickAffordances()?.get(1)?.onClicked?.invoke()
+ selectAffordance(quickAffordances, 1)
assertPickerUiState(
slots = slots(),
affordances = quickAffordances(),
@@ -155,7 +153,7 @@
// First, switch to the second slot:
slots()?.get(KeyguardQuickAffordanceSlots.SLOT_ID_BOTTOM_END)?.onClicked?.invoke()
// Second, select the "affordance 3" affordance:
- quickAffordances()?.get(3)?.onClicked?.invoke()
+ selectAffordance(quickAffordances, 3)
assertPickerUiState(
slots = slots(),
affordances = quickAffordances(),
@@ -174,7 +172,7 @@
)
// Select a different affordance for the second slot.
- quickAffordances()?.get(2)?.onClicked?.invoke()
+ selectAffordance(quickAffordances, 2)
assertPickerUiState(
slots = slots(),
affordances = quickAffordances(),
@@ -200,17 +198,17 @@
val quickAffordances = collectLastValue(underTest.quickAffordances)
// Select "affordance 1" for the first slot.
- quickAffordances()?.get(1)?.onClicked?.invoke()
+ selectAffordance(quickAffordances, 1)
// Select an affordance for the second slot.
// First, switch to the second slot:
slots()?.get(KeyguardQuickAffordanceSlots.SLOT_ID_BOTTOM_END)?.onClicked?.invoke()
// Second, select the "affordance 3" affordance:
- quickAffordances()?.get(3)?.onClicked?.invoke()
+ selectAffordance(quickAffordances, 3)
// Switch back to the first slot:
slots()?.get(KeyguardQuickAffordanceSlots.SLOT_ID_BOTTOM_START)?.onClicked?.invoke()
// Select the "none" affordance, which is always in position 0:
- quickAffordances()?.get(0)?.onClicked?.invoke()
+ selectAffordance(quickAffordances, 0)
assertPickerUiState(
slots = slots(),
@@ -256,14 +254,17 @@
)
// Lets try to select that disabled affordance:
- quickAffordances()?.get(affordanceIndex + 1)?.onClicked?.invoke()
+ selectAffordance(quickAffordances, affordanceIndex + 1)
// We expect there to be a dialog that should be shown:
- assertThat(dialog()?.icon).isEqualTo(FakeCustomizationProviderClient.ICON_1)
- assertThat(dialog()?.instructions).isEqualTo(enablementInstructions)
- assertThat(dialog()?.actionText).isEqualTo(enablementActionText)
- assertThat(dialog()?.intent?.`package`).isEqualTo(packageName)
- assertThat(dialog()?.intent?.action).isEqualTo(action)
+ assertThat(dialog()?.icon)
+ .isEqualTo(Icon.Loaded(FakeCustomizationProviderClient.ICON_1, null))
+ assertThat(dialog()?.title).isEqualTo(Text.Loaded("disabled"))
+ assertThat(dialog()?.message)
+ .isEqualTo(Text.Loaded(enablementInstructions.joinToString("\n")))
+ assertThat(dialog()?.buttons?.size).isEqualTo(1)
+ assertThat(dialog()?.buttons?.first()?.text)
+ .isEqualTo(Text.Loaded(enablementActionText))
// Once we report that the dialog has been dismissed by the user, we expect there to be
// no
@@ -273,6 +274,30 @@
}
@Test
+ fun `Start settings activity when long-pressing an affordance`() =
+ testScope.runTest {
+ val quickAffordances = collectLastValue(underTest.quickAffordances)
+
+ // Lets add a configurable affordance to the picker:
+ val configureIntent = Intent("some.action")
+ val affordanceIndex =
+ client.addAffordance(
+ CustomizationProviderClient.Affordance(
+ id = "affordance",
+ name = "affordance",
+ iconResourceId = 1,
+ isEnabled = true,
+ configureIntent = configureIntent,
+ )
+ )
+
+ // Lets try to long-click the affordance:
+ quickAffordances()?.get(affordanceIndex + 1)?.onLongClicked?.invoke()
+
+ assertThat(latestStartedActivityIntent).isEqualTo(configureIntent)
+ }
+
+ @Test
fun `summary - affordance selected in both bottom-start and bottom-end`() =
testScope.runTest {
val slots = collectLastValue(underTest.slots)
@@ -280,21 +305,23 @@
val summary = collectLastValue(underTest.summary)
// Select "affordance 1" for the first slot.
- quickAffordances()?.get(1)?.onClicked?.invoke()
+ selectAffordance(quickAffordances, 1)
// Select an affordance for the second slot.
// First, switch to the second slot:
slots()?.get(KeyguardQuickAffordanceSlots.SLOT_ID_BOTTOM_END)?.onClicked?.invoke()
// Second, select the "affordance 3" affordance:
- quickAffordances()?.get(3)?.onClicked?.invoke()
+ selectAffordance(quickAffordances, 3)
assertThat(summary())
.isEqualTo(
KeyguardQuickAffordanceSummaryViewModel(
description =
- "${FakeCustomizationProviderClient.AFFORDANCE_1}," +
- " ${FakeCustomizationProviderClient.AFFORDANCE_3}",
- icon1 = FakeCustomizationProviderClient.ICON_1,
- icon2 = FakeCustomizationProviderClient.ICON_3,
+ Text.Loaded(
+ "${FakeCustomizationProviderClient.AFFORDANCE_1}," +
+ " ${FakeCustomizationProviderClient.AFFORDANCE_3}"
+ ),
+ icon1 = Icon.Loaded(FakeCustomizationProviderClient.ICON_1, null),
+ icon2 = Icon.Loaded(FakeCustomizationProviderClient.ICON_3, null),
)
)
}
@@ -307,13 +334,13 @@
val summary = collectLastValue(underTest.summary)
// Select "affordance 1" for the first slot.
- quickAffordances()?.get(1)?.onClicked?.invoke()
+ selectAffordance(quickAffordances, 1)
assertThat(summary())
.isEqualTo(
KeyguardQuickAffordanceSummaryViewModel(
- description = FakeCustomizationProviderClient.AFFORDANCE_1,
- icon1 = FakeCustomizationProviderClient.ICON_1,
+ description = Text.Loaded(FakeCustomizationProviderClient.AFFORDANCE_1),
+ icon1 = Icon.Loaded(FakeCustomizationProviderClient.ICON_1, null),
icon2 = null,
)
)
@@ -330,14 +357,14 @@
// First, switch to the second slot:
slots()?.get(KeyguardQuickAffordanceSlots.SLOT_ID_BOTTOM_END)?.onClicked?.invoke()
// Second, select the "affordance 3" affordance:
- quickAffordances()?.get(3)?.onClicked?.invoke()
+ selectAffordance(quickAffordances, 3)
assertThat(summary())
.isEqualTo(
KeyguardQuickAffordanceSummaryViewModel(
- description = FakeCustomizationProviderClient.AFFORDANCE_3,
+ description = Text.Loaded(FakeCustomizationProviderClient.AFFORDANCE_3),
icon1 = null,
- icon2 = FakeCustomizationProviderClient.ICON_3,
+ icon2 = Icon.Loaded(FakeCustomizationProviderClient.ICON_3, null),
)
)
}
@@ -345,15 +372,28 @@
@Test
fun `summary - no affordances selected`() =
testScope.runTest {
- val slots = collectLastValue(underTest.slots)
- val quickAffordances = collectLastValue(underTest.quickAffordances)
val summary = collectLastValue(underTest.summary)
- assertThat(summary()?.description).isEqualTo("None")
+ assertThat(summary()?.description)
+ .isEqualTo(Text.Resource(R.string.keyguard_quick_affordance_none_selected))
assertThat(summary()?.icon1).isNotNull()
assertThat(summary()?.icon2).isNull()
}
+ /** Simulates a user selecting the affordance at the given index, if that is clickable. */
+ private fun TestScope.selectAffordance(
+ affordances: () -> List<OptionItemViewModel<Icon>>?,
+ index: Int,
+ ) {
+ val onClickedFlow = affordances()?.get(index)?.onClicked
+ val onClickedLastValueOrNull: (() -> (() -> Unit)?)? =
+ onClickedFlow?.let { collectLastValue(it) }
+ onClickedLastValueOrNull?.let { onClickedLastValue ->
+ val onClickedOrNull: (() -> Unit)? = onClickedLastValue()
+ onClickedOrNull?.let { onClicked -> onClicked() }
+ }
+ }
+
/**
* Asserts the entire picker UI state is what is expected. This includes the slot tabs and the
* affordance list.
@@ -363,9 +403,9 @@
* @param selectedSlotText The text of the slot that's expected to be selected
* @param selectedAffordanceText The text of the affordance that's expected to be selected
*/
- private fun assertPickerUiState(
+ private fun TestScope.assertPickerUiState(
slots: Map<String, KeyguardQuickAffordanceSlotViewModel>?,
- affordances: List<KeyguardQuickAffordanceViewModel>?,
+ affordances: List<OptionItemViewModel<Icon>>?,
selectedSlotText: String,
selectedAffordanceText: String,
) {
@@ -383,12 +423,18 @@
var foundSelectedAffordance = false
assertThat(affordances).isNotNull()
affordances?.forEach { affordance ->
- val nameMatchesSelectedName = affordance.contentDescription == selectedAffordanceText
- assertWithMessage(
- "Expected affordance with name \"${affordance.contentDescription}\" to have" +
- " isSelected=$nameMatchesSelectedName but it was ${affordance.isSelected}"
+ val nameMatchesSelectedName =
+ Text.evaluationEquals(
+ context,
+ affordance.text,
+ Text.Loaded(selectedAffordanceText),
)
- .that(affordance.isSelected)
+ val isSelected: Boolean? = collectLastValue(affordance.isSelected).invoke()
+ assertWithMessage(
+ "Expected affordance with name \"${affordance.text}\" to have" +
+ " isSelected=$nameMatchesSelectedName but it was $isSelected"
+ )
+ .that(isSelected)
.isEqualTo(nameMatchesSelectedName)
foundSelectedAffordance = foundSelectedAffordance || nameMatchesSelectedName
}
@@ -416,7 +462,8 @@
*
* @param slots The observed slot view-models, keyed by slot ID
* @param expectedAffordanceNameBySlotId The expected name of the selected affordance for each
- * slot ID or `null` if it's expected for there to be no affordance for that slot in the preview
+ * slot ID or `null` if it's expected for there to be no affordance for that slot in the
+ * preview
*/
private fun assertPreviewUiState(
slots: Map<String, KeyguardQuickAffordanceSlotViewModel>?,
@@ -425,13 +472,12 @@
assertThat(slots).isNotNull()
slots?.forEach { (slotId, slotViewModel) ->
val expectedAffordanceName = expectedAffordanceNameBySlotId[slotId]
- val actualAffordanceName =
- slotViewModel.selectedQuickAffordances.firstOrNull()?.contentDescription
+ val actualAffordanceName = slotViewModel.selectedQuickAffordances.firstOrNull()?.text
assertWithMessage(
"At slotId=\"$slotId\", expected affordance=\"$expectedAffordanceName\" but" +
- " was \"$actualAffordanceName\"!"
+ " was \"${actualAffordanceName?.asString(context)}\"!"
)
- .that(actualAffordanceName)
+ .that(actualAffordanceName?.asString(context))
.isEqualTo(expectedAffordanceName)
}
}
diff --git a/tests/src/com/android/customization/model/themedicon/domain/interactor/ThemedIconInteractorTest.kt b/tests/src/com/android/customization/model/themedicon/domain/interactor/ThemedIconInteractorTest.kt
new file mode 100644
index 0000000..e6e30c3
--- /dev/null
+++ b/tests/src/com/android/customization/model/themedicon/domain/interactor/ThemedIconInteractorTest.kt
@@ -0,0 +1,56 @@
+/*
+ * 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.themedicon.domain.interactor
+
+import androidx.test.filters.SmallTest
+import com.android.customization.model.themedicon.data.repository.ThemeIconRepository
+import com.android.wallpaper.testing.collectLastValue
+import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.test.runTest
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.JUnit4
+
+@OptIn(ExperimentalCoroutinesApi::class)
+@SmallTest
+@RunWith(JUnit4::class)
+class ThemedIconInteractorTest {
+
+ private lateinit var underTest: ThemedIconInteractor
+
+ @Before
+ fun setUp() {
+ underTest =
+ ThemedIconInteractor(
+ repository = ThemeIconRepository(),
+ )
+ }
+
+ @Test
+ fun `end-to-end`() = runTest {
+ val isActivated = collectLastValue(underTest.isActivated)
+
+ underTest.setActivated(isActivated = true)
+ assertThat(isActivated()).isTrue()
+
+ underTest.setActivated(isActivated = false)
+ assertThat(isActivated()).isFalse()
+ }
+}
diff --git a/tests/src/com/android/customization/model/themedicon/domain/interactor/ThemedIconSnapshotRestorerTest.kt b/tests/src/com/android/customization/model/themedicon/domain/interactor/ThemedIconSnapshotRestorerTest.kt
new file mode 100644
index 0000000..df1fd20
--- /dev/null
+++ b/tests/src/com/android/customization/model/themedicon/domain/interactor/ThemedIconSnapshotRestorerTest.kt
@@ -0,0 +1,102 @@
+/*
+ * 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.themedicon.domain.interactor
+
+import androidx.test.filters.SmallTest
+import com.android.customization.model.themedicon.data.repository.ThemeIconRepository
+import com.android.wallpaper.testing.FakeSnapshotStore
+import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.test.runTest
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.JUnit4
+
+@OptIn(ExperimentalCoroutinesApi::class)
+@SmallTest
+@RunWith(JUnit4::class)
+class ThemedIconSnapshotRestorerTest {
+
+ private lateinit var underTest: ThemedIconSnapshotRestorer
+ private var isActivated = false
+
+ @Before
+ fun setUp() {
+ isActivated = false
+ underTest =
+ ThemedIconSnapshotRestorer(
+ isActivated = { isActivated },
+ setActivated = { isActivated = it },
+ interactor =
+ ThemedIconInteractor(
+ repository = ThemeIconRepository(),
+ )
+ )
+ }
+
+ @Test
+ fun `set up and restore - active`() = runTest {
+ isActivated = true
+
+ val store = FakeSnapshotStore()
+ store.store(underTest.setUpSnapshotRestorer(store = store))
+ val storedSnapshot = store.retrieve()
+
+ underTest.restoreToSnapshot(snapshot = storedSnapshot)
+ assertThat(isActivated).isTrue()
+ }
+
+ @Test
+ fun `set up and restore - inactive`() = runTest {
+ isActivated = false
+
+ val store = FakeSnapshotStore()
+ store.store(underTest.setUpSnapshotRestorer(store = store))
+ val storedSnapshot = store.retrieve()
+
+ underTest.restoreToSnapshot(snapshot = storedSnapshot)
+ assertThat(isActivated).isFalse()
+ }
+
+ @Test
+ fun `set up - deactivate - restore to active`() = runTest {
+ isActivated = true
+ val store = FakeSnapshotStore()
+ store.store(underTest.setUpSnapshotRestorer(store = store))
+ val initialSnapshot = store.retrieve()
+
+ underTest.store(isActivated = false)
+
+ underTest.restoreToSnapshot(snapshot = initialSnapshot)
+ assertThat(isActivated).isTrue()
+ }
+
+ @Test
+ fun `set up - activate - restore to inactive`() = runTest {
+ isActivated = false
+ val store = FakeSnapshotStore()
+ store.store(underTest.setUpSnapshotRestorer(store = store))
+ val initialSnapshot = store.retrieve()
+
+ underTest.store(isActivated = true)
+
+ underTest.restoreToSnapshot(snapshot = initialSnapshot)
+ assertThat(isActivated).isFalse()
+ }
+}
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
new file mode 100644
index 0000000..2ef4e97
--- /dev/null
+++ b/tests/src/com/android/customization/picker/clock/data/repository/FakeClockPickerRepository.kt
@@ -0,0 +1,89 @@
+/*
+ * 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.data.repository
+
+import android.graphics.Color
+import androidx.annotation.ColorInt
+import androidx.annotation.IntRange
+import com.android.customization.picker.clock.data.repository.FakeClockPickerRepository.Companion.fakeClocks
+import com.android.customization.picker.clock.shared.ClockSize
+import com.android.customization.picker.clock.shared.model.ClockMetadataModel
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.MutableStateFlow
+import kotlinx.coroutines.flow.asStateFlow
+import kotlinx.coroutines.flow.combine
+
+/** By default [FakeClockPickerRepository] uses [fakeClocks]. */
+open class FakeClockPickerRepository(clocks: List<ClockMetadataModel> = fakeClocks) :
+ ClockPickerRepository {
+ override val allClocks: Flow<List<ClockMetadataModel>> = MutableStateFlow(clocks).asStateFlow()
+
+ private val selectedClockId = MutableStateFlow(fakeClocks[0].clockId)
+ @ColorInt private val selectedColorId = MutableStateFlow<String?>(null)
+ private val colorTone = MutableStateFlow(ClockMetadataModel.DEFAULT_COLOR_TONE_PROGRESS)
+ @ColorInt private val seedColor = MutableStateFlow<Int?>(null)
+ override val selectedClock: Flow<ClockMetadataModel> =
+ combine(
+ selectedClockId,
+ selectedColorId,
+ colorTone,
+ seedColor,
+ ) { selectedClockId, selectedColor, colorTone, seedColor ->
+ val selectedClock = fakeClocks.find { clock -> clock.clockId == selectedClockId }
+ checkNotNull(selectedClock)
+ ClockMetadataModel(
+ selectedClock.clockId,
+ selectedClock.name,
+ selectedColor,
+ colorTone,
+ seedColor,
+ )
+ }
+
+ private val _selectedClockSize = MutableStateFlow(ClockSize.SMALL)
+ override val selectedClockSize: Flow<ClockSize> = _selectedClockSize.asStateFlow()
+
+ override fun setSelectedClock(clockId: String) {
+ selectedClockId.value = clockId
+ }
+
+ override fun setClockColor(
+ selectedColorId: String?,
+ @IntRange(from = 0, to = 100) colorToneProgress: Int,
+ @ColorInt seedColor: Int?,
+ ) {
+ this.selectedColorId.value = selectedColorId
+ this.colorTone.value = colorToneProgress
+ this.seedColor.value = seedColor
+ }
+
+ override suspend fun setClockSize(size: ClockSize) {
+ _selectedClockSize.value = size
+ }
+
+ companion object {
+ val fakeClocks =
+ listOf(
+ ClockMetadataModel("clock0", "clock0", null, 50, null),
+ ClockMetadataModel("clock1", "clock1", null, 50, null),
+ ClockMetadataModel("clock2", "clock2", null, 50, null),
+ ClockMetadataModel("clock3", "clock3", null, 50, null),
+ )
+ const val CLOCK_COLOR_ID = "RED"
+ const val CLOCK_COLOR_TONE_PROGRESS = 87
+ const val SEED_COLOR = Color.RED
+ }
+}
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
new file mode 100644
index 0000000..cd41d7d
--- /dev/null
+++ b/tests/src/com/android/customization/picker/clock/domain/interactor/ClockPickerInteractorTest.kt
@@ -0,0 +1,73 @@
+package com.android.customization.picker.clock.domain.interactor
+
+import androidx.test.filters.SmallTest
+import com.android.customization.picker.clock.data.repository.FakeClockPickerRepository
+import com.android.customization.picker.clock.shared.ClockSize
+import com.android.wallpaper.testing.collectLastValue
+import com.google.common.truth.Truth
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.test.StandardTestDispatcher
+import kotlinx.coroutines.test.resetMain
+import kotlinx.coroutines.test.runTest
+import kotlinx.coroutines.test.setMain
+import org.junit.After
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.JUnit4
+
+@OptIn(ExperimentalCoroutinesApi::class)
+@SmallTest
+@RunWith(JUnit4::class)
+class ClockPickerInteractorTest {
+
+ private lateinit var underTest: ClockPickerInteractor
+
+ @Before
+ fun setUp() {
+ val testDispatcher = StandardTestDispatcher()
+ Dispatchers.setMain(testDispatcher)
+ underTest = ClockPickerInteractor(FakeClockPickerRepository())
+ }
+
+ @After
+ fun tearDown() {
+ Dispatchers.resetMain()
+ }
+
+ @Test
+ fun setSelectedClock() = runTest {
+ val observedSelectedClockId = collectLastValue(underTest.selectedClockId)
+ underTest.setSelectedClock(FakeClockPickerRepository.fakeClocks[1].clockId)
+ Truth.assertThat(observedSelectedClockId())
+ .isEqualTo(FakeClockPickerRepository.fakeClocks[1].clockId)
+ }
+
+ @Test
+ fun setClockSize() = runTest {
+ val observedClockSize = collectLastValue(underTest.selectedClockSize)
+ underTest.setClockSize(ClockSize.DYNAMIC)
+ Truth.assertThat(observedClockSize()).isEqualTo(ClockSize.DYNAMIC)
+
+ underTest.setClockSize(ClockSize.SMALL)
+ Truth.assertThat(observedClockSize()).isEqualTo(ClockSize.SMALL)
+ }
+
+ @Test
+ fun setColor() = runTest {
+ val observedSelectedColor = collectLastValue(underTest.selectedColorId)
+ val observedColorToneProgress = collectLastValue(underTest.colorToneProgress)
+ val observedSeedColor = collectLastValue(underTest.seedColor)
+ underTest.setClockColor(
+ FakeClockPickerRepository.CLOCK_COLOR_ID,
+ FakeClockPickerRepository.CLOCK_COLOR_TONE_PROGRESS,
+ FakeClockPickerRepository.SEED_COLOR,
+ )
+ Truth.assertThat(observedSelectedColor())
+ .isEqualTo(FakeClockPickerRepository.CLOCK_COLOR_ID)
+ Truth.assertThat(observedColorToneProgress())
+ .isEqualTo(FakeClockPickerRepository.CLOCK_COLOR_TONE_PROGRESS)
+ Truth.assertThat(observedSeedColor()).isEqualTo(FakeClockPickerRepository.SEED_COLOR)
+ }
+}
diff --git a/tests/src/com/android/customization/picker/clock/ui/viewmodel/ClockCarouselViewModelTest.kt b/tests/src/com/android/customization/picker/clock/ui/viewmodel/ClockCarouselViewModelTest.kt
new file mode 100644
index 0000000..63f77bd
--- /dev/null
+++ b/tests/src/com/android/customization/picker/clock/ui/viewmodel/ClockCarouselViewModelTest.kt
@@ -0,0 +1,120 @@
+/*
+ * 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.viewmodel
+
+import androidx.test.filters.SmallTest
+import com.android.customization.picker.clock.data.repository.FakeClockPickerRepository
+import com.android.customization.picker.clock.domain.interactor.ClockPickerInteractor
+import com.android.customization.picker.clock.shared.model.ClockMetadataModel
+import com.android.wallpaper.testing.collectLastValue
+import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.test.StandardTestDispatcher
+import kotlinx.coroutines.test.advanceTimeBy
+import kotlinx.coroutines.test.resetMain
+import kotlinx.coroutines.test.runTest
+import kotlinx.coroutines.test.setMain
+import org.junit.After
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.JUnit4
+
+@OptIn(ExperimentalCoroutinesApi::class)
+@SmallTest
+@RunWith(JUnit4::class)
+class ClockCarouselViewModelTest {
+ private val repositoryWithMultipleClocks by lazy { FakeClockPickerRepository() }
+ private val repositoryWithSingleClock by lazy {
+ FakeClockPickerRepository(
+ listOf(
+ ClockMetadataModel(
+ "clock0",
+ "clock0",
+ null,
+ ClockMetadataModel.DEFAULT_COLOR_TONE_PROGRESS,
+ null,
+ ),
+ )
+ )
+ }
+ private lateinit var underTest: ClockCarouselViewModel
+
+ @Before
+ fun setUp() {
+ val testDispatcher = StandardTestDispatcher()
+ Dispatchers.setMain(testDispatcher)
+ }
+
+ @After
+ fun tearDown() {
+ Dispatchers.resetMain()
+ }
+
+ @Test
+ fun setSelectedClock() = runTest {
+ underTest = ClockCarouselViewModel(ClockPickerInteractor(repositoryWithMultipleClocks))
+ val observedSelectedIndex = collectLastValue(underTest.selectedIndex)
+ advanceTimeBy(ClockCarouselViewModel.CLOCKS_EVENT_UPDATE_DELAY_MILLIS)
+ underTest.setSelectedClock(FakeClockPickerRepository.fakeClocks[2].clockId)
+ assertThat(observedSelectedIndex()).isEqualTo(2)
+ }
+
+ @Test
+ fun setShouldShowCarousel() = runTest {
+ underTest = ClockCarouselViewModel(ClockPickerInteractor(repositoryWithMultipleClocks))
+ val observedIsCarouselVisible = collectLastValue(underTest.isCarouselVisible)
+ advanceTimeBy(ClockCarouselViewModel.CLOCKS_EVENT_UPDATE_DELAY_MILLIS)
+ underTest.showClockCarousel(false)
+ assertThat(observedIsCarouselVisible()).isFalse()
+ underTest.showClockCarousel(true)
+ assertThat(observedIsCarouselVisible()).isTrue()
+ }
+
+ @Test
+ fun shouldNotShowCarouselWhenSingleClock() = runTest {
+ underTest = ClockCarouselViewModel(ClockPickerInteractor(repositoryWithSingleClock))
+ val observedIsCarouselVisible = collectLastValue(underTest.isCarouselVisible)
+ advanceTimeBy(ClockCarouselViewModel.CLOCKS_EVENT_UPDATE_DELAY_MILLIS)
+ underTest.showClockCarousel(false)
+ assertThat(observedIsCarouselVisible()).isFalse()
+ underTest.showClockCarousel(true)
+ assertThat(observedIsCarouselVisible()).isFalse()
+ }
+
+ @Test
+ fun setShouldShowSingleClock() = runTest {
+ underTest = ClockCarouselViewModel(ClockPickerInteractor(repositoryWithSingleClock))
+ val observedIsSingleClockViewVisible = collectLastValue(underTest.isSingleClockViewVisible)
+ advanceTimeBy(ClockCarouselViewModel.CLOCKS_EVENT_UPDATE_DELAY_MILLIS)
+ underTest.showClockCarousel(false)
+ assertThat(observedIsSingleClockViewVisible()).isFalse()
+ underTest.showClockCarousel(true)
+ assertThat(observedIsSingleClockViewVisible()).isTrue()
+ }
+
+ @Test
+ fun shouldNotShowSingleClockWhenMultipleClocks() = runTest {
+ underTest = ClockCarouselViewModel(ClockPickerInteractor(repositoryWithMultipleClocks))
+ val observedIsSingleClockViewVisible = collectLastValue(underTest.isSingleClockViewVisible)
+ advanceTimeBy(ClockCarouselViewModel.CLOCKS_EVENT_UPDATE_DELAY_MILLIS)
+ underTest.showClockCarousel(false)
+ assertThat(observedIsSingleClockViewVisible()).isFalse()
+ underTest.showClockCarousel(true)
+ assertThat(observedIsSingleClockViewVisible()).isFalse()
+ }
+}
diff --git a/tests/src/com/android/customization/picker/clock/ui/viewmodel/ClockSectionViewModelTest.kt b/tests/src/com/android/customization/picker/clock/ui/viewmodel/ClockSectionViewModelTest.kt
new file mode 100644
index 0000000..61976ad
--- /dev/null
+++ b/tests/src/com/android/customization/picker/clock/ui/viewmodel/ClockSectionViewModelTest.kt
@@ -0,0 +1,82 @@
+/*
+ * 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.viewmodel
+
+import androidx.test.filters.SmallTest
+import androidx.test.platform.app.InstrumentationRegistry
+import com.android.customization.picker.clock.data.repository.FakeClockPickerRepository
+import com.android.customization.picker.clock.domain.interactor.ClockPickerInteractor
+import com.android.customization.picker.clock.shared.ClockSize
+import com.android.customization.picker.clock.shared.model.ClockMetadataModel
+import com.android.wallpaper.testing.collectLastValue
+import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.test.StandardTestDispatcher
+import kotlinx.coroutines.test.resetMain
+import kotlinx.coroutines.test.runTest
+import kotlinx.coroutines.test.setMain
+import org.junit.After
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.JUnit4
+
+@OptIn(ExperimentalCoroutinesApi::class)
+@SmallTest
+@RunWith(JUnit4::class)
+class ClockSectionViewModelTest {
+
+ private lateinit var clockColorMap: Map<String, ClockColorViewModel>
+ private lateinit var interactor: ClockPickerInteractor
+ private lateinit var underTest: ClockSectionViewModel
+
+ @Before
+ fun setUp() {
+ val testDispatcher = StandardTestDispatcher()
+ Dispatchers.setMain(testDispatcher)
+ val context = InstrumentationRegistry.getInstrumentation().targetContext
+ clockColorMap = ClockColorViewModel.getPresetColorMap(context.resources)
+ interactor = ClockPickerInteractor(FakeClockPickerRepository())
+ underTest =
+ ClockSectionViewModel(
+ context,
+ interactor,
+ )
+ }
+
+ @After
+ fun tearDown() {
+ Dispatchers.resetMain()
+ }
+
+ @Test
+ fun setSelectedClock() = runTest {
+ val colorRed = clockColorMap.values.first()
+ val observedSelectedClockColorAndSizeText =
+ collectLastValue(underTest.selectedClockColorAndSizeText)
+ interactor.setClockColor(
+ colorRed.colorId,
+ ClockMetadataModel.DEFAULT_COLOR_TONE_PROGRESS,
+ ClockSettingsViewModel.blendColorWithTone(
+ colorRed.color,
+ colorRed.getColorTone(ClockMetadataModel.DEFAULT_COLOR_TONE_PROGRESS),
+ )
+ )
+ interactor.setClockSize(ClockSize.DYNAMIC)
+ assertThat(observedSelectedClockColorAndSizeText()).isEqualTo("Red, dynamic")
+ }
+}
diff --git a/tests/src/com/android/customization/picker/clock/ui/viewmodel/ClockSettingsViewModelTest.kt b/tests/src/com/android/customization/picker/clock/ui/viewmodel/ClockSettingsViewModelTest.kt
new file mode 100644
index 0000000..d53288d
--- /dev/null
+++ b/tests/src/com/android/customization/picker/clock/ui/viewmodel/ClockSettingsViewModelTest.kt
@@ -0,0 +1,156 @@
+package com.android.customization.picker.clock.ui.viewmodel
+
+import android.content.Context
+import androidx.test.filters.SmallTest
+import androidx.test.platform.app.InstrumentationRegistry
+import com.android.customization.picker.clock.data.repository.FakeClockPickerRepository
+import com.android.customization.picker.clock.domain.interactor.ClockPickerInteractor
+import com.android.customization.picker.clock.shared.ClockSize
+import com.android.customization.picker.clock.shared.model.ClockMetadataModel
+import com.android.customization.picker.color.data.repository.FakeColorPickerRepository
+import com.android.customization.picker.color.domain.interactor.ColorPickerInteractor
+import com.android.customization.picker.color.domain.interactor.ColorPickerSnapshotRestorer
+import com.android.wallpaper.testing.FakeSnapshotStore
+import com.android.wallpaper.testing.collectLastValue
+import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.runBlocking
+import kotlinx.coroutines.test.StandardTestDispatcher
+import kotlinx.coroutines.test.advanceTimeBy
+import kotlinx.coroutines.test.resetMain
+import kotlinx.coroutines.test.runTest
+import kotlinx.coroutines.test.setMain
+import org.junit.After
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.JUnit4
+
+@OptIn(ExperimentalCoroutinesApi::class)
+@SmallTest
+@RunWith(JUnit4::class)
+class ClockSettingsViewModelTest {
+
+ private lateinit var context: Context
+ private lateinit var colorPickerInteractor: ColorPickerInteractor
+ private lateinit var underTest: ClockSettingsViewModel
+ private lateinit var colorMap: Map<String, ClockColorViewModel>
+
+ @Before
+ fun setUp() {
+ val testDispatcher = StandardTestDispatcher()
+ Dispatchers.setMain(testDispatcher)
+ context = InstrumentationRegistry.getInstrumentation().targetContext
+ colorPickerInteractor =
+ ColorPickerInteractor(
+ repository = FakeColorPickerRepository(context = context),
+ snapshotRestorer = {
+ ColorPickerSnapshotRestorer(interactor = colorPickerInteractor).apply {
+ runBlocking { setUpSnapshotRestorer(store = FakeSnapshotStore()) }
+ }
+ },
+ )
+ underTest =
+ ClockSettingsViewModel.Factory(
+ context = context,
+ clockPickerInteractor = ClockPickerInteractor(FakeClockPickerRepository()),
+ colorPickerInteractor = colorPickerInteractor,
+ )
+ .create(ClockSettingsViewModel::class.java)
+ colorMap = ClockColorViewModel.getPresetColorMap(context.resources)
+ }
+
+ @After
+ fun tearDown() {
+ Dispatchers.resetMain()
+ }
+
+ @Test
+ fun clickOnColorSettingsTab() = runTest {
+ val tabs = collectLastValue(underTest.tabs)
+ assertThat(tabs()?.get(0)?.name).isEqualTo("Color")
+ assertThat(tabs()?.get(0)?.isSelected).isTrue()
+ assertThat(tabs()?.get(1)?.name).isEqualTo("Size")
+ assertThat(tabs()?.get(1)?.isSelected).isFalse()
+
+ tabs()?.get(1)?.onClicked?.invoke()
+ assertThat(tabs()?.get(0)?.isSelected).isFalse()
+ assertThat(tabs()?.get(1)?.isSelected).isTrue()
+ }
+
+ @Test
+ fun setSelectedColor() = runTest {
+ val observedClockColorOptions = collectLastValue(underTest.colorOptions)
+ val observedSelectedColorOptionPosition =
+ collectLastValue(underTest.selectedColorOptionPosition)
+ val observedSliderProgress = collectLastValue(underTest.sliderProgress)
+ val observedSeedColor = collectLastValue(underTest.seedColor)
+ // Advance COLOR_OPTIONS_EVENT_UPDATE_DELAY_MILLIS since there is a delay from colorOptions
+ advanceTimeBy(ClockSettingsViewModel.COLOR_OPTIONS_EVENT_UPDATE_DELAY_MILLIS)
+ assertThat(observedClockColorOptions()!![0].isSelected).isTrue()
+ assertThat(observedClockColorOptions()!![0].onClick).isNull()
+ assertThat(observedSelectedColorOptionPosition()).isEqualTo(0)
+
+ observedClockColorOptions()!![1].onClick?.invoke()
+ // Advance COLOR_OPTIONS_EVENT_UPDATE_DELAY_MILLIS since there is a delay from colorOptions
+ advanceTimeBy(ClockSettingsViewModel.COLOR_OPTIONS_EVENT_UPDATE_DELAY_MILLIS)
+ assertThat(observedClockColorOptions()!![1].isSelected).isTrue()
+ assertThat(observedClockColorOptions()!![1].onClick).isNull()
+ assertThat(observedSelectedColorOptionPosition()).isEqualTo(1)
+ assertThat(observedSliderProgress())
+ .isEqualTo(ClockMetadataModel.DEFAULT_COLOR_TONE_PROGRESS)
+ val expectedSelectedColorModel = colorMap.values.first() // RED
+ assertThat(observedSeedColor())
+ .isEqualTo(
+ ClockSettingsViewModel.blendColorWithTone(
+ expectedSelectedColorModel.color,
+ expectedSelectedColorModel.getColorTone(
+ ClockMetadataModel.DEFAULT_COLOR_TONE_PROGRESS
+ ),
+ )
+ )
+ }
+
+ @Test
+ fun setColorTone() = runTest {
+ val observedClockColorOptions = collectLastValue(underTest.colorOptions)
+ val observedIsSliderEnabled = collectLastValue(underTest.isSliderEnabled)
+ val observedSliderProgress = collectLastValue(underTest.sliderProgress)
+ val observedSeedColor = collectLastValue(underTest.seedColor)
+ // Advance COLOR_OPTIONS_EVENT_UPDATE_DELAY_MILLIS since there is a delay from colorOptions
+ advanceTimeBy(ClockSettingsViewModel.COLOR_OPTIONS_EVENT_UPDATE_DELAY_MILLIS)
+ assertThat(observedClockColorOptions()!![0].isSelected).isTrue()
+ assertThat(observedIsSliderEnabled()).isFalse()
+
+ observedClockColorOptions()!![1].onClick?.invoke()
+
+ // Advance COLOR_OPTIONS_EVENT_UPDATE_DELAY_MILLIS since there is a delay from colorOptions
+ advanceTimeBy(ClockSettingsViewModel.COLOR_OPTIONS_EVENT_UPDATE_DELAY_MILLIS)
+ assertThat(observedIsSliderEnabled()).isTrue()
+ val targetProgress1 = 99
+ underTest.onSliderProgressChanged(targetProgress1)
+ assertThat(observedSliderProgress()).isEqualTo(targetProgress1)
+ val targetProgress2 = 55
+ underTest.onSliderProgressStop(targetProgress2)
+ assertThat(observedSliderProgress()).isEqualTo(targetProgress2)
+ val expectedSelectedColorModel = colorMap.values.first() // RED
+ assertThat(observedSeedColor())
+ .isEqualTo(
+ ClockSettingsViewModel.blendColorWithTone(
+ expectedSelectedColorModel.color,
+ expectedSelectedColorModel.getColorTone(targetProgress2),
+ )
+ )
+ }
+
+ @Test
+ fun setClockSize() = runTest {
+ val observedClockSize = collectLastValue(underTest.selectedClockSize)
+ underTest.setClockSize(ClockSize.DYNAMIC)
+ assertThat(observedClockSize()).isEqualTo(ClockSize.DYNAMIC)
+
+ underTest.setClockSize(ClockSize.SMALL)
+ assertThat(observedClockSize()).isEqualTo(ClockSize.SMALL)
+ }
+}
diff --git a/tests/src/com/android/customization/picker/notifications/data/repository/NotificationsRepositoryTest.kt b/tests/src/com/android/customization/picker/notifications/data/repository/NotificationsRepositoryTest.kt
new file mode 100644
index 0000000..be799db
--- /dev/null
+++ b/tests/src/com/android/customization/picker/notifications/data/repository/NotificationsRepositoryTest.kt
@@ -0,0 +1,94 @@
+/*
+ * 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.notifications.data.repository
+
+import android.provider.Settings
+import androidx.test.filters.SmallTest
+import com.android.customization.picker.notifications.shared.model.NotificationSettingsModel
+import com.android.wallpaper.testing.FakeSecureSettingsRepository
+import com.android.wallpaper.testing.collectLastValue
+import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.test.StandardTestDispatcher
+import kotlinx.coroutines.test.TestScope
+import kotlinx.coroutines.test.runTest
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.JUnit4
+
+@OptIn(ExperimentalCoroutinesApi::class)
+@SmallTest
+@RunWith(JUnit4::class)
+class NotificationsRepositoryTest {
+
+ private lateinit var underTest: NotificationsRepository
+
+ private lateinit var testScope: TestScope
+ private lateinit var secureSettingsRepository: FakeSecureSettingsRepository
+
+ @Before
+ fun setUp() {
+ val testDispatcher = StandardTestDispatcher()
+ testScope = TestScope(testDispatcher)
+ secureSettingsRepository = FakeSecureSettingsRepository()
+
+ underTest =
+ NotificationsRepository(
+ scope = testScope.backgroundScope,
+ backgroundDispatcher = testDispatcher,
+ secureSettingsRepository = secureSettingsRepository,
+ )
+ }
+
+ @Test
+ fun settings() =
+ testScope.runTest {
+ val settings = collectLastValue(underTest.settings)
+
+ secureSettingsRepository.set(
+ name = Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS,
+ value = 1,
+ )
+ assertThat(settings())
+ .isEqualTo(NotificationSettingsModel(isShowNotificationsOnLockScreenEnabled = true))
+
+ secureSettingsRepository.set(
+ name = Settings.Secure.LOCK_SCREEN_SHOW_NOTIFICATIONS,
+ value = 0,
+ )
+ assertThat(settings())
+ .isEqualTo(
+ NotificationSettingsModel(isShowNotificationsOnLockScreenEnabled = false)
+ )
+ }
+
+ @Test
+ fun setSettings() =
+ testScope.runTest {
+ val settings = collectLastValue(underTest.settings)
+
+ val model1 = NotificationSettingsModel(isShowNotificationsOnLockScreenEnabled = true)
+ underTest.setSettings(model1)
+ assertThat(settings()).isEqualTo(model1)
+
+ val model2 = NotificationSettingsModel(isShowNotificationsOnLockScreenEnabled = false)
+ underTest.setSettings(model2)
+ assertThat(settings()).isEqualTo(model2)
+ }
+}
diff --git a/tests/src/com/android/customization/picker/notifications/ui/viewmodel/NotificationSectionViewModelTest.kt b/tests/src/com/android/customization/picker/notifications/ui/viewmodel/NotificationSectionViewModelTest.kt
new file mode 100644
index 0000000..6442609
--- /dev/null
+++ b/tests/src/com/android/customization/picker/notifications/ui/viewmodel/NotificationSectionViewModelTest.kt
@@ -0,0 +1,101 @@
+/*
+ * 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.notifications.ui.viewmodel
+
+import androidx.test.filters.SmallTest
+import com.android.customization.picker.notifications.data.repository.NotificationsRepository
+import com.android.customization.picker.notifications.domain.interactor.NotificationsInteractor
+import com.android.customization.picker.notifications.domain.interactor.NotificationsSnapshotRestorer
+import com.android.wallpaper.testing.FakeSecureSettingsRepository
+import com.android.wallpaper.testing.FakeSnapshotStore
+import com.android.wallpaper.testing.collectLastValue
+import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.runBlocking
+import kotlinx.coroutines.test.TestScope
+import kotlinx.coroutines.test.UnconfinedTestDispatcher
+import kotlinx.coroutines.test.resetMain
+import kotlinx.coroutines.test.runTest
+import kotlinx.coroutines.test.setMain
+import org.junit.After
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.JUnit4
+
+@OptIn(ExperimentalCoroutinesApi::class)
+@SmallTest
+@RunWith(JUnit4::class)
+class NotificationSectionViewModelTest {
+
+ private lateinit var underTest: NotificationSectionViewModel
+
+ private lateinit var testScope: TestScope
+ private lateinit var interactor: NotificationsInteractor
+
+ @Before
+ fun setUp() {
+ val testDispatcher = UnconfinedTestDispatcher()
+ Dispatchers.setMain(testDispatcher)
+ testScope = TestScope(testDispatcher)
+ interactor =
+ NotificationsInteractor(
+ repository =
+ NotificationsRepository(
+ scope = testScope.backgroundScope,
+ backgroundDispatcher = testDispatcher,
+ secureSettingsRepository = FakeSecureSettingsRepository(),
+ ),
+ snapshotRestorer = {
+ NotificationsSnapshotRestorer(
+ interactor = interactor,
+ )
+ .apply { runBlocking { setUpSnapshotRestorer(FakeSnapshotStore()) } }
+ },
+ )
+
+ underTest =
+ NotificationSectionViewModel(
+ interactor = interactor,
+ )
+ }
+
+ @After
+ fun tearDown() {
+ Dispatchers.resetMain()
+ }
+
+ @Test
+ fun `toggles back and forth`() =
+ testScope.runTest {
+ val subtitleStringResId = collectLastValue(underTest.subtitleStringResourceId)
+ val isSwitchOn = collectLastValue(underTest.isSwitchOn)
+
+ val initialSubtitleStringRes = subtitleStringResId()
+ val initialIsSwitchOn = isSwitchOn()
+
+ underTest.onClicked()
+ assertThat(subtitleStringResId()).isNotEqualTo(initialSubtitleStringRes)
+ assertThat(isSwitchOn()).isNotEqualTo(initialIsSwitchOn)
+
+ underTest.onClicked()
+ assertThat(subtitleStringResId()).isEqualTo(initialSubtitleStringRes)
+ assertThat(isSwitchOn()).isEqualTo(initialIsSwitchOn)
+ }
+}
diff --git a/tests/src/com/android/customization/testing/TestCustomizationInjector.java b/tests/src/com/android/customization/testing/TestCustomizationInjector.java
deleted file mode 100644
index d609335..0000000
--- a/tests/src/com/android/customization/testing/TestCustomizationInjector.java
+++ /dev/null
@@ -1,143 +0,0 @@
-package com.android.customization.testing;
-
-import android.content.Context;
-
-import androidx.fragment.app.FragmentActivity;
-
-import com.android.customization.model.theme.OverlayManagerCompat;
-import com.android.customization.model.theme.ThemeBundleProvider;
-import com.android.customization.model.theme.ThemeManager;
-import com.android.customization.module.CustomizationInjector;
-import com.android.customization.module.CustomizationPreferences;
-import com.android.customization.module.ThemesUserEventLogger;
-import com.android.customization.picker.quickaffordance.data.repository.KeyguardQuickAffordancePickerRepository;
-import com.android.customization.picker.quickaffordance.domain.interactor.KeyguardQuickAffordancePickerInteractor;
-import com.android.customization.picker.quickaffordance.domain.interactor.KeyguardQuickAffordanceSnapshotRestorer;
-import com.android.systemui.shared.customization.data.content.CustomizationProviderClient;
-import com.android.systemui.shared.customization.data.content.CustomizationProviderClientImpl;
-import com.android.wallpaper.config.BaseFlags;
-import com.android.wallpaper.module.DrawableLayerResolver;
-import com.android.wallpaper.module.PackageStatusNotifier;
-import com.android.wallpaper.module.UserEventLogger;
-import com.android.wallpaper.picker.undo.domain.interactor.SnapshotRestorer;
-import com.android.wallpaper.testing.TestInjector;
-
-import java.util.HashMap;
-import java.util.Map;
-
-import kotlinx.coroutines.Dispatchers;
-
-/**
- * Test implementation of the dependency injector.
- */
-public class TestCustomizationInjector extends TestInjector implements CustomizationInjector {
- private CustomizationPreferences mCustomizationPreferences;
- private ThemeManager mThemeManager;
- private PackageStatusNotifier mPackageStatusNotifier;
- private DrawableLayerResolver mDrawableLayerResolver;
- private UserEventLogger mUserEventLogger;
- private KeyguardQuickAffordancePickerInteractor mKeyguardQuickAffordancePickerInteractor;
- private BaseFlags mFlags;
- private CustomizationProviderClient mCustomizationProviderClient;
- private KeyguardQuickAffordanceSnapshotRestorer mKeyguardQuickAffordanceSnapshotRestorer;
-
- @Override
- public CustomizationPreferences getCustomizationPreferences(Context context) {
- if (mCustomizationPreferences == null) {
- mCustomizationPreferences = new TestDefaultCustomizationPreferences(context);
- }
- return mCustomizationPreferences;
- }
-
- @Override
- public ThemeManager getThemeManager(
- ThemeBundleProvider provider,
- FragmentActivity activity,
- OverlayManagerCompat overlayManagerCompat,
- ThemesUserEventLogger logger) {
- if (mThemeManager == null) {
- mThemeManager = new TestThemeManager(provider, activity, overlayManagerCompat, logger);
- }
- return mThemeManager;
- }
-
- @Override
- public PackageStatusNotifier getPackageStatusNotifier(Context context) {
- if (mPackageStatusNotifier == null) {
- mPackageStatusNotifier = new TestPackageStatusNotifier();
- }
- return mPackageStatusNotifier;
- }
-
- @Override
- public DrawableLayerResolver getDrawableLayerResolver() {
- if (mDrawableLayerResolver == null) {
- mDrawableLayerResolver = new TestDrawableLayerResolver();
- }
- return mDrawableLayerResolver;
- }
-
- @Override
- public UserEventLogger getUserEventLogger(Context unused) {
- if (mUserEventLogger == null) {
- mUserEventLogger = new TestThemesUserEventLogger();
- }
- return mUserEventLogger;
- }
-
- @Override
- public KeyguardQuickAffordancePickerInteractor getKeyguardQuickAffordancePickerInteractor(
- Context context) {
- if (mKeyguardQuickAffordancePickerInteractor == null) {
- final CustomizationProviderClient client =
- new CustomizationProviderClientImpl(context, Dispatchers.getIO());
- mKeyguardQuickAffordancePickerInteractor = new KeyguardQuickAffordancePickerInteractor(
- new KeyguardQuickAffordancePickerRepository(client, Dispatchers.getIO()),
- client,
- () -> getKeyguardQuickAffordanceSnapshotRestorer(context));
- }
- return mKeyguardQuickAffordancePickerInteractor;
- }
-
- @Override
- public BaseFlags getFlags() {
- if (mFlags == null) {
- mFlags = new BaseFlags() {};
- }
-
- return mFlags;
- }
-
- @Override
- public Map<Integer, SnapshotRestorer> getSnapshotRestorers(Context context) {
- final Map<Integer, SnapshotRestorer> restorers = new HashMap<>();
- restorers.put(
- KEY_QUICK_AFFORDANCE_SNAPSHOT_RESTORER,
- getKeyguardQuickAffordanceSnapshotRestorer(context));
- return restorers;
- }
-
- /** Returns the {@link CustomizationProviderClient}. */
- private CustomizationProviderClient getKeyguardQuickAffordancePickerProviderClient(
- Context context) {
- if (mCustomizationProviderClient == null) {
- mCustomizationProviderClient =
- new CustomizationProviderClientImpl(context, Dispatchers.getIO());
- }
-
- return mCustomizationProviderClient;
- }
-
- private KeyguardQuickAffordanceSnapshotRestorer getKeyguardQuickAffordanceSnapshotRestorer(
- Context context) {
- if (mKeyguardQuickAffordanceSnapshotRestorer == null) {
- mKeyguardQuickAffordanceSnapshotRestorer = new KeyguardQuickAffordanceSnapshotRestorer(
- getKeyguardQuickAffordancePickerInteractor(context),
- getKeyguardQuickAffordancePickerProviderClient(context));
- }
-
- return mKeyguardQuickAffordanceSnapshotRestorer;
- }
-
- private static final int KEY_QUICK_AFFORDANCE_SNAPSHOT_RESTORER = 1;
-}
diff --git a/tests/src/com/android/customization/testing/TestCustomizationInjector.kt b/tests/src/com/android/customization/testing/TestCustomizationInjector.kt
new file mode 100644
index 0000000..b49e654
--- /dev/null
+++ b/tests/src/com/android/customization/testing/TestCustomizationInjector.kt
@@ -0,0 +1,289 @@
+package com.android.customization.testing
+
+import android.app.Activity
+import android.content.Context
+import android.text.TextUtils
+import androidx.fragment.app.FragmentActivity
+import com.android.customization.model.color.ColorCustomizationManager
+import com.android.customization.model.color.ColorOptionsProvider
+import com.android.customization.model.theme.OverlayManagerCompat
+import com.android.customization.model.theme.ThemeBundleProvider
+import com.android.customization.model.theme.ThemeManager
+import com.android.customization.module.CustomizationInjector
+import com.android.customization.module.CustomizationPreferences
+import com.android.customization.module.ThemesUserEventLogger
+import com.android.customization.picker.clock.data.repository.ClockRegistryProvider
+import com.android.customization.picker.clock.data.repository.FakeClockPickerRepository
+import com.android.customization.picker.clock.domain.interactor.ClockPickerInteractor
+import com.android.customization.picker.clock.ui.view.ClockViewFactory
+import com.android.customization.picker.clock.ui.viewmodel.ClockCarouselViewModel
+import com.android.customization.picker.clock.ui.viewmodel.ClockSectionViewModel
+import com.android.customization.picker.clock.ui.viewmodel.ClockSettingsViewModel
+import com.android.customization.picker.color.data.repository.ColorPickerRepository
+import com.android.customization.picker.color.data.repository.ColorPickerRepositoryImpl
+import com.android.customization.picker.color.domain.interactor.ColorPickerInteractor
+import com.android.customization.picker.color.domain.interactor.ColorPickerSnapshotRestorer
+import com.android.customization.picker.color.ui.viewmodel.ColorPickerViewModel
+import com.android.customization.picker.quickaffordance.data.repository.KeyguardQuickAffordancePickerRepository
+import com.android.customization.picker.quickaffordance.domain.interactor.KeyguardQuickAffordancePickerInteractor
+import com.android.customization.picker.quickaffordance.domain.interactor.KeyguardQuickAffordanceSnapshotRestorer
+import com.android.systemui.shared.clocks.ClockRegistry
+import com.android.systemui.shared.customization.data.content.CustomizationProviderClient
+import com.android.systemui.shared.customization.data.content.CustomizationProviderClientImpl
+import com.android.wallpaper.config.BaseFlags
+import com.android.wallpaper.model.WallpaperColorsViewModel
+import com.android.wallpaper.module.DrawableLayerResolver
+import com.android.wallpaper.module.PackageStatusNotifier
+import com.android.wallpaper.module.UserEventLogger
+import com.android.wallpaper.picker.customization.data.content.WallpaperClientImpl
+import com.android.wallpaper.picker.customization.data.repository.WallpaperRepository
+import com.android.wallpaper.picker.customization.domain.interactor.WallpaperInteractor
+import com.android.wallpaper.picker.undo.domain.interactor.SnapshotRestorer
+import com.android.wallpaper.testing.TestInjector
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.GlobalScope
+
+/** Test implementation of the dependency injector. */
+class TestCustomizationInjector : TestInjector(), CustomizationInjector {
+ private var customizationPreferences: CustomizationPreferences? = null
+ private var themeManager: ThemeManager? = null
+ private var packageStatusNotifier: PackageStatusNotifier? = null
+ private var drawableLayerResolver: DrawableLayerResolver? = null
+ private var userEventLogger: UserEventLogger? = null
+ private var wallpaperInteractor: WallpaperInteractor? = null
+ private var keyguardQuickAffordancePickerInteractor: KeyguardQuickAffordancePickerInteractor? =
+ null
+ private var flags: BaseFlags? = null
+ private var customizationProviderClient: CustomizationProviderClient? = null
+ private var keyguardQuickAffordanceSnapshotRestorer: KeyguardQuickAffordanceSnapshotRestorer? =
+ null
+ private var clockRegistry: ClockRegistry? = null
+ private var clockPickerInteractor: ClockPickerInteractor? = null
+ private var clockSectionViewModel: ClockSectionViewModel? = null
+ private var clockViewFactory: ClockViewFactory? = null
+ private var colorPickerRepository: ColorPickerRepository? = null
+ private var colorPickerInteractor: ColorPickerInteractor? = null
+ private var colorPickerViewModelFactory: ColorPickerViewModel.Factory? = null
+ private var colorPickerSnapshotRestorer: ColorPickerSnapshotRestorer? = null
+ private var colorCustomizationManager: ColorCustomizationManager? = null
+ private var clockCarouselViewModel: ClockCarouselViewModel? = null
+ private var clockSettingsViewModelFactory: ClockSettingsViewModel.Factory? = null
+
+ override fun getCustomizationPreferences(context: Context): CustomizationPreferences {
+ return customizationPreferences
+ ?: TestDefaultCustomizationPreferences(context).also { customizationPreferences = it }
+ }
+
+ override fun getThemeManager(
+ provider: ThemeBundleProvider,
+ activity: FragmentActivity,
+ overlayManagerCompat: OverlayManagerCompat,
+ logger: ThemesUserEventLogger
+ ): ThemeManager {
+ return themeManager
+ ?: TestThemeManager(provider, activity, overlayManagerCompat, logger).also {
+ themeManager = it
+ }
+ }
+
+ override fun getPackageStatusNotifier(context: Context): PackageStatusNotifier {
+ return packageStatusNotifier
+ ?: TestPackageStatusNotifier().also {
+ packageStatusNotifier = TestPackageStatusNotifier()
+ }
+ }
+
+ override fun getDrawableLayerResolver(): DrawableLayerResolver {
+ return drawableLayerResolver
+ ?: TestDrawableLayerResolver().also { drawableLayerResolver = it }
+ }
+
+ override fun getUserEventLogger(context: Context): UserEventLogger {
+ return userEventLogger ?: TestThemesUserEventLogger().also { userEventLogger = it }
+ }
+
+ override fun getWallpaperInteractor(context: Context): WallpaperInteractor {
+ return wallpaperInteractor
+ ?: WallpaperInteractor(
+ repository =
+ WallpaperRepository(
+ scope = GlobalScope,
+ client = WallpaperClientImpl(context = context),
+ backgroundDispatcher = Dispatchers.IO,
+ ),
+ shouldHandleReload = {
+ TextUtils.equals(
+ getColorCustomizationManager(context).currentColorSource,
+ ColorOptionsProvider.COLOR_SOURCE_PRESET
+ )
+ }
+ )
+ .also { wallpaperInteractor = it }
+ }
+
+ override fun getKeyguardQuickAffordancePickerInteractor(
+ context: Context
+ ): KeyguardQuickAffordancePickerInteractor {
+ return keyguardQuickAffordancePickerInteractor
+ ?: createCustomizationProviderClient(context).also {
+ keyguardQuickAffordancePickerInteractor = it
+ }
+ }
+
+ private fun createCustomizationProviderClient(
+ context: Context
+ ): KeyguardQuickAffordancePickerInteractor {
+ val client: CustomizationProviderClient =
+ CustomizationProviderClientImpl(context, Dispatchers.IO)
+ return KeyguardQuickAffordancePickerInteractor(
+ KeyguardQuickAffordancePickerRepository(client, Dispatchers.IO),
+ client
+ ) {
+ getKeyguardQuickAffordanceSnapshotRestorer(context)
+ }
+ }
+
+ override fun getFlags(): BaseFlags {
+ return flags ?: object : BaseFlags() {}.also { flags = it }
+ }
+
+ override fun getSnapshotRestorers(context: Context): Map<Int, SnapshotRestorer> {
+ val restorers: MutableMap<Int, SnapshotRestorer> = HashMap()
+ restorers[KEY_QUICK_AFFORDANCE_SNAPSHOT_RESTORER] =
+ getKeyguardQuickAffordanceSnapshotRestorer(context)
+ restorers[KEY_COLOR_PICKER_SNAPSHOT_RESTORER] =
+ getColorPickerSnapshotRestorer(context, getWallpaperColorsViewModel())
+ return restorers
+ }
+
+ /** Returns the [CustomizationProviderClient]. */
+ private fun getKeyguardQuickAffordancePickerProviderClient(
+ context: Context
+ ): CustomizationProviderClient {
+ return customizationProviderClient
+ ?: CustomizationProviderClientImpl(context, Dispatchers.IO).also {
+ customizationProviderClient = it
+ }
+ }
+
+ private fun getKeyguardQuickAffordanceSnapshotRestorer(
+ context: Context
+ ): KeyguardQuickAffordanceSnapshotRestorer {
+ return keyguardQuickAffordanceSnapshotRestorer
+ ?: KeyguardQuickAffordanceSnapshotRestorer(
+ getKeyguardQuickAffordancePickerInteractor(context),
+ getKeyguardQuickAffordancePickerProviderClient(context)
+ )
+ .also { keyguardQuickAffordanceSnapshotRestorer = it }
+ }
+
+ override fun getClockRegistry(context: Context): ClockRegistry {
+ return clockRegistry
+ ?: ClockRegistryProvider(context, GlobalScope, Dispatchers.Main, Dispatchers.IO)
+ .get()
+ .also { clockRegistry = it }
+ }
+
+ override fun getClockPickerInteractor(context: Context): ClockPickerInteractor {
+ return clockPickerInteractor
+ ?: ClockPickerInteractor(FakeClockPickerRepository()).also {
+ clockPickerInteractor = it
+ }
+ }
+
+ override fun getClockSectionViewModel(context: Context): ClockSectionViewModel {
+ return clockSectionViewModel
+ ?: ClockSectionViewModel(context, getClockPickerInteractor(context)).also {
+ clockSectionViewModel = it
+ }
+ }
+
+ private fun getColorPickerRepository(
+ context: Context,
+ wallpaperColorsViewModel: WallpaperColorsViewModel,
+ ): ColorPickerRepository {
+ return colorPickerRepository
+ ?: ColorPickerRepositoryImpl(
+ wallpaperColorsViewModel,
+ getColorCustomizationManager(context)
+ )
+ }
+
+ override fun getColorPickerInteractor(
+ context: Context,
+ wallpaperColorsViewModel: WallpaperColorsViewModel,
+ ): ColorPickerInteractor {
+ return colorPickerInteractor
+ ?: ColorPickerInteractor(
+ repository = getColorPickerRepository(context, wallpaperColorsViewModel),
+ snapshotRestorer = {
+ getColorPickerSnapshotRestorer(context, wallpaperColorsViewModel)
+ },
+ )
+ .also { colorPickerInteractor = it }
+ }
+
+ override fun getColorPickerViewModelFactory(
+ context: Context,
+ wallpaperColorsViewModel: WallpaperColorsViewModel,
+ ): ColorPickerViewModel.Factory {
+ return colorPickerViewModelFactory
+ ?: ColorPickerViewModel.Factory(
+ context,
+ getColorPickerInteractor(context, wallpaperColorsViewModel),
+ )
+ .also { colorPickerViewModelFactory = it }
+ }
+
+ private fun getColorPickerSnapshotRestorer(
+ context: Context,
+ wallpaperColorsViewModel: WallpaperColorsViewModel
+ ): ColorPickerSnapshotRestorer {
+ return colorPickerSnapshotRestorer
+ ?: ColorPickerSnapshotRestorer(
+ getColorPickerInteractor(context, wallpaperColorsViewModel)
+ )
+ .also { colorPickerSnapshotRestorer = it }
+ }
+
+ private fun getColorCustomizationManager(context: Context): ColorCustomizationManager {
+ return colorCustomizationManager
+ ?: ColorCustomizationManager.getInstance(context, OverlayManagerCompat(context)).also {
+ colorCustomizationManager = it
+ }
+ }
+
+ override fun getClockCarouselViewModel(context: Context): ClockCarouselViewModel {
+ return clockCarouselViewModel
+ ?: ClockCarouselViewModel(getClockPickerInteractor(context)).also {
+ clockCarouselViewModel = it
+ }
+ }
+
+ override fun getClockViewFactory(activity: Activity): ClockViewFactory {
+ return clockViewFactory
+ ?: ClockViewFactory(activity, getClockRegistry(activity)).also { clockViewFactory = it }
+ }
+
+ override fun getClockSettingsViewModelFactory(
+ context: Context,
+ wallpaperColorsViewModel: WallpaperColorsViewModel,
+ ): ClockSettingsViewModel.Factory {
+ return clockSettingsViewModelFactory
+ ?: ClockSettingsViewModel.Factory(
+ context,
+ getClockPickerInteractor(context),
+ getColorPickerInteractor(
+ context,
+ wallpaperColorsViewModel,
+ ),
+ )
+ .also { clockSettingsViewModelFactory = it }
+ }
+
+ companion object {
+ private const val KEY_QUICK_AFFORDANCE_SNAPSHOT_RESTORER = 1
+ private const val KEY_COLOR_PICKER_SNAPSHOT_RESTORER =
+ KEY_QUICK_AFFORDANCE_SNAPSHOT_RESTORER + 1
+ }
+}
diff --git a/tests/src/com/android/customization/testing/TestPluginManager.kt b/tests/src/com/android/customization/testing/TestPluginManager.kt
new file mode 100644
index 0000000..167d8dd
--- /dev/null
+++ b/tests/src/com/android/customization/testing/TestPluginManager.kt
@@ -0,0 +1,36 @@
+package com.android.customization.testing
+
+import com.android.systemui.plugins.Plugin
+import com.android.systemui.plugins.PluginListener
+import com.android.systemui.plugins.PluginManager
+
+class TestPluginManager : PluginManager {
+ override fun getPrivilegedPlugins(): Array<String> {
+ return emptyArray()
+ }
+
+ override fun <T : Plugin?> addPluginListener(listener: PluginListener<T>, cls: Class<T>) {}
+ override fun <T : Plugin?> addPluginListener(
+ listener: PluginListener<T>,
+ cls: Class<T>,
+ allowMultiple: Boolean
+ ) {}
+
+ override fun <T : Plugin?> addPluginListener(
+ action: String,
+ listener: PluginListener<T>,
+ cls: Class<T>
+ ) {}
+
+ override fun <T : Plugin?> addPluginListener(
+ action: String,
+ listener: PluginListener<T>,
+ cls: Class<T>,
+ allowMultiple: Boolean
+ ) {}
+
+ override fun removePluginListener(listener: PluginListener<*>?) {}
+ override fun <T> dependsOn(p: Plugin, cls: Class<T>): Boolean {
+ return false
+ }
+}
diff --git a/themes/res/values-af/strings.xml b/themes/res/values-af/strings.xml
deleted file mode 100644
index a0da3f8..0000000
--- a/themes/res/values-af/strings.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (C) 2022 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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="rainbow_color_name_red" msgid="7452506008058561006">"Rooi"</string>
- <string name="rainbow_color_name_orange" msgid="2921298510262609543">"Oranje"</string>
- <string name="rainbow_color_name_yellow" msgid="8675574652757989201">"Geel"</string>
- <string name="rainbow_color_name_green" msgid="1932895389710184112">"Groen"</string>
- <string name="rainbow_color_name_blue" msgid="3473176664458856892">"Blou"</string>
- <string name="rainbow_color_name_purple" msgid="2704722524588084868">"Pers"</string>
- <string name="rainbow_color_name_magenta" msgid="7248703626077785569">"Magenta"</string>
- <string name="monochromatic_name" msgid="2554823570460886176">"Monochromaties"</string>
-</resources>
diff --git a/themes/res/values-am/strings.xml b/themes/res/values-am/strings.xml
deleted file mode 100644
index c5d0492..0000000
--- a/themes/res/values-am/strings.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (C) 2022 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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="rainbow_color_name_red" msgid="7452506008058561006">"ቀይ"</string>
- <string name="rainbow_color_name_orange" msgid="2921298510262609543">"ብርቱካናማ"</string>
- <string name="rainbow_color_name_yellow" msgid="8675574652757989201">"ቢጫ"</string>
- <string name="rainbow_color_name_green" msgid="1932895389710184112">"አረንጓዴ"</string>
- <string name="rainbow_color_name_blue" msgid="3473176664458856892">"ሰማያዊ"</string>
- <string name="rainbow_color_name_purple" msgid="2704722524588084868">"ሐምራዊ"</string>
- <string name="rainbow_color_name_magenta" msgid="7248703626077785569">"ማጀንታ"</string>
- <string name="monochromatic_name" msgid="2554823570460886176">"ሞኖክሮማቲክ"</string>
-</resources>
diff --git a/themes/res/values-ar/strings.xml b/themes/res/values-ar/strings.xml
deleted file mode 100644
index 89ef13e..0000000
--- a/themes/res/values-ar/strings.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (C) 2022 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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="rainbow_color_name_red" msgid="7452506008058561006">"أحمر"</string>
- <string name="rainbow_color_name_orange" msgid="2921298510262609543">"برتقالي"</string>
- <string name="rainbow_color_name_yellow" msgid="8675574652757989201">"أصفر"</string>
- <string name="rainbow_color_name_green" msgid="1932895389710184112">"أخضر"</string>
- <string name="rainbow_color_name_blue" msgid="3473176664458856892">"أزرق"</string>
- <string name="rainbow_color_name_purple" msgid="2704722524588084868">"بنفسجي"</string>
- <string name="rainbow_color_name_magenta" msgid="7248703626077785569">"أرجواني"</string>
- <string name="monochromatic_name" msgid="2554823570460886176">"أحادي اللون"</string>
-</resources>
diff --git a/themes/res/values-as/strings.xml b/themes/res/values-as/strings.xml
deleted file mode 100644
index a42cbca..0000000
--- a/themes/res/values-as/strings.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (C) 2022 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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="rainbow_color_name_red" msgid="7452506008058561006">"ৰঙা"</string>
- <string name="rainbow_color_name_orange" msgid="2921298510262609543">"কমলা"</string>
- <string name="rainbow_color_name_yellow" msgid="8675574652757989201">"হালধীয়া"</string>
- <string name="rainbow_color_name_green" msgid="1932895389710184112">"সেউজীয়া"</string>
- <string name="rainbow_color_name_blue" msgid="3473176664458856892">"নীলা"</string>
- <string name="rainbow_color_name_purple" msgid="2704722524588084868">"বেঙুনীয়া"</string>
- <string name="rainbow_color_name_magenta" msgid="7248703626077785569">"মেজেণ্টা"</string>
- <string name="monochromatic_name" msgid="2554823570460886176">"মন’ক্ৰ’মেটিক"</string>
-</resources>
diff --git a/themes/res/values-az/strings.xml b/themes/res/values-az/strings.xml
deleted file mode 100644
index 37719fe..0000000
--- a/themes/res/values-az/strings.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (C) 2022 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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="rainbow_color_name_red" msgid="7452506008058561006">"Qırmızı"</string>
- <string name="rainbow_color_name_orange" msgid="2921298510262609543">"Narıncı"</string>
- <string name="rainbow_color_name_yellow" msgid="8675574652757989201">"Sarı"</string>
- <string name="rainbow_color_name_green" msgid="1932895389710184112">"Yaşıl"</string>
- <string name="rainbow_color_name_blue" msgid="3473176664458856892">"Göy"</string>
- <string name="rainbow_color_name_purple" msgid="2704722524588084868">"Mor"</string>
- <string name="rainbow_color_name_magenta" msgid="7248703626077785569">"Çəhrayı qırmızı"</string>
- <string name="monochromatic_name" msgid="2554823570460886176">"Monoxromatik"</string>
-</resources>
diff --git a/themes/res/values-b+sr+Latn/strings.xml b/themes/res/values-b+sr+Latn/strings.xml
deleted file mode 100644
index 0497600..0000000
--- a/themes/res/values-b+sr+Latn/strings.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (C) 2022 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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="rainbow_color_name_red" msgid="7452506008058561006">"Crvena"</string>
- <string name="rainbow_color_name_orange" msgid="2921298510262609543">"Narandžasta"</string>
- <string name="rainbow_color_name_yellow" msgid="8675574652757989201">"Žuta"</string>
- <string name="rainbow_color_name_green" msgid="1932895389710184112">"Zelena"</string>
- <string name="rainbow_color_name_blue" msgid="3473176664458856892">"Plava"</string>
- <string name="rainbow_color_name_purple" msgid="2704722524588084868">"Ljubičasta"</string>
- <string name="rainbow_color_name_magenta" msgid="7248703626077785569">"Magenta"</string>
- <string name="monochromatic_name" msgid="2554823570460886176">"Monohromatsko"</string>
-</resources>
diff --git a/themes/res/values-be/strings.xml b/themes/res/values-be/strings.xml
deleted file mode 100644
index b9e2dc5..0000000
--- a/themes/res/values-be/strings.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (C) 2022 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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="rainbow_color_name_red" msgid="7452506008058561006">"Чырвоны"</string>
- <string name="rainbow_color_name_orange" msgid="2921298510262609543">"Аранжавы"</string>
- <string name="rainbow_color_name_yellow" msgid="8675574652757989201">"Жоўты"</string>
- <string name="rainbow_color_name_green" msgid="1932895389710184112">"Зялёны"</string>
- <string name="rainbow_color_name_blue" msgid="3473176664458856892">"Сіні"</string>
- <string name="rainbow_color_name_purple" msgid="2704722524588084868">"Фіялетавы"</string>
- <string name="rainbow_color_name_magenta" msgid="7248703626077785569">"Пурпурны"</string>
- <string name="monochromatic_name" msgid="2554823570460886176">"Манахромная"</string>
-</resources>
diff --git a/themes/res/values-bg/strings.xml b/themes/res/values-bg/strings.xml
deleted file mode 100644
index 99e1b0d..0000000
--- a/themes/res/values-bg/strings.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (C) 2022 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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="rainbow_color_name_red" msgid="7452506008058561006">"Червено"</string>
- <string name="rainbow_color_name_orange" msgid="2921298510262609543">"Оранжево"</string>
- <string name="rainbow_color_name_yellow" msgid="8675574652757989201">"Жълто"</string>
- <string name="rainbow_color_name_green" msgid="1932895389710184112">"Зелено"</string>
- <string name="rainbow_color_name_blue" msgid="3473176664458856892">"Синьо"</string>
- <string name="rainbow_color_name_purple" msgid="2704722524588084868">"Лилаво"</string>
- <string name="rainbow_color_name_magenta" msgid="7248703626077785569">"Пурпурно"</string>
- <string name="monochromatic_name" msgid="2554823570460886176">"Монохроматично"</string>
-</resources>
diff --git a/themes/res/values-bn/strings.xml b/themes/res/values-bn/strings.xml
deleted file mode 100644
index 8a90e02..0000000
--- a/themes/res/values-bn/strings.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (C) 2022 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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="rainbow_color_name_red" msgid="7452506008058561006">"লাল"</string>
- <string name="rainbow_color_name_orange" msgid="2921298510262609543">"কমলা"</string>
- <string name="rainbow_color_name_yellow" msgid="8675574652757989201">"হলুদ"</string>
- <string name="rainbow_color_name_green" msgid="1932895389710184112">"সবুজ"</string>
- <string name="rainbow_color_name_blue" msgid="3473176664458856892">"নীল"</string>
- <string name="rainbow_color_name_purple" msgid="2704722524588084868">"বেগুনি"</string>
- <string name="rainbow_color_name_magenta" msgid="7248703626077785569">"ম্যাজেন্টা"</string>
- <string name="monochromatic_name" msgid="2554823570460886176">"মোনোক্রোম্যাটিক"</string>
-</resources>
diff --git a/themes/res/values-bs/strings.xml b/themes/res/values-bs/strings.xml
deleted file mode 100644
index 1f9990a..0000000
--- a/themes/res/values-bs/strings.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (C) 2022 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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="rainbow_color_name_red" msgid="7452506008058561006">"Crvena"</string>
- <string name="rainbow_color_name_orange" msgid="2921298510262609543">"Narandžasta"</string>
- <string name="rainbow_color_name_yellow" msgid="8675574652757989201">"Žuta"</string>
- <string name="rainbow_color_name_green" msgid="1932895389710184112">"Zelena"</string>
- <string name="rainbow_color_name_blue" msgid="3473176664458856892">"Plava"</string>
- <string name="rainbow_color_name_purple" msgid="2704722524588084868">"Ljubičasta"</string>
- <string name="rainbow_color_name_magenta" msgid="7248703626077785569">"Magenta"</string>
- <string name="monochromatic_name" msgid="2554823570460886176">"Monohromatski"</string>
-</resources>
diff --git a/themes/res/values-ca/strings.xml b/themes/res/values-ca/strings.xml
deleted file mode 100644
index 55c487e..0000000
--- a/themes/res/values-ca/strings.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (C) 2022 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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="rainbow_color_name_red" msgid="7452506008058561006">"Vermell"</string>
- <string name="rainbow_color_name_orange" msgid="2921298510262609543">"Taronja"</string>
- <string name="rainbow_color_name_yellow" msgid="8675574652757989201">"Groc"</string>
- <string name="rainbow_color_name_green" msgid="1932895389710184112">"Verd"</string>
- <string name="rainbow_color_name_blue" msgid="3473176664458856892">"Blau"</string>
- <string name="rainbow_color_name_purple" msgid="2704722524588084868">"Lila"</string>
- <string name="rainbow_color_name_magenta" msgid="7248703626077785569">"Magenta"</string>
- <string name="monochromatic_name" msgid="2554823570460886176">"Monocromàtic"</string>
-</resources>
diff --git a/themes/res/values-cs/strings.xml b/themes/res/values-cs/strings.xml
deleted file mode 100644
index b58134e..0000000
--- a/themes/res/values-cs/strings.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (C) 2022 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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="rainbow_color_name_red" msgid="7452506008058561006">"Červená"</string>
- <string name="rainbow_color_name_orange" msgid="2921298510262609543">"Oranžová"</string>
- <string name="rainbow_color_name_yellow" msgid="8675574652757989201">"Žlutá"</string>
- <string name="rainbow_color_name_green" msgid="1932895389710184112">"Zelená"</string>
- <string name="rainbow_color_name_blue" msgid="3473176664458856892">"Modrá"</string>
- <string name="rainbow_color_name_purple" msgid="2704722524588084868">"Nachová"</string>
- <string name="rainbow_color_name_magenta" msgid="7248703626077785569">"Purpurová"</string>
- <string name="monochromatic_name" msgid="2554823570460886176">"Monochromatické"</string>
-</resources>
diff --git a/themes/res/values-da/strings.xml b/themes/res/values-da/strings.xml
deleted file mode 100644
index ae6595a..0000000
--- a/themes/res/values-da/strings.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (C) 2022 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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="rainbow_color_name_red" msgid="7452506008058561006">"Rød"</string>
- <string name="rainbow_color_name_orange" msgid="2921298510262609543">"Orange"</string>
- <string name="rainbow_color_name_yellow" msgid="8675574652757989201">"Gul"</string>
- <string name="rainbow_color_name_green" msgid="1932895389710184112">"Grøn"</string>
- <string name="rainbow_color_name_blue" msgid="3473176664458856892">"Blå"</string>
- <string name="rainbow_color_name_purple" msgid="2704722524588084868">"Lilla"</string>
- <string name="rainbow_color_name_magenta" msgid="7248703626077785569">"Magenta"</string>
- <string name="monochromatic_name" msgid="2554823570460886176">"Monokrom"</string>
-</resources>
diff --git a/themes/res/values-de/strings.xml b/themes/res/values-de/strings.xml
deleted file mode 100644
index c941c1e..0000000
--- a/themes/res/values-de/strings.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (C) 2022 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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="rainbow_color_name_red" msgid="7452506008058561006">"Rot"</string>
- <string name="rainbow_color_name_orange" msgid="2921298510262609543">"Orange"</string>
- <string name="rainbow_color_name_yellow" msgid="8675574652757989201">"Gelb"</string>
- <string name="rainbow_color_name_green" msgid="1932895389710184112">"Grün"</string>
- <string name="rainbow_color_name_blue" msgid="3473176664458856892">"Blau"</string>
- <string name="rainbow_color_name_purple" msgid="2704722524588084868">"Lila"</string>
- <string name="rainbow_color_name_magenta" msgid="7248703626077785569">"Magenta"</string>
- <string name="monochromatic_name" msgid="2554823570460886176">"Einfarbig"</string>
-</resources>
diff --git a/themes/res/values-el/strings.xml b/themes/res/values-el/strings.xml
deleted file mode 100644
index 4b62b5d..0000000
--- a/themes/res/values-el/strings.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (C) 2022 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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="rainbow_color_name_red" msgid="7452506008058561006">"Κόκκινο"</string>
- <string name="rainbow_color_name_orange" msgid="2921298510262609543">"Πορτοκαλί"</string>
- <string name="rainbow_color_name_yellow" msgid="8675574652757989201">"Κίτρινο"</string>
- <string name="rainbow_color_name_green" msgid="1932895389710184112">"Πράσινο"</string>
- <string name="rainbow_color_name_blue" msgid="3473176664458856892">"Μπλε"</string>
- <string name="rainbow_color_name_purple" msgid="2704722524588084868">"Μοβ"</string>
- <string name="rainbow_color_name_magenta" msgid="7248703626077785569">"Ματζέντα"</string>
- <string name="monochromatic_name" msgid="2554823570460886176">"Μονοχρωματικό"</string>
-</resources>
diff --git a/themes/res/values-en-rAU/strings.xml b/themes/res/values-en-rAU/strings.xml
deleted file mode 100644
index ae4e8c5..0000000
--- a/themes/res/values-en-rAU/strings.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (C) 2022 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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="rainbow_color_name_red" msgid="7452506008058561006">"Red"</string>
- <string name="rainbow_color_name_orange" msgid="2921298510262609543">"Orange"</string>
- <string name="rainbow_color_name_yellow" msgid="8675574652757989201">"Yellow"</string>
- <string name="rainbow_color_name_green" msgid="1932895389710184112">"Green"</string>
- <string name="rainbow_color_name_blue" msgid="3473176664458856892">"Blue"</string>
- <string name="rainbow_color_name_purple" msgid="2704722524588084868">"Purple"</string>
- <string name="rainbow_color_name_magenta" msgid="7248703626077785569">"Magenta"</string>
- <string name="monochromatic_name" msgid="2554823570460886176">"Monochromatic"</string>
-</resources>
diff --git a/themes/res/values-en-rCA/strings.xml b/themes/res/values-en-rCA/strings.xml
deleted file mode 100644
index 780a3c9..0000000
--- a/themes/res/values-en-rCA/strings.xml
+++ /dev/null
@@ -1,29 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (C) 2022 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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="rainbow_color_name_red" msgid="7452506008058561006">"Red"</string>
- <string name="rainbow_color_name_orange" msgid="2921298510262609543">"Orange"</string>
- <string name="rainbow_color_name_yellow" msgid="8675574652757989201">"Yellow"</string>
- <string name="rainbow_color_name_green" msgid="1932895389710184112">"Green"</string>
- <string name="rainbow_color_name_blue" msgid="3473176664458856892">"Blue"</string>
- <string name="rainbow_color_name_purple" msgid="2704722524588084868">"Purple"</string>
- <string name="rainbow_color_name_magenta" msgid="7248703626077785569">"Magenta"</string>
- <!-- no translation found for monochromatic_name (2554823570460886176) -->
- <skip />
-</resources>
diff --git a/themes/res/values-en-rGB/strings.xml b/themes/res/values-en-rGB/strings.xml
deleted file mode 100644
index ae4e8c5..0000000
--- a/themes/res/values-en-rGB/strings.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (C) 2022 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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="rainbow_color_name_red" msgid="7452506008058561006">"Red"</string>
- <string name="rainbow_color_name_orange" msgid="2921298510262609543">"Orange"</string>
- <string name="rainbow_color_name_yellow" msgid="8675574652757989201">"Yellow"</string>
- <string name="rainbow_color_name_green" msgid="1932895389710184112">"Green"</string>
- <string name="rainbow_color_name_blue" msgid="3473176664458856892">"Blue"</string>
- <string name="rainbow_color_name_purple" msgid="2704722524588084868">"Purple"</string>
- <string name="rainbow_color_name_magenta" msgid="7248703626077785569">"Magenta"</string>
- <string name="monochromatic_name" msgid="2554823570460886176">"Monochromatic"</string>
-</resources>
diff --git a/themes/res/values-en-rIN/strings.xml b/themes/res/values-en-rIN/strings.xml
deleted file mode 100644
index ae4e8c5..0000000
--- a/themes/res/values-en-rIN/strings.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (C) 2022 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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="rainbow_color_name_red" msgid="7452506008058561006">"Red"</string>
- <string name="rainbow_color_name_orange" msgid="2921298510262609543">"Orange"</string>
- <string name="rainbow_color_name_yellow" msgid="8675574652757989201">"Yellow"</string>
- <string name="rainbow_color_name_green" msgid="1932895389710184112">"Green"</string>
- <string name="rainbow_color_name_blue" msgid="3473176664458856892">"Blue"</string>
- <string name="rainbow_color_name_purple" msgid="2704722524588084868">"Purple"</string>
- <string name="rainbow_color_name_magenta" msgid="7248703626077785569">"Magenta"</string>
- <string name="monochromatic_name" msgid="2554823570460886176">"Monochromatic"</string>
-</resources>
diff --git a/themes/res/values-en-rXC/strings.xml b/themes/res/values-en-rXC/strings.xml
deleted file mode 100644
index 170b178..0000000
--- a/themes/res/values-en-rXC/strings.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (C) 2022 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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="rainbow_color_name_red" msgid="7452506008058561006">"Red"</string>
- <string name="rainbow_color_name_orange" msgid="2921298510262609543">"Orange"</string>
- <string name="rainbow_color_name_yellow" msgid="8675574652757989201">"Yellow"</string>
- <string name="rainbow_color_name_green" msgid="1932895389710184112">"Green"</string>
- <string name="rainbow_color_name_blue" msgid="3473176664458856892">"Blue"</string>
- <string name="rainbow_color_name_purple" msgid="2704722524588084868">"Purple"</string>
- <string name="rainbow_color_name_magenta" msgid="7248703626077785569">"Magenta"</string>
- <string name="monochromatic_name" msgid="2554823570460886176">"Monochromatic"</string>
-</resources>
diff --git a/themes/res/values-es-rUS/strings.xml b/themes/res/values-es-rUS/strings.xml
deleted file mode 100644
index 413e3f0..0000000
--- a/themes/res/values-es-rUS/strings.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (C) 2022 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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="rainbow_color_name_red" msgid="7452506008058561006">"Rojo"</string>
- <string name="rainbow_color_name_orange" msgid="2921298510262609543">"Naranja"</string>
- <string name="rainbow_color_name_yellow" msgid="8675574652757989201">"Amarillo"</string>
- <string name="rainbow_color_name_green" msgid="1932895389710184112">"Verde"</string>
- <string name="rainbow_color_name_blue" msgid="3473176664458856892">"Azul"</string>
- <string name="rainbow_color_name_purple" msgid="2704722524588084868">"Púrpura"</string>
- <string name="rainbow_color_name_magenta" msgid="7248703626077785569">"Magenta"</string>
- <string name="monochromatic_name" msgid="2554823570460886176">"Monocromático"</string>
-</resources>
diff --git a/themes/res/values-es/strings.xml b/themes/res/values-es/strings.xml
deleted file mode 100644
index 65b9081..0000000
--- a/themes/res/values-es/strings.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (C) 2022 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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="rainbow_color_name_red" msgid="7452506008058561006">"Rojo"</string>
- <string name="rainbow_color_name_orange" msgid="2921298510262609543">"Naranja"</string>
- <string name="rainbow_color_name_yellow" msgid="8675574652757989201">"Amarillo"</string>
- <string name="rainbow_color_name_green" msgid="1932895389710184112">"Verde"</string>
- <string name="rainbow_color_name_blue" msgid="3473176664458856892">"Azul"</string>
- <string name="rainbow_color_name_purple" msgid="2704722524588084868">"Morado"</string>
- <string name="rainbow_color_name_magenta" msgid="7248703626077785569">"Magenta"</string>
- <string name="monochromatic_name" msgid="2554823570460886176">"Monocromático"</string>
-</resources>
diff --git a/themes/res/values-et/strings.xml b/themes/res/values-et/strings.xml
deleted file mode 100644
index a4907c1..0000000
--- a/themes/res/values-et/strings.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (C) 2022 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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="rainbow_color_name_red" msgid="7452506008058561006">"Punane"</string>
- <string name="rainbow_color_name_orange" msgid="2921298510262609543">"Oranž"</string>
- <string name="rainbow_color_name_yellow" msgid="8675574652757989201">"Kollane"</string>
- <string name="rainbow_color_name_green" msgid="1932895389710184112">"Roheline"</string>
- <string name="rainbow_color_name_blue" msgid="3473176664458856892">"Sinine"</string>
- <string name="rainbow_color_name_purple" msgid="2704722524588084868">"Lilla"</string>
- <string name="rainbow_color_name_magenta" msgid="7248703626077785569">"Magenta"</string>
- <string name="monochromatic_name" msgid="2554823570460886176">"Monokromaatiline"</string>
-</resources>
diff --git a/themes/res/values-eu/strings.xml b/themes/res/values-eu/strings.xml
deleted file mode 100644
index 2525de7..0000000
--- a/themes/res/values-eu/strings.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (C) 2022 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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="rainbow_color_name_red" msgid="7452506008058561006">"Gorria"</string>
- <string name="rainbow_color_name_orange" msgid="2921298510262609543">"Laranja"</string>
- <string name="rainbow_color_name_yellow" msgid="8675574652757989201">"Horia"</string>
- <string name="rainbow_color_name_green" msgid="1932895389710184112">"Berdea"</string>
- <string name="rainbow_color_name_blue" msgid="3473176664458856892">"Urdina"</string>
- <string name="rainbow_color_name_purple" msgid="2704722524588084868">"Morea"</string>
- <string name="rainbow_color_name_magenta" msgid="7248703626077785569">"Magenta"</string>
- <string name="monochromatic_name" msgid="2554823570460886176">"Monokromatikoa"</string>
-</resources>
diff --git a/themes/res/values-fa/strings.xml b/themes/res/values-fa/strings.xml
deleted file mode 100644
index 3a03e5f..0000000
--- a/themes/res/values-fa/strings.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (C) 2022 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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="rainbow_color_name_red" msgid="7452506008058561006">"قرمز"</string>
- <string name="rainbow_color_name_orange" msgid="2921298510262609543">"نارنجی"</string>
- <string name="rainbow_color_name_yellow" msgid="8675574652757989201">"زرد"</string>
- <string name="rainbow_color_name_green" msgid="1932895389710184112">"سبز"</string>
- <string name="rainbow_color_name_blue" msgid="3473176664458856892">"آبی"</string>
- <string name="rainbow_color_name_purple" msgid="2704722524588084868">"بنفش"</string>
- <string name="rainbow_color_name_magenta" msgid="7248703626077785569">"سرخابی"</string>
- <string name="monochromatic_name" msgid="2554823570460886176">"تکرنگ"</string>
-</resources>
diff --git a/themes/res/values-fi/strings.xml b/themes/res/values-fi/strings.xml
deleted file mode 100644
index 9f24dec..0000000
--- a/themes/res/values-fi/strings.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (C) 2022 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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="rainbow_color_name_red" msgid="7452506008058561006">"Punainen"</string>
- <string name="rainbow_color_name_orange" msgid="2921298510262609543">"Oranssi"</string>
- <string name="rainbow_color_name_yellow" msgid="8675574652757989201">"Keltainen"</string>
- <string name="rainbow_color_name_green" msgid="1932895389710184112">"Vihreä"</string>
- <string name="rainbow_color_name_blue" msgid="3473176664458856892">"Sininen"</string>
- <string name="rainbow_color_name_purple" msgid="2704722524588084868">"Violetti"</string>
- <string name="rainbow_color_name_magenta" msgid="7248703626077785569">"Magenta"</string>
- <string name="monochromatic_name" msgid="2554823570460886176">"Yksivärinen"</string>
-</resources>
diff --git a/themes/res/values-fr-rCA/strings.xml b/themes/res/values-fr-rCA/strings.xml
deleted file mode 100644
index 5bb81e9..0000000
--- a/themes/res/values-fr-rCA/strings.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (C) 2022 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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="rainbow_color_name_red" msgid="7452506008058561006">"Rouge"</string>
- <string name="rainbow_color_name_orange" msgid="2921298510262609543">"Orange"</string>
- <string name="rainbow_color_name_yellow" msgid="8675574652757989201">"Jaune"</string>
- <string name="rainbow_color_name_green" msgid="1932895389710184112">"Vert"</string>
- <string name="rainbow_color_name_blue" msgid="3473176664458856892">"Bleu"</string>
- <string name="rainbow_color_name_purple" msgid="2704722524588084868">"Mauve"</string>
- <string name="rainbow_color_name_magenta" msgid="7248703626077785569">"Magenta"</string>
- <string name="monochromatic_name" msgid="2554823570460886176">"Monochromatique"</string>
-</resources>
diff --git a/themes/res/values-fr/strings.xml b/themes/res/values-fr/strings.xml
deleted file mode 100644
index 7942935..0000000
--- a/themes/res/values-fr/strings.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (C) 2022 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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="rainbow_color_name_red" msgid="7452506008058561006">"Rouge"</string>
- <string name="rainbow_color_name_orange" msgid="2921298510262609543">"Orange"</string>
- <string name="rainbow_color_name_yellow" msgid="8675574652757989201">"Jaune"</string>
- <string name="rainbow_color_name_green" msgid="1932895389710184112">"Vert"</string>
- <string name="rainbow_color_name_blue" msgid="3473176664458856892">"Bleu"</string>
- <string name="rainbow_color_name_purple" msgid="2704722524588084868">"Violet"</string>
- <string name="rainbow_color_name_magenta" msgid="7248703626077785569">"Magenta"</string>
- <string name="monochromatic_name" msgid="2554823570460886176">"Monochrome"</string>
-</resources>
diff --git a/themes/res/values-gl/strings.xml b/themes/res/values-gl/strings.xml
deleted file mode 100644
index 7317086..0000000
--- a/themes/res/values-gl/strings.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (C) 2022 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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="rainbow_color_name_red" msgid="7452506008058561006">"Vermello"</string>
- <string name="rainbow_color_name_orange" msgid="2921298510262609543">"Laranxa"</string>
- <string name="rainbow_color_name_yellow" msgid="8675574652757989201">"Amarelo"</string>
- <string name="rainbow_color_name_green" msgid="1932895389710184112">"Verde"</string>
- <string name="rainbow_color_name_blue" msgid="3473176664458856892">"Azul"</string>
- <string name="rainbow_color_name_purple" msgid="2704722524588084868">"Violeta"</string>
- <string name="rainbow_color_name_magenta" msgid="7248703626077785569">"Maxenta"</string>
- <string name="monochromatic_name" msgid="2554823570460886176">"Monocromático"</string>
-</resources>
diff --git a/themes/res/values-gu/strings.xml b/themes/res/values-gu/strings.xml
deleted file mode 100644
index b8c6c25..0000000
--- a/themes/res/values-gu/strings.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (C) 2022 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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="rainbow_color_name_red" msgid="7452506008058561006">"લાલ"</string>
- <string name="rainbow_color_name_orange" msgid="2921298510262609543">"નારંગી"</string>
- <string name="rainbow_color_name_yellow" msgid="8675574652757989201">"પીળો"</string>
- <string name="rainbow_color_name_green" msgid="1932895389710184112">"લીલો"</string>
- <string name="rainbow_color_name_blue" msgid="3473176664458856892">"વાદળી"</string>
- <string name="rainbow_color_name_purple" msgid="2704722524588084868">"જાંબલી"</string>
- <string name="rainbow_color_name_magenta" msgid="7248703626077785569">"મજેન્ટા"</string>
- <string name="monochromatic_name" msgid="2554823570460886176">"મોનોક્રોમૅટિક"</string>
-</resources>
diff --git a/themes/res/values-hi/strings.xml b/themes/res/values-hi/strings.xml
deleted file mode 100644
index f2e122b..0000000
--- a/themes/res/values-hi/strings.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (C) 2022 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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="rainbow_color_name_red" msgid="7452506008058561006">"लाल"</string>
- <string name="rainbow_color_name_orange" msgid="2921298510262609543">"नारंगी"</string>
- <string name="rainbow_color_name_yellow" msgid="8675574652757989201">"पीला"</string>
- <string name="rainbow_color_name_green" msgid="1932895389710184112">"हरा"</string>
- <string name="rainbow_color_name_blue" msgid="3473176664458856892">"नीला"</string>
- <string name="rainbow_color_name_purple" msgid="2704722524588084868">"बैंगनी"</string>
- <string name="rainbow_color_name_magenta" msgid="7248703626077785569">"मजेंटा"</string>
- <string name="monochromatic_name" msgid="2554823570460886176">"मोनोक्रोमैटिक"</string>
-</resources>
diff --git a/themes/res/values-hr/strings.xml b/themes/res/values-hr/strings.xml
deleted file mode 100644
index 6d8b772..0000000
--- a/themes/res/values-hr/strings.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (C) 2022 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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="rainbow_color_name_red" msgid="7452506008058561006">"Crvena"</string>
- <string name="rainbow_color_name_orange" msgid="2921298510262609543">"Narančasta"</string>
- <string name="rainbow_color_name_yellow" msgid="8675574652757989201">"Žuta"</string>
- <string name="rainbow_color_name_green" msgid="1932895389710184112">"Zelena"</string>
- <string name="rainbow_color_name_blue" msgid="3473176664458856892">"Plava"</string>
- <string name="rainbow_color_name_purple" msgid="2704722524588084868">"Ljubičasta"</string>
- <string name="rainbow_color_name_magenta" msgid="7248703626077785569">"Grimizna"</string>
- <string name="monochromatic_name" msgid="2554823570460886176">"Monokromatsko"</string>
-</resources>
diff --git a/themes/res/values-hu/strings.xml b/themes/res/values-hu/strings.xml
deleted file mode 100644
index d830cd3..0000000
--- a/themes/res/values-hu/strings.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (C) 2022 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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="rainbow_color_name_red" msgid="7452506008058561006">"Piros"</string>
- <string name="rainbow_color_name_orange" msgid="2921298510262609543">"Narancssárga"</string>
- <string name="rainbow_color_name_yellow" msgid="8675574652757989201">"Sárga"</string>
- <string name="rainbow_color_name_green" msgid="1932895389710184112">"Zöld"</string>
- <string name="rainbow_color_name_blue" msgid="3473176664458856892">"Kék"</string>
- <string name="rainbow_color_name_purple" msgid="2704722524588084868">"Lila"</string>
- <string name="rainbow_color_name_magenta" msgid="7248703626077785569">"Magenta"</string>
- <string name="monochromatic_name" msgid="2554823570460886176">"Egyszínű"</string>
-</resources>
diff --git a/themes/res/values-hy/strings.xml b/themes/res/values-hy/strings.xml
deleted file mode 100644
index 1b7a791..0000000
--- a/themes/res/values-hy/strings.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (C) 2022 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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="rainbow_color_name_red" msgid="7452506008058561006">"Կարմիր"</string>
- <string name="rainbow_color_name_orange" msgid="2921298510262609543">"Նարնջագույն"</string>
- <string name="rainbow_color_name_yellow" msgid="8675574652757989201">"Դեղին"</string>
- <string name="rainbow_color_name_green" msgid="1932895389710184112">"Կանաչ"</string>
- <string name="rainbow_color_name_blue" msgid="3473176664458856892">"Կապույտ"</string>
- <string name="rainbow_color_name_purple" msgid="2704722524588084868">"Մանուշակագույն"</string>
- <string name="rainbow_color_name_magenta" msgid="7248703626077785569">"Մորեգույն"</string>
- <string name="monochromatic_name" msgid="2554823570460886176">"Մոնոխրոմ"</string>
-</resources>
diff --git a/themes/res/values-in/strings.xml b/themes/res/values-in/strings.xml
deleted file mode 100644
index ab3df36..0000000
--- a/themes/res/values-in/strings.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (C) 2022 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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="rainbow_color_name_red" msgid="7452506008058561006">"Merah"</string>
- <string name="rainbow_color_name_orange" msgid="2921298510262609543">"Oranye"</string>
- <string name="rainbow_color_name_yellow" msgid="8675574652757989201">"Kuning"</string>
- <string name="rainbow_color_name_green" msgid="1932895389710184112">"Hijau"</string>
- <string name="rainbow_color_name_blue" msgid="3473176664458856892">"Biru"</string>
- <string name="rainbow_color_name_purple" msgid="2704722524588084868">"Ungu"</string>
- <string name="rainbow_color_name_magenta" msgid="7248703626077785569">"Magenta"</string>
- <string name="monochromatic_name" msgid="2554823570460886176">"Monokromatik"</string>
-</resources>
diff --git a/themes/res/values-is/strings.xml b/themes/res/values-is/strings.xml
deleted file mode 100644
index 1e34499..0000000
--- a/themes/res/values-is/strings.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (C) 2022 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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="rainbow_color_name_red" msgid="7452506008058561006">"Rauður"</string>
- <string name="rainbow_color_name_orange" msgid="2921298510262609543">"Appelsínugulur"</string>
- <string name="rainbow_color_name_yellow" msgid="8675574652757989201">"Gulur"</string>
- <string name="rainbow_color_name_green" msgid="1932895389710184112">"Grænn"</string>
- <string name="rainbow_color_name_blue" msgid="3473176664458856892">"Blár"</string>
- <string name="rainbow_color_name_purple" msgid="2704722524588084868">"Fjólublár"</string>
- <string name="rainbow_color_name_magenta" msgid="7248703626077785569">"Blárauður"</string>
- <string name="monochromatic_name" msgid="2554823570460886176">"Einlitt"</string>
-</resources>
diff --git a/themes/res/values-it/strings.xml b/themes/res/values-it/strings.xml
deleted file mode 100644
index 1ebec4c..0000000
--- a/themes/res/values-it/strings.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (C) 2022 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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="rainbow_color_name_red" msgid="7452506008058561006">"Rosso"</string>
- <string name="rainbow_color_name_orange" msgid="2921298510262609543">"Arancione"</string>
- <string name="rainbow_color_name_yellow" msgid="8675574652757989201">"Giallo"</string>
- <string name="rainbow_color_name_green" msgid="1932895389710184112">"Verde"</string>
- <string name="rainbow_color_name_blue" msgid="3473176664458856892">"Blu"</string>
- <string name="rainbow_color_name_purple" msgid="2704722524588084868">"Viola"</string>
- <string name="rainbow_color_name_magenta" msgid="7248703626077785569">"Magenta"</string>
- <string name="monochromatic_name" msgid="2554823570460886176">"Monocromatico"</string>
-</resources>
diff --git a/themes/res/values-iw/strings.xml b/themes/res/values-iw/strings.xml
deleted file mode 100644
index 49feaed..0000000
--- a/themes/res/values-iw/strings.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (C) 2022 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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="rainbow_color_name_red" msgid="7452506008058561006">"אדום"</string>
- <string name="rainbow_color_name_orange" msgid="2921298510262609543">"כתום"</string>
- <string name="rainbow_color_name_yellow" msgid="8675574652757989201">"צהוב"</string>
- <string name="rainbow_color_name_green" msgid="1932895389710184112">"ירוק"</string>
- <string name="rainbow_color_name_blue" msgid="3473176664458856892">"כחול"</string>
- <string name="rainbow_color_name_purple" msgid="2704722524588084868">"סגול"</string>
- <string name="rainbow_color_name_magenta" msgid="7248703626077785569">"מג\'נטה"</string>
- <string name="monochromatic_name" msgid="2554823570460886176">"מונוכרומטי"</string>
-</resources>
diff --git a/themes/res/values-ja/strings.xml b/themes/res/values-ja/strings.xml
deleted file mode 100644
index 7a259e6..0000000
--- a/themes/res/values-ja/strings.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (C) 2022 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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="rainbow_color_name_red" msgid="7452506008058561006">"赤"</string>
- <string name="rainbow_color_name_orange" msgid="2921298510262609543">"オレンジ"</string>
- <string name="rainbow_color_name_yellow" msgid="8675574652757989201">"黄"</string>
- <string name="rainbow_color_name_green" msgid="1932895389710184112">"緑"</string>
- <string name="rainbow_color_name_blue" msgid="3473176664458856892">"青"</string>
- <string name="rainbow_color_name_purple" msgid="2704722524588084868">"紫"</string>
- <string name="rainbow_color_name_magenta" msgid="7248703626077785569">"マゼンタ"</string>
- <string name="monochromatic_name" msgid="2554823570460886176">"モノクロ"</string>
-</resources>
diff --git a/themes/res/values-ka/strings.xml b/themes/res/values-ka/strings.xml
deleted file mode 100644
index 041dfc4..0000000
--- a/themes/res/values-ka/strings.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (C) 2022 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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="rainbow_color_name_red" msgid="7452506008058561006">"წითელი"</string>
- <string name="rainbow_color_name_orange" msgid="2921298510262609543">"ფორთოხლისფერი"</string>
- <string name="rainbow_color_name_yellow" msgid="8675574652757989201">"ყვითელი"</string>
- <string name="rainbow_color_name_green" msgid="1932895389710184112">"მწვანე"</string>
- <string name="rainbow_color_name_blue" msgid="3473176664458856892">"ლურჯი"</string>
- <string name="rainbow_color_name_purple" msgid="2704722524588084868">"იისფერი"</string>
- <string name="rainbow_color_name_magenta" msgid="7248703626077785569">"მეწამული"</string>
- <string name="monochromatic_name" msgid="2554823570460886176">"მონოქრომატული"</string>
-</resources>
diff --git a/themes/res/values-kk/strings.xml b/themes/res/values-kk/strings.xml
deleted file mode 100644
index b9d3952..0000000
--- a/themes/res/values-kk/strings.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (C) 2022 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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="rainbow_color_name_red" msgid="7452506008058561006">"Қызыл"</string>
- <string name="rainbow_color_name_orange" msgid="2921298510262609543">"Қызғылт сары"</string>
- <string name="rainbow_color_name_yellow" msgid="8675574652757989201">"Сары"</string>
- <string name="rainbow_color_name_green" msgid="1932895389710184112">"Жасыл"</string>
- <string name="rainbow_color_name_blue" msgid="3473176664458856892">"Көк"</string>
- <string name="rainbow_color_name_purple" msgid="2704722524588084868">"Күлгін"</string>
- <string name="rainbow_color_name_magenta" msgid="7248703626077785569">"Қызғылт күлгін"</string>
- <string name="monochromatic_name" msgid="2554823570460886176">"Монохром"</string>
-</resources>
diff --git a/themes/res/values-km/strings.xml b/themes/res/values-km/strings.xml
deleted file mode 100644
index a182c7a..0000000
--- a/themes/res/values-km/strings.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (C) 2022 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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="rainbow_color_name_red" msgid="7452506008058561006">"ក្រហម"</string>
- <string name="rainbow_color_name_orange" msgid="2921298510262609543">"ទឹកក្រូច"</string>
- <string name="rainbow_color_name_yellow" msgid="8675574652757989201">"លឿង"</string>
- <string name="rainbow_color_name_green" msgid="1932895389710184112">"បៃតង"</string>
- <string name="rainbow_color_name_blue" msgid="3473176664458856892">"ខៀវ"</string>
- <string name="rainbow_color_name_purple" msgid="2704722524588084868">"ស្វាយ"</string>
- <string name="rainbow_color_name_magenta" msgid="7248703626077785569">"ក្រហមស្វាយ"</string>
- <string name="monochromatic_name" msgid="2554823570460886176">"បែបម៉ូណូក្រូម"</string>
-</resources>
diff --git a/themes/res/values-kn/strings.xml b/themes/res/values-kn/strings.xml
deleted file mode 100644
index a899325..0000000
--- a/themes/res/values-kn/strings.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (C) 2022 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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="rainbow_color_name_red" msgid="7452506008058561006">"ಕೆಂಪು"</string>
- <string name="rainbow_color_name_orange" msgid="2921298510262609543">"ಕಿತ್ತಳೆ"</string>
- <string name="rainbow_color_name_yellow" msgid="8675574652757989201">"ಹಳದಿ"</string>
- <string name="rainbow_color_name_green" msgid="1932895389710184112">"ಹಸಿರು"</string>
- <string name="rainbow_color_name_blue" msgid="3473176664458856892">"ನೀಲಿ"</string>
- <string name="rainbow_color_name_purple" msgid="2704722524588084868">"ನೇರಳೆ"</string>
- <string name="rainbow_color_name_magenta" msgid="7248703626077785569">"ಮೆಜೆಂತಾ"</string>
- <string name="monochromatic_name" msgid="2554823570460886176">"Monochromatic"</string>
-</resources>
diff --git a/themes/res/values-ko/strings.xml b/themes/res/values-ko/strings.xml
deleted file mode 100644
index 2a77dc8..0000000
--- a/themes/res/values-ko/strings.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (C) 2022 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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="rainbow_color_name_red" msgid="7452506008058561006">"빨간색"</string>
- <string name="rainbow_color_name_orange" msgid="2921298510262609543">"주황색"</string>
- <string name="rainbow_color_name_yellow" msgid="8675574652757989201">"노란색"</string>
- <string name="rainbow_color_name_green" msgid="1932895389710184112">"녹색"</string>
- <string name="rainbow_color_name_blue" msgid="3473176664458856892">"파란색"</string>
- <string name="rainbow_color_name_purple" msgid="2704722524588084868">"보라색"</string>
- <string name="rainbow_color_name_magenta" msgid="7248703626077785569">"자홍색"</string>
- <string name="monochromatic_name" msgid="2554823570460886176">"단색"</string>
-</resources>
diff --git a/themes/res/values-ky/strings.xml b/themes/res/values-ky/strings.xml
deleted file mode 100644
index 1aaf2e0..0000000
--- a/themes/res/values-ky/strings.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (C) 2022 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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="rainbow_color_name_red" msgid="7452506008058561006">"Кызыл"</string>
- <string name="rainbow_color_name_orange" msgid="2921298510262609543">"Кызгылт сары"</string>
- <string name="rainbow_color_name_yellow" msgid="8675574652757989201">"Сары"</string>
- <string name="rainbow_color_name_green" msgid="1932895389710184112">"Жашыл"</string>
- <string name="rainbow_color_name_blue" msgid="3473176664458856892">"Көк"</string>
- <string name="rainbow_color_name_purple" msgid="2704722524588084868">"Кызгылт"</string>
- <string name="rainbow_color_name_magenta" msgid="7248703626077785569">"Маджента"</string>
- <string name="monochromatic_name" msgid="2554823570460886176">"Монохроматикалык"</string>
-</resources>
diff --git a/themes/res/values-lo/strings.xml b/themes/res/values-lo/strings.xml
deleted file mode 100644
index 8e5f1a2..0000000
--- a/themes/res/values-lo/strings.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (C) 2022 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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="rainbow_color_name_red" msgid="7452506008058561006">"ສີແດງ"</string>
- <string name="rainbow_color_name_orange" msgid="2921298510262609543">"ສີສົ້ມ"</string>
- <string name="rainbow_color_name_yellow" msgid="8675574652757989201">"ສີເຫຼືອງ"</string>
- <string name="rainbow_color_name_green" msgid="1932895389710184112">"ສີຂຽວ"</string>
- <string name="rainbow_color_name_blue" msgid="3473176664458856892">"ສີຟ້າ"</string>
- <string name="rainbow_color_name_purple" msgid="2704722524588084868">"ສີມ່ວງ"</string>
- <string name="rainbow_color_name_magenta" msgid="7248703626077785569">"ສີແດງມ່ວງ"</string>
- <string name="monochromatic_name" msgid="2554823570460886176">"ສີດຽວ"</string>
-</resources>
diff --git a/themes/res/values-lt/strings.xml b/themes/res/values-lt/strings.xml
deleted file mode 100644
index 542eea7..0000000
--- a/themes/res/values-lt/strings.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (C) 2022 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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="rainbow_color_name_red" msgid="7452506008058561006">"Raudona"</string>
- <string name="rainbow_color_name_orange" msgid="2921298510262609543">"Oranžinė"</string>
- <string name="rainbow_color_name_yellow" msgid="8675574652757989201">"Geltona"</string>
- <string name="rainbow_color_name_green" msgid="1932895389710184112">"Žalia"</string>
- <string name="rainbow_color_name_blue" msgid="3473176664458856892">"Mėlyna"</string>
- <string name="rainbow_color_name_purple" msgid="2704722524588084868">"Violetinė"</string>
- <string name="rainbow_color_name_magenta" msgid="7248703626077785569">"Purpurinė"</string>
- <string name="monochromatic_name" msgid="2554823570460886176">"Vienspalvis"</string>
-</resources>
diff --git a/themes/res/values-lv/strings.xml b/themes/res/values-lv/strings.xml
deleted file mode 100644
index 58b15e8..0000000
--- a/themes/res/values-lv/strings.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (C) 2022 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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="rainbow_color_name_red" msgid="7452506008058561006">"Sarkana"</string>
- <string name="rainbow_color_name_orange" msgid="2921298510262609543">"Oranža"</string>
- <string name="rainbow_color_name_yellow" msgid="8675574652757989201">"Dzeltena"</string>
- <string name="rainbow_color_name_green" msgid="1932895389710184112">"Zaļa"</string>
- <string name="rainbow_color_name_blue" msgid="3473176664458856892">"Zila"</string>
- <string name="rainbow_color_name_purple" msgid="2704722524588084868">"Violeta"</string>
- <string name="rainbow_color_name_magenta" msgid="7248703626077785569">"Fuksīna"</string>
- <string name="monochromatic_name" msgid="2554823570460886176">"Vienkrāsains"</string>
-</resources>
diff --git a/themes/res/values-mk/strings.xml b/themes/res/values-mk/strings.xml
deleted file mode 100644
index 94d1098..0000000
--- a/themes/res/values-mk/strings.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (C) 2022 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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="rainbow_color_name_red" msgid="7452506008058561006">"Црвена"</string>
- <string name="rainbow_color_name_orange" msgid="2921298510262609543">"Портокалова"</string>
- <string name="rainbow_color_name_yellow" msgid="8675574652757989201">"Жолта"</string>
- <string name="rainbow_color_name_green" msgid="1932895389710184112">"Зелена"</string>
- <string name="rainbow_color_name_blue" msgid="3473176664458856892">"Сина"</string>
- <string name="rainbow_color_name_purple" msgid="2704722524588084868">"Виолетова"</string>
- <string name="rainbow_color_name_magenta" msgid="7248703626077785569">"Магента"</string>
- <string name="monochromatic_name" msgid="2554823570460886176">"Монохроматски"</string>
-</resources>
diff --git a/themes/res/values-ml/strings.xml b/themes/res/values-ml/strings.xml
deleted file mode 100644
index 60f5acb..0000000
--- a/themes/res/values-ml/strings.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (C) 2022 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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="rainbow_color_name_red" msgid="7452506008058561006">"ചുവപ്പ്"</string>
- <string name="rainbow_color_name_orange" msgid="2921298510262609543">"ഓറഞ്ച്"</string>
- <string name="rainbow_color_name_yellow" msgid="8675574652757989201">"മഞ്ഞ"</string>
- <string name="rainbow_color_name_green" msgid="1932895389710184112">"പച്ച"</string>
- <string name="rainbow_color_name_blue" msgid="3473176664458856892">"നീല"</string>
- <string name="rainbow_color_name_purple" msgid="2704722524588084868">"പർപ്പിൾ"</string>
- <string name="rainbow_color_name_magenta" msgid="7248703626077785569">"മജന്ത"</string>
- <string name="monochromatic_name" msgid="2554823570460886176">"മോണോക്രൊമാറ്റിക്"</string>
-</resources>
diff --git a/themes/res/values-mn/strings.xml b/themes/res/values-mn/strings.xml
deleted file mode 100644
index 1a8c146..0000000
--- a/themes/res/values-mn/strings.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (C) 2022 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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="rainbow_color_name_red" msgid="7452506008058561006">"Улаан"</string>
- <string name="rainbow_color_name_orange" msgid="2921298510262609543">"Улбар шар"</string>
- <string name="rainbow_color_name_yellow" msgid="8675574652757989201">"Шар"</string>
- <string name="rainbow_color_name_green" msgid="1932895389710184112">"Ногоон"</string>
- <string name="rainbow_color_name_blue" msgid="3473176664458856892">"Цэнхэр"</string>
- <string name="rainbow_color_name_purple" msgid="2704722524588084868">"Нил ягаан"</string>
- <string name="rainbow_color_name_magenta" msgid="7248703626077785569">"Гүн нил ягаан"</string>
- <string name="monochromatic_name" msgid="2554823570460886176">"Дан өнгийн"</string>
-</resources>
diff --git a/themes/res/values-mr/strings.xml b/themes/res/values-mr/strings.xml
deleted file mode 100644
index cd0f1e7..0000000
--- a/themes/res/values-mr/strings.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (C) 2022 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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="rainbow_color_name_red" msgid="7452506008058561006">"लाल"</string>
- <string name="rainbow_color_name_orange" msgid="2921298510262609543">"नारिंगी"</string>
- <string name="rainbow_color_name_yellow" msgid="8675574652757989201">"पिवळा"</string>
- <string name="rainbow_color_name_green" msgid="1932895389710184112">"हिरवा"</string>
- <string name="rainbow_color_name_blue" msgid="3473176664458856892">"निळा"</string>
- <string name="rainbow_color_name_purple" msgid="2704722524588084868">"जांभळा"</string>
- <string name="rainbow_color_name_magenta" msgid="7248703626077785569">"मजेंटा"</string>
- <string name="monochromatic_name" msgid="2554823570460886176">"मोनोक्रोमॅटिक"</string>
-</resources>
diff --git a/themes/res/values-ms/strings.xml b/themes/res/values-ms/strings.xml
deleted file mode 100644
index 52a945b..0000000
--- a/themes/res/values-ms/strings.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (C) 2022 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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="rainbow_color_name_red" msgid="7452506008058561006">"Merah"</string>
- <string name="rainbow_color_name_orange" msgid="2921298510262609543">"Jingga"</string>
- <string name="rainbow_color_name_yellow" msgid="8675574652757989201">"Kuning"</string>
- <string name="rainbow_color_name_green" msgid="1932895389710184112">"Hijau"</string>
- <string name="rainbow_color_name_blue" msgid="3473176664458856892">"Biru"</string>
- <string name="rainbow_color_name_purple" msgid="2704722524588084868">"Ungu"</string>
- <string name="rainbow_color_name_magenta" msgid="7248703626077785569">"Magenta"</string>
- <string name="monochromatic_name" msgid="2554823570460886176">"Monokromatik"</string>
-</resources>
diff --git a/themes/res/values-my/strings.xml b/themes/res/values-my/strings.xml
deleted file mode 100644
index 6a12ed8..0000000
--- a/themes/res/values-my/strings.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (C) 2022 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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="rainbow_color_name_red" msgid="7452506008058561006">"အနီရောင်"</string>
- <string name="rainbow_color_name_orange" msgid="2921298510262609543">"လိမ္မော်ရောင်"</string>
- <string name="rainbow_color_name_yellow" msgid="8675574652757989201">"အဝါရောင်"</string>
- <string name="rainbow_color_name_green" msgid="1932895389710184112">"အစိမ်းရောင်"</string>
- <string name="rainbow_color_name_blue" msgid="3473176664458856892">"အပြာရောင်"</string>
- <string name="rainbow_color_name_purple" msgid="2704722524588084868">"ခရမ်းရောင်"</string>
- <string name="rainbow_color_name_magenta" msgid="7248703626077785569">"ပန်းခရမ်း"</string>
- <string name="monochromatic_name" msgid="2554823570460886176">"တစ်ရောင်တည်းအသွေးစုံ"</string>
-</resources>
diff --git a/themes/res/values-nb/strings.xml b/themes/res/values-nb/strings.xml
deleted file mode 100644
index f099b11..0000000
--- a/themes/res/values-nb/strings.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (C) 2022 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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="rainbow_color_name_red" msgid="7452506008058561006">"Rød"</string>
- <string name="rainbow_color_name_orange" msgid="2921298510262609543">"Oransje"</string>
- <string name="rainbow_color_name_yellow" msgid="8675574652757989201">"Gul"</string>
- <string name="rainbow_color_name_green" msgid="1932895389710184112">"Grønn"</string>
- <string name="rainbow_color_name_blue" msgid="3473176664458856892">"Blå"</string>
- <string name="rainbow_color_name_purple" msgid="2704722524588084868">"Lilla"</string>
- <string name="rainbow_color_name_magenta" msgid="7248703626077785569">"Magenta"</string>
- <string name="monochromatic_name" msgid="2554823570460886176">"Ensfarget"</string>
-</resources>
diff --git a/themes/res/values-ne/strings.xml b/themes/res/values-ne/strings.xml
deleted file mode 100644
index 3100185..0000000
--- a/themes/res/values-ne/strings.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (C) 2022 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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="rainbow_color_name_red" msgid="7452506008058561006">"रातो"</string>
- <string name="rainbow_color_name_orange" msgid="2921298510262609543">"सुन्तले रङ"</string>
- <string name="rainbow_color_name_yellow" msgid="8675574652757989201">"पहेँलो"</string>
- <string name="rainbow_color_name_green" msgid="1932895389710184112">"हरियो"</string>
- <string name="rainbow_color_name_blue" msgid="3473176664458856892">"निलो"</string>
- <string name="rainbow_color_name_purple" msgid="2704722524588084868">"बैजनी"</string>
- <string name="rainbow_color_name_magenta" msgid="7248703626077785569">"मजेन्टा"</string>
- <string name="monochromatic_name" msgid="2554823570460886176">"Monochromatic"</string>
-</resources>
diff --git a/themes/res/values-nl/strings.xml b/themes/res/values-nl/strings.xml
deleted file mode 100644
index be6785e..0000000
--- a/themes/res/values-nl/strings.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (C) 2022 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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="rainbow_color_name_red" msgid="7452506008058561006">"Rood"</string>
- <string name="rainbow_color_name_orange" msgid="2921298510262609543">"Oranje"</string>
- <string name="rainbow_color_name_yellow" msgid="8675574652757989201">"Geel"</string>
- <string name="rainbow_color_name_green" msgid="1932895389710184112">"Groen"</string>
- <string name="rainbow_color_name_blue" msgid="3473176664458856892">"Blauw"</string>
- <string name="rainbow_color_name_purple" msgid="2704722524588084868">"Paars"</string>
- <string name="rainbow_color_name_magenta" msgid="7248703626077785569">"Magenta"</string>
- <string name="monochromatic_name" msgid="2554823570460886176">"Monochroom"</string>
-</resources>
diff --git a/themes/res/values-or/strings.xml b/themes/res/values-or/strings.xml
deleted file mode 100644
index 3b10876..0000000
--- a/themes/res/values-or/strings.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (C) 2022 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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="rainbow_color_name_red" msgid="7452506008058561006">"ଲାଲ୍"</string>
- <string name="rainbow_color_name_orange" msgid="2921298510262609543">"କମଳା"</string>
- <string name="rainbow_color_name_yellow" msgid="8675574652757989201">"ହଳଦିଆ"</string>
- <string name="rainbow_color_name_green" msgid="1932895389710184112">"ସବୁଜ"</string>
- <string name="rainbow_color_name_blue" msgid="3473176664458856892">"ନୀଳ"</string>
- <string name="rainbow_color_name_purple" msgid="2704722524588084868">"ବାଇଗଣୀ"</string>
- <string name="rainbow_color_name_magenta" msgid="7248703626077785569">"ମାଜେଣ୍ଟା"</string>
- <string name="monochromatic_name" msgid="2554823570460886176">"ମୋନୋକ୍ରୋମାଟିକ"</string>
-</resources>
diff --git a/themes/res/values-pa/strings.xml b/themes/res/values-pa/strings.xml
deleted file mode 100644
index aee99a2..0000000
--- a/themes/res/values-pa/strings.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (C) 2022 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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="rainbow_color_name_red" msgid="7452506008058561006">"ਲਾਲ"</string>
- <string name="rainbow_color_name_orange" msgid="2921298510262609543">"ਸੰਤਰੀ"</string>
- <string name="rainbow_color_name_yellow" msgid="8675574652757989201">"ਪੀਲਾ"</string>
- <string name="rainbow_color_name_green" msgid="1932895389710184112">"ਹਰਾ"</string>
- <string name="rainbow_color_name_blue" msgid="3473176664458856892">"ਨੀਲਾ"</string>
- <string name="rainbow_color_name_purple" msgid="2704722524588084868">"ਜਾਮਨੀ"</string>
- <string name="rainbow_color_name_magenta" msgid="7248703626077785569">"ਮੈਜੰਟਾ"</string>
- <string name="monochromatic_name" msgid="2554823570460886176">"ਮੋਨੋਕ੍ਰੋਮੈਟਿਕ"</string>
-</resources>
diff --git a/themes/res/values-pl/strings.xml b/themes/res/values-pl/strings.xml
deleted file mode 100644
index 718067b..0000000
--- a/themes/res/values-pl/strings.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (C) 2022 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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="rainbow_color_name_red" msgid="7452506008058561006">"Czerwony"</string>
- <string name="rainbow_color_name_orange" msgid="2921298510262609543">"Pomarańczowy"</string>
- <string name="rainbow_color_name_yellow" msgid="8675574652757989201">"Żółty"</string>
- <string name="rainbow_color_name_green" msgid="1932895389710184112">"Zielony"</string>
- <string name="rainbow_color_name_blue" msgid="3473176664458856892">"Niebieski"</string>
- <string name="rainbow_color_name_purple" msgid="2704722524588084868">"Fioletowy"</string>
- <string name="rainbow_color_name_magenta" msgid="7248703626077785569">"Amarantowy"</string>
- <string name="monochromatic_name" msgid="2554823570460886176">"Monochromatyczne"</string>
-</resources>
diff --git a/themes/res/values-pt-rPT/strings.xml b/themes/res/values-pt-rPT/strings.xml
deleted file mode 100644
index 70525b6..0000000
--- a/themes/res/values-pt-rPT/strings.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (C) 2022 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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="rainbow_color_name_red" msgid="7452506008058561006">"Vermelho"</string>
- <string name="rainbow_color_name_orange" msgid="2921298510262609543">"Laranja"</string>
- <string name="rainbow_color_name_yellow" msgid="8675574652757989201">"Amarelo"</string>
- <string name="rainbow_color_name_green" msgid="1932895389710184112">"Verde"</string>
- <string name="rainbow_color_name_blue" msgid="3473176664458856892">"Azul"</string>
- <string name="rainbow_color_name_purple" msgid="2704722524588084868">"Roxo"</string>
- <string name="rainbow_color_name_magenta" msgid="7248703626077785569">"Magenta"</string>
- <string name="monochromatic_name" msgid="2554823570460886176">"Monocromático"</string>
-</resources>
diff --git a/themes/res/values-pt/strings.xml b/themes/res/values-pt/strings.xml
deleted file mode 100644
index 70525b6..0000000
--- a/themes/res/values-pt/strings.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (C) 2022 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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="rainbow_color_name_red" msgid="7452506008058561006">"Vermelho"</string>
- <string name="rainbow_color_name_orange" msgid="2921298510262609543">"Laranja"</string>
- <string name="rainbow_color_name_yellow" msgid="8675574652757989201">"Amarelo"</string>
- <string name="rainbow_color_name_green" msgid="1932895389710184112">"Verde"</string>
- <string name="rainbow_color_name_blue" msgid="3473176664458856892">"Azul"</string>
- <string name="rainbow_color_name_purple" msgid="2704722524588084868">"Roxo"</string>
- <string name="rainbow_color_name_magenta" msgid="7248703626077785569">"Magenta"</string>
- <string name="monochromatic_name" msgid="2554823570460886176">"Monocromático"</string>
-</resources>
diff --git a/themes/res/values-ro/strings.xml b/themes/res/values-ro/strings.xml
deleted file mode 100644
index c07e7c0..0000000
--- a/themes/res/values-ro/strings.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (C) 2022 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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="rainbow_color_name_red" msgid="7452506008058561006">"Roșu"</string>
- <string name="rainbow_color_name_orange" msgid="2921298510262609543">"Portocaliu"</string>
- <string name="rainbow_color_name_yellow" msgid="8675574652757989201">"Galben"</string>
- <string name="rainbow_color_name_green" msgid="1932895389710184112">"Verde"</string>
- <string name="rainbow_color_name_blue" msgid="3473176664458856892">"Albastru"</string>
- <string name="rainbow_color_name_purple" msgid="2704722524588084868">"Violet"</string>
- <string name="rainbow_color_name_magenta" msgid="7248703626077785569">"Magenta"</string>
- <string name="monochromatic_name" msgid="2554823570460886176">"Monocromatică"</string>
-</resources>
diff --git a/themes/res/values-ru/strings.xml b/themes/res/values-ru/strings.xml
deleted file mode 100644
index f714ff7..0000000
--- a/themes/res/values-ru/strings.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (C) 2022 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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="rainbow_color_name_red" msgid="7452506008058561006">"Красный"</string>
- <string name="rainbow_color_name_orange" msgid="2921298510262609543">"Оранжевый"</string>
- <string name="rainbow_color_name_yellow" msgid="8675574652757989201">"Желтый"</string>
- <string name="rainbow_color_name_green" msgid="1932895389710184112">"Зеленый"</string>
- <string name="rainbow_color_name_blue" msgid="3473176664458856892">"Синий"</string>
- <string name="rainbow_color_name_purple" msgid="2704722524588084868">"Фиолетовый"</string>
- <string name="rainbow_color_name_magenta" msgid="7248703626077785569">"Пурпурный"</string>
- <string name="monochromatic_name" msgid="2554823570460886176">"Монохромное"</string>
-</resources>
diff --git a/themes/res/values-si/strings.xml b/themes/res/values-si/strings.xml
deleted file mode 100644
index 107a988..0000000
--- a/themes/res/values-si/strings.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (C) 2022 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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="rainbow_color_name_red" msgid="7452506008058561006">"රතු"</string>
- <string name="rainbow_color_name_orange" msgid="2921298510262609543">"තැඹිලි"</string>
- <string name="rainbow_color_name_yellow" msgid="8675574652757989201">"කහ"</string>
- <string name="rainbow_color_name_green" msgid="1932895389710184112">"කොළ"</string>
- <string name="rainbow_color_name_blue" msgid="3473176664458856892">"නිල්"</string>
- <string name="rainbow_color_name_purple" msgid="2704722524588084868">"දම්"</string>
- <string name="rainbow_color_name_magenta" msgid="7248703626077785569">"මැජෙන්ටා"</string>
- <string name="monochromatic_name" msgid="2554823570460886176">"ඒකවර්ණ"</string>
-</resources>
diff --git a/themes/res/values-sk/strings.xml b/themes/res/values-sk/strings.xml
deleted file mode 100644
index 9368e6b..0000000
--- a/themes/res/values-sk/strings.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (C) 2022 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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="rainbow_color_name_red" msgid="7452506008058561006">"Červená"</string>
- <string name="rainbow_color_name_orange" msgid="2921298510262609543">"Oranžová"</string>
- <string name="rainbow_color_name_yellow" msgid="8675574652757989201">"Žltá"</string>
- <string name="rainbow_color_name_green" msgid="1932895389710184112">"Zelená"</string>
- <string name="rainbow_color_name_blue" msgid="3473176664458856892">"Modrá"</string>
- <string name="rainbow_color_name_purple" msgid="2704722524588084868">"Fialová"</string>
- <string name="rainbow_color_name_magenta" msgid="7248703626077785569">"Ružovofialová"</string>
- <string name="monochromatic_name" msgid="2554823570460886176">"Monochromatické"</string>
-</resources>
diff --git a/themes/res/values-sl/strings.xml b/themes/res/values-sl/strings.xml
deleted file mode 100644
index 051a9a3..0000000
--- a/themes/res/values-sl/strings.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (C) 2022 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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="rainbow_color_name_red" msgid="7452506008058561006">"Rdeča"</string>
- <string name="rainbow_color_name_orange" msgid="2921298510262609543">"Oranžna"</string>
- <string name="rainbow_color_name_yellow" msgid="8675574652757989201">"Rumena"</string>
- <string name="rainbow_color_name_green" msgid="1932895389710184112">"Zelena"</string>
- <string name="rainbow_color_name_blue" msgid="3473176664458856892">"Modra"</string>
- <string name="rainbow_color_name_purple" msgid="2704722524588084868">"Vijolična"</string>
- <string name="rainbow_color_name_magenta" msgid="7248703626077785569">"Magenta"</string>
- <string name="monochromatic_name" msgid="2554823570460886176">"Monokromatsko"</string>
-</resources>
diff --git a/themes/res/values-sq/strings.xml b/themes/res/values-sq/strings.xml
deleted file mode 100644
index b9c3ac9..0000000
--- a/themes/res/values-sq/strings.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (C) 2022 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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="rainbow_color_name_red" msgid="7452506008058561006">"E kuqe"</string>
- <string name="rainbow_color_name_orange" msgid="2921298510262609543">"Portokalli"</string>
- <string name="rainbow_color_name_yellow" msgid="8675574652757989201">"E verdhë"</string>
- <string name="rainbow_color_name_green" msgid="1932895389710184112">"E gjelbër"</string>
- <string name="rainbow_color_name_blue" msgid="3473176664458856892">"Blu"</string>
- <string name="rainbow_color_name_purple" msgid="2704722524588084868">"Vjollcë"</string>
- <string name="rainbow_color_name_magenta" msgid="7248703626077785569">"E purpurt"</string>
- <string name="monochromatic_name" msgid="2554823570460886176">"Monokromatik"</string>
-</resources>
diff --git a/themes/res/values-sr/strings.xml b/themes/res/values-sr/strings.xml
deleted file mode 100644
index dca38db..0000000
--- a/themes/res/values-sr/strings.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (C) 2022 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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="rainbow_color_name_red" msgid="7452506008058561006">"Црвена"</string>
- <string name="rainbow_color_name_orange" msgid="2921298510262609543">"Наранџаста"</string>
- <string name="rainbow_color_name_yellow" msgid="8675574652757989201">"Жута"</string>
- <string name="rainbow_color_name_green" msgid="1932895389710184112">"Зелена"</string>
- <string name="rainbow_color_name_blue" msgid="3473176664458856892">"Плава"</string>
- <string name="rainbow_color_name_purple" msgid="2704722524588084868">"Љубичаста"</string>
- <string name="rainbow_color_name_magenta" msgid="7248703626077785569">"Магента"</string>
- <string name="monochromatic_name" msgid="2554823570460886176">"Монохроматско"</string>
-</resources>
diff --git a/themes/res/values-sv/strings.xml b/themes/res/values-sv/strings.xml
deleted file mode 100644
index a16f98c..0000000
--- a/themes/res/values-sv/strings.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (C) 2022 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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="rainbow_color_name_red" msgid="7452506008058561006">"Röd"</string>
- <string name="rainbow_color_name_orange" msgid="2921298510262609543">"Orange"</string>
- <string name="rainbow_color_name_yellow" msgid="8675574652757989201">"Gul"</string>
- <string name="rainbow_color_name_green" msgid="1932895389710184112">"Grön"</string>
- <string name="rainbow_color_name_blue" msgid="3473176664458856892">"Blå"</string>
- <string name="rainbow_color_name_purple" msgid="2704722524588084868">"Lila"</string>
- <string name="rainbow_color_name_magenta" msgid="7248703626077785569">"Magenta"</string>
- <string name="monochromatic_name" msgid="2554823570460886176">"Enfärgad"</string>
-</resources>
diff --git a/themes/res/values-sw/strings.xml b/themes/res/values-sw/strings.xml
deleted file mode 100644
index 26a08f3..0000000
--- a/themes/res/values-sw/strings.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (C) 2022 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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="rainbow_color_name_red" msgid="7452506008058561006">"Nyekundu"</string>
- <string name="rainbow_color_name_orange" msgid="2921298510262609543">"Rangi ya machungwa"</string>
- <string name="rainbow_color_name_yellow" msgid="8675574652757989201">"Njano"</string>
- <string name="rainbow_color_name_green" msgid="1932895389710184112">"Kijani"</string>
- <string name="rainbow_color_name_blue" msgid="3473176664458856892">"Bluu"</string>
- <string name="rainbow_color_name_purple" msgid="2704722524588084868">"Zambarau"</string>
- <string name="rainbow_color_name_magenta" msgid="7248703626077785569">"Majenta"</string>
- <string name="monochromatic_name" msgid="2554823570460886176">"Yenye rangi moja"</string>
-</resources>
diff --git a/themes/res/values-ta/strings.xml b/themes/res/values-ta/strings.xml
deleted file mode 100644
index d9f63f9..0000000
--- a/themes/res/values-ta/strings.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (C) 2022 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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="rainbow_color_name_red" msgid="7452506008058561006">"சிவப்பு"</string>
- <string name="rainbow_color_name_orange" msgid="2921298510262609543">"ஆரஞ்சு"</string>
- <string name="rainbow_color_name_yellow" msgid="8675574652757989201">"மஞ்சள்"</string>
- <string name="rainbow_color_name_green" msgid="1932895389710184112">"பச்சை"</string>
- <string name="rainbow_color_name_blue" msgid="3473176664458856892">"நீலம்"</string>
- <string name="rainbow_color_name_purple" msgid="2704722524588084868">"ஊதா"</string>
- <string name="rainbow_color_name_magenta" msgid="7248703626077785569">"மெஜந்தா"</string>
- <string name="monochromatic_name" msgid="2554823570460886176">"ஒற்றை வண்ணம்"</string>
-</resources>
diff --git a/themes/res/values-te/strings.xml b/themes/res/values-te/strings.xml
deleted file mode 100644
index 7193b3f..0000000
--- a/themes/res/values-te/strings.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (C) 2022 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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="rainbow_color_name_red" msgid="7452506008058561006">"ఎరుపు రంగు"</string>
- <string name="rainbow_color_name_orange" msgid="2921298510262609543">"నారింజ రంగు"</string>
- <string name="rainbow_color_name_yellow" msgid="8675574652757989201">"పసుపు రంగు"</string>
- <string name="rainbow_color_name_green" msgid="1932895389710184112">"ఆకుపచ్చ రంగు"</string>
- <string name="rainbow_color_name_blue" msgid="3473176664458856892">"నీలం"</string>
- <string name="rainbow_color_name_purple" msgid="2704722524588084868">"ఊదా రంగు"</string>
- <string name="rainbow_color_name_magenta" msgid="7248703626077785569">"మెజెంటా రంగు"</string>
- <string name="monochromatic_name" msgid="2554823570460886176">"ఏకవర్ణం"</string>
-</resources>
diff --git a/themes/res/values-th/strings.xml b/themes/res/values-th/strings.xml
deleted file mode 100644
index fed6f85..0000000
--- a/themes/res/values-th/strings.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (C) 2022 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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="rainbow_color_name_red" msgid="7452506008058561006">"แดง"</string>
- <string name="rainbow_color_name_orange" msgid="2921298510262609543">"ส้ม"</string>
- <string name="rainbow_color_name_yellow" msgid="8675574652757989201">"เหลือง"</string>
- <string name="rainbow_color_name_green" msgid="1932895389710184112">"เขียว"</string>
- <string name="rainbow_color_name_blue" msgid="3473176664458856892">"น้ำเงิน"</string>
- <string name="rainbow_color_name_purple" msgid="2704722524588084868">"ม่วง"</string>
- <string name="rainbow_color_name_magenta" msgid="7248703626077785569">"ม่วงแดง"</string>
- <string name="monochromatic_name" msgid="2554823570460886176">"สีเดียว"</string>
-</resources>
diff --git a/themes/res/values-tl/strings.xml b/themes/res/values-tl/strings.xml
deleted file mode 100644
index 56b9341..0000000
--- a/themes/res/values-tl/strings.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (C) 2022 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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="rainbow_color_name_red" msgid="7452506008058561006">"Pula"</string>
- <string name="rainbow_color_name_orange" msgid="2921298510262609543">"Orange"</string>
- <string name="rainbow_color_name_yellow" msgid="8675574652757989201">"Dilaw"</string>
- <string name="rainbow_color_name_green" msgid="1932895389710184112">"Berde"</string>
- <string name="rainbow_color_name_blue" msgid="3473176664458856892">"Asul"</string>
- <string name="rainbow_color_name_purple" msgid="2704722524588084868">"Purple"</string>
- <string name="rainbow_color_name_magenta" msgid="7248703626077785569">"Magenta"</string>
- <string name="monochromatic_name" msgid="2554823570460886176">"Monochromatic"</string>
-</resources>
diff --git a/themes/res/values-tr/strings.xml b/themes/res/values-tr/strings.xml
deleted file mode 100644
index 7c8a549..0000000
--- a/themes/res/values-tr/strings.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (C) 2022 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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="rainbow_color_name_red" msgid="7452506008058561006">"Kırmızı"</string>
- <string name="rainbow_color_name_orange" msgid="2921298510262609543">"Turuncu"</string>
- <string name="rainbow_color_name_yellow" msgid="8675574652757989201">"Sarı"</string>
- <string name="rainbow_color_name_green" msgid="1932895389710184112">"Yeşil"</string>
- <string name="rainbow_color_name_blue" msgid="3473176664458856892">"Mavi"</string>
- <string name="rainbow_color_name_purple" msgid="2704722524588084868">"Mor"</string>
- <string name="rainbow_color_name_magenta" msgid="7248703626077785569">"Macenta"</string>
- <string name="monochromatic_name" msgid="2554823570460886176">"Tek Renkli"</string>
-</resources>
diff --git a/themes/res/values-uk/strings.xml b/themes/res/values-uk/strings.xml
deleted file mode 100644
index 39bdab6..0000000
--- a/themes/res/values-uk/strings.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (C) 2022 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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="rainbow_color_name_red" msgid="7452506008058561006">"Червоний"</string>
- <string name="rainbow_color_name_orange" msgid="2921298510262609543">"Оранжевий"</string>
- <string name="rainbow_color_name_yellow" msgid="8675574652757989201">"Жовтий"</string>
- <string name="rainbow_color_name_green" msgid="1932895389710184112">"Зелений"</string>
- <string name="rainbow_color_name_blue" msgid="3473176664458856892">"Синій"</string>
- <string name="rainbow_color_name_purple" msgid="2704722524588084868">"Фіолетовий"</string>
- <string name="rainbow_color_name_magenta" msgid="7248703626077785569">"Пурпуровий"</string>
- <string name="monochromatic_name" msgid="2554823570460886176">"Монохроматична"</string>
-</resources>
diff --git a/themes/res/values-ur/strings.xml b/themes/res/values-ur/strings.xml
deleted file mode 100644
index 744ee5c..0000000
--- a/themes/res/values-ur/strings.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (C) 2022 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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="rainbow_color_name_red" msgid="7452506008058561006">"سرخ"</string>
- <string name="rainbow_color_name_orange" msgid="2921298510262609543">"نارنجی"</string>
- <string name="rainbow_color_name_yellow" msgid="8675574652757989201">"پیلا"</string>
- <string name="rainbow_color_name_green" msgid="1932895389710184112">"سبز"</string>
- <string name="rainbow_color_name_blue" msgid="3473176664458856892">"نیلا"</string>
- <string name="rainbow_color_name_purple" msgid="2704722524588084868">"جامنی"</string>
- <string name="rainbow_color_name_magenta" msgid="7248703626077785569">"میجنٹا"</string>
- <string name="monochromatic_name" msgid="2554823570460886176">"Monochromatic"</string>
-</resources>
diff --git a/themes/res/values-uz/strings.xml b/themes/res/values-uz/strings.xml
deleted file mode 100644
index 6a09e63..0000000
--- a/themes/res/values-uz/strings.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (C) 2022 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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="rainbow_color_name_red" msgid="7452506008058561006">"Qizil"</string>
- <string name="rainbow_color_name_orange" msgid="2921298510262609543">"Toʻq sariq"</string>
- <string name="rainbow_color_name_yellow" msgid="8675574652757989201">"Sariq"</string>
- <string name="rainbow_color_name_green" msgid="1932895389710184112">"Yashil"</string>
- <string name="rainbow_color_name_blue" msgid="3473176664458856892">"Koʻk"</string>
- <string name="rainbow_color_name_purple" msgid="2704722524588084868">"Siyohrang"</string>
- <string name="rainbow_color_name_magenta" msgid="7248703626077785569">"Qirmizi"</string>
- <string name="monochromatic_name" msgid="2554823570460886176">"Bir rangli"</string>
-</resources>
diff --git a/themes/res/values-vi/strings.xml b/themes/res/values-vi/strings.xml
deleted file mode 100644
index 46e41b9..0000000
--- a/themes/res/values-vi/strings.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (C) 2022 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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="rainbow_color_name_red" msgid="7452506008058561006">"Đỏ"</string>
- <string name="rainbow_color_name_orange" msgid="2921298510262609543">"Cam"</string>
- <string name="rainbow_color_name_yellow" msgid="8675574652757989201">"Vàng"</string>
- <string name="rainbow_color_name_green" msgid="1932895389710184112">"Xanh lục"</string>
- <string name="rainbow_color_name_blue" msgid="3473176664458856892">"Xanh lam"</string>
- <string name="rainbow_color_name_purple" msgid="2704722524588084868">"Tím"</string>
- <string name="rainbow_color_name_magenta" msgid="7248703626077785569">"Đỏ tía"</string>
- <string name="monochromatic_name" msgid="2554823570460886176">"Đơn sắc"</string>
-</resources>
diff --git a/themes/res/values-zh-rCN/strings.xml b/themes/res/values-zh-rCN/strings.xml
deleted file mode 100644
index 074e0c6..0000000
--- a/themes/res/values-zh-rCN/strings.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (C) 2022 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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="rainbow_color_name_red" msgid="7452506008058561006">"红色"</string>
- <string name="rainbow_color_name_orange" msgid="2921298510262609543">"橙色"</string>
- <string name="rainbow_color_name_yellow" msgid="8675574652757989201">"黄色"</string>
- <string name="rainbow_color_name_green" msgid="1932895389710184112">"绿色"</string>
- <string name="rainbow_color_name_blue" msgid="3473176664458856892">"蓝色"</string>
- <string name="rainbow_color_name_purple" msgid="2704722524588084868">"紫色"</string>
- <string name="rainbow_color_name_magenta" msgid="7248703626077785569">"品红色"</string>
- <string name="monochromatic_name" msgid="2554823570460886176">"单色"</string>
-</resources>
diff --git a/themes/res/values-zh-rHK/strings.xml b/themes/res/values-zh-rHK/strings.xml
deleted file mode 100644
index ce97c07..0000000
--- a/themes/res/values-zh-rHK/strings.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (C) 2022 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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="rainbow_color_name_red" msgid="7452506008058561006">"紅色"</string>
- <string name="rainbow_color_name_orange" msgid="2921298510262609543">"橙色"</string>
- <string name="rainbow_color_name_yellow" msgid="8675574652757989201">"黃色"</string>
- <string name="rainbow_color_name_green" msgid="1932895389710184112">"綠色"</string>
- <string name="rainbow_color_name_blue" msgid="3473176664458856892">"藍色"</string>
- <string name="rainbow_color_name_purple" msgid="2704722524588084868">"紫色"</string>
- <string name="rainbow_color_name_magenta" msgid="7248703626077785569">"紫紅色"</string>
- <string name="monochromatic_name" msgid="2554823570460886176">"單色"</string>
-</resources>
diff --git a/themes/res/values-zh-rTW/strings.xml b/themes/res/values-zh-rTW/strings.xml
deleted file mode 100644
index ce67534..0000000
--- a/themes/res/values-zh-rTW/strings.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (C) 2022 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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="rainbow_color_name_red" msgid="7452506008058561006">"紅色"</string>
- <string name="rainbow_color_name_orange" msgid="2921298510262609543">"橘色"</string>
- <string name="rainbow_color_name_yellow" msgid="8675574652757989201">"黃色"</string>
- <string name="rainbow_color_name_green" msgid="1932895389710184112">"綠色"</string>
- <string name="rainbow_color_name_blue" msgid="3473176664458856892">"藍色"</string>
- <string name="rainbow_color_name_purple" msgid="2704722524588084868">"紫色"</string>
- <string name="rainbow_color_name_magenta" msgid="7248703626077785569">"洋紅色"</string>
- <string name="monochromatic_name" msgid="2554823570460886176">"單色"</string>
-</resources>
diff --git a/themes/res/values-zu/strings.xml b/themes/res/values-zu/strings.xml
deleted file mode 100644
index 75240f6..0000000
--- a/themes/res/values-zu/strings.xml
+++ /dev/null
@@ -1,28 +0,0 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<!--
- ~ Copyright (C) 2022 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.
- -->
-
-<resources xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="rainbow_color_name_red" msgid="7452506008058561006">"Okubomvu"</string>
- <string name="rainbow_color_name_orange" msgid="2921298510262609543">"Okuwolintshi"</string>
- <string name="rainbow_color_name_yellow" msgid="8675574652757989201">"Okuphuzi"</string>
- <string name="rainbow_color_name_green" msgid="1932895389710184112">"Okuluhlaza okotshani"</string>
- <string name="rainbow_color_name_blue" msgid="3473176664458856892">"Okuluhlaza okwesibhakabhaka"</string>
- <string name="rainbow_color_name_purple" msgid="2704722524588084868">"Okuphephuli"</string>
- <string name="rainbow_color_name_magenta" msgid="7248703626077785569">"Oku-magenta"</string>
- <string name="monochromatic_name" msgid="2554823570460886176">"I-Monochromatic"</string>
-</resources>