Merge tag 'android-13.0.0_r35' into leaf-2.0
Android 13.0.0 release 35
* tag 'android-13.0.0_r35': (51 commits)
Import translations. DO NOT MERGE ANYWHERE
Revert "Use Mockito 4.6.1 API"
Offset preview to start if on wallpaper display
Add ThemePicker instrumented tests to presubmit
Fix unit test to allow ThemePickerTests to run as presubmit
Import translations. DO NOT MERGE ANYWHERE
Import translations. DO NOT MERGE ANYWHERE
[TP] Make injectors kt
Renames customization content provider (3/7).
Beautifies picker disabled dialogs (2/2).
Unified screen preview section (2/3).
Add metrics for probing wallpaper effect readiness.
Moves common screen preview logic to WPP2 (2/2).
Wallpaper picker reset support (2/3).
Add target for ThemePicker instrumented tests
Tabbed navigation in Wallpaper Picker (2/3).
Use Mockito 4.6.1 API
Import translations. DO NOT MERGE ANYWHERE
Defines flag for ravemped WPP UI (4/5).
Links WPP clocks flag to SysUI's flag (1/3).
...
Change-Id: If8bf153ab4e89e0fe71aa3e7bac3afa1bb86dc30
diff --git a/Android.bp b/Android.bp
index 05e6bfa..ffd72ee 100644
--- a/Android.bp
+++ b/Android.bp
@@ -28,6 +28,14 @@
}
filegroup {
+ name: "ThemePicker_src_overrides",
+ srcs: [
+ "src_override/**/*.java",
+ "src_override/**/*.kt",
+ ],
+}
+
+filegroup {
name: "ThemePicker_Manifest",
srcs: [
"AndroidManifest.xml",
@@ -46,20 +54,33 @@
+ "$(location soong_zip) -o $(out) -C $$RES_DIR -D $$RES_DIR"
}
-//
-// Build app code.
-//
-android_app {
- name: "ThemePicker",
+genrule {
+ name: "ThemePicker_res_overrides",
+ tools: ["soong_zip"],
+ srcs: [
+ "res_override/**/*",
+ ],
+ out: ["ThemePicker_res_overrides.zip"],
+ cmd: "INPUTS=($(in)) && "
+ + "RES_DIR=$$(dirname $$(dirname $${INPUTS[0]})) && "
+ + "$(location soong_zip) -o $(out) -C $$RES_DIR -D $$RES_DIR"
+}
+
+java_defaults {
+ name: "ThemePicker_defaults",
static_libs: [
"guava",
"monet",
- "renderscript_toolkit",
+ "renderscript_toolkit",
"wallpaper-common-deps",
"SettingsLibSettingsTheme",
"SystemUI-statsd",
"styleprotoslite",
+ "androidx.lifecycle_lifecycle-runtime-ktx",
+ "androidx.lifecycle_lifecycle-viewmodel-ktx",
+ "androidx.recyclerview_recyclerview",
+ "SystemUICustomizationLib",
],
jni_libs: [
@@ -69,17 +90,12 @@
srcs: [
":WallpaperPicker2_srcs",
":ThemePicker_srcs",
- "src_override/**/*.java",
- "src_override/**/*.kt",
- ],
-
- resource_dirs: [
- "res_override",
+ ":ThemePicker_src_overrides",
],
use_embedded_native_libs: true,
- resource_zips: [":WallpaperPicker2_res", ":ThemePicker_res"],
+ resource_zips: [":WallpaperPicker2_res", ":ThemePicker_res", ":ThemePicker_res_overrides"],
optimize: {
enabled: false,
@@ -89,6 +105,15 @@
privileged: true,
system_ext_specific: true,
+}
+
+//
+// Build app code.
+//
+android_app {
+ name: "ThemePicker",
+ defaults: ["ThemePicker_defaults"],
+
platform_apis: true,
manifest: "AndroidManifest.xml",
additional_manifests: [":WallpaperPicker2_Manifest"],
diff --git a/AndroidManifest.xml b/AndroidManifest.xml
index 0d0ba15..16c15ca 100755
--- a/AndroidManifest.xml
+++ b/AndroidManifest.xml
@@ -11,6 +11,8 @@
<uses-permission android:name="android.permission.BIND_WALLPAPER" />
<uses-permission android:name="android.permission.MODIFY_DAY_NIGHT_MODE" />
+ <uses-permission android:name="android.permission.READ_DEVICE_CONFIG" />
+ <uses-permission android:name="android.permission.CUSTOMIZE_SYSTEM_UI" />
<uses-permission android:name="android.permission.QUERY_ALL_PACKAGES" />
<uses-permission android:name="android.permission.INTERACT_ACROSS_USERS_FULL" />
@@ -40,7 +42,7 @@
<intent>
<action android:name="com.android.launcher3.action.PARTNER_CUSTOMIZATION" />
</intent>
- <!-- Intent filter with action used to discover launcher -->
+ <!-- Intent filter used to query the launcher Activity for grid preview metadata -->
<intent>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.HOME" />
diff --git a/TEST_MAPPING b/TEST_MAPPING
new file mode 100644
index 0000000..0bde595
--- /dev/null
+++ b/TEST_MAPPING
@@ -0,0 +1,12 @@
+{
+ "presubmit": [
+ {
+ "name": "ThemePickerTests",
+ "options": [
+ {
+ "exclude-annotation": "org.junit.Ignore"
+ }
+ ]
+ }
+ ]
+}
diff --git a/ktfmt_includes.txt b/ktfmt_includes.txt
index 703e852..112b4a1 100644
--- a/ktfmt_includes.txt
+++ b/ktfmt_includes.txt
@@ -1,7 +1,3 @@
+src/
+src_override/
+tests/
--src/com/android/customization/model/color/ColorProvider.kt
--src/com/android/customization/model/color/ColorUtils.kt
--src/com/android/customization/module/SysUiStatsLogger.kt
--src/com/android/customization/picker/clock/ClockSectionView.kt
diff --git a/res/color-night/check_circle_grey_large_not_select_background_color.xml b/res/color-night/check_circle_grey_large_not_select_background_color.xml
index ab5c0cd..32826a7 100644
--- a/res/color-night/check_circle_grey_large_not_select_background_color.xml
+++ b/res/color-night/check_circle_grey_large_not_select_background_color.xml
@@ -14,7 +14,6 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-<selector xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:androidprv="http://schemas.android.com/apk/prv/res/android">
- <item android:color="?androidprv:attr/textColorSecondary" />
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:color="@color/text_color_secondary" />
</selector>
\ No newline at end of file
diff --git a/res/color-night/check_circle_grey_large_not_select_color.xml b/res/color-night/check_circle_grey_large_not_select_color.xml
index 6e8db34..63261b4 100644
--- a/res/color-night/check_circle_grey_large_not_select_color.xml
+++ b/res/color-night/check_circle_grey_large_not_select_color.xml
@@ -14,7 +14,6 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-<selector xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:androidprv="http://schemas.android.com/apk/prv/res/android" >
- <item android:color="?androidprv:attr/textColorOnAccent" />
+<selector xmlns:android="http://schemas.android.com/apk/res/android" >
+ <item android:color="@color/text_color_on_accent" />
</selector>
\ No newline at end of file
diff --git a/res/color-night/option_background_new_selection_color.xml b/res/color-night/option_background_new_selection_color.xml
index 0158ea2..7455a85 100644
--- a/res/color-night/option_background_new_selection_color.xml
+++ b/res/color-night/option_background_new_selection_color.xml
@@ -14,7 +14,6 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-<selector xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:androidprv="http://schemas.android.com/apk/prv/res/android">
- <item android:color="?androidprv:attr/colorAccentPrimaryVariant" />
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:color="@color/color_accent_primary_variant" />
</selector>
\ No newline at end of file
diff --git a/res/color/check_circle_grey_large_not_select_background_color.xml b/res/color/check_circle_grey_large_not_select_background_color.xml
index c023611..4a8a163 100644
--- a/res/color/check_circle_grey_large_not_select_background_color.xml
+++ b/res/color/check_circle_grey_large_not_select_background_color.xml
@@ -14,7 +14,6 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-<selector xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:androidprv="http://schemas.android.com/apk/prv/res/android">
- <item android:color="?androidprv:attr/textColorSecondaryInverse" />
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:color="@color/text_color_secondary_inverse" />
</selector>
\ No newline at end of file
diff --git a/res/color/check_circle_grey_large_not_select_color.xml b/res/color/check_circle_grey_large_not_select_color.xml
index 252665f..e89678a 100644
--- a/res/color/check_circle_grey_large_not_select_color.xml
+++ b/res/color/check_circle_grey_large_not_select_color.xml
@@ -14,7 +14,6 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-<selector xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:androidprv="http://schemas.android.com/apk/prv/res/android">
- <item android:color="?androidprv:attr/textColorPrimary" />
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:color="@color/text_color_primary" />
</selector>
\ No newline at end of file
diff --git a/res/color/keyguard_quick_affordance_slot_tab_background_color.xml b/res/color/keyguard_quick_affordance_slot_tab_background_color.xml
new file mode 100644
index 0000000..4708cef
--- /dev/null
+++ b/res/color/keyguard_quick_affordance_slot_tab_background_color.xml
@@ -0,0 +1,21 @@
+<?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.
+ ~
+ -->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:state_selected="true" android:color="@color/color_accent_primary" />
+ <item android:color="@android:color/transparent" />
+</selector>
diff --git a/res/color/keyguard_quick_affordance_slot_tab_text_color.xml b/res/color/keyguard_quick_affordance_slot_tab_text_color.xml
new file mode 100644
index 0000000..84502d4
--- /dev/null
+++ b/res/color/keyguard_quick_affordance_slot_tab_text_color.xml
@@ -0,0 +1,21 @@
+<?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.
+ ~
+ -->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:state_selected="true" android:color="@color/text_color_on_accent" />
+ <item android:color="@color/text_color_primary" />
+</selector>
diff --git a/res/color/option_background_new_selection_color.xml b/res/color/option_background_new_selection_color.xml
index 0158ea2..7455a85 100644
--- a/res/color/option_background_new_selection_color.xml
+++ b/res/color/option_background_new_selection_color.xml
@@ -14,7 +14,6 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-<selector xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:androidprv="http://schemas.android.com/apk/prv/res/android">
- <item android:color="?androidprv:attr/colorAccentPrimaryVariant" />
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:color="@color/color_accent_primary_variant" />
</selector>
\ No newline at end of file
diff --git a/res/drawable/beta_tag_background.xml b/res/drawable/beta_tag_background.xml
index 8104531..62a5129 100644
--- a/res/drawable/beta_tag_background.xml
+++ b/res/drawable/beta_tag_background.xml
@@ -14,11 +14,10 @@
limitations under the License.
-->
<shape xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
android:shape="rectangle">
<size
android:width="@dimen/beta_tag_background_width"
android:height="@dimen/beta_tag_background_height" />
<corners android:radius="@dimen/beta_tag_background_height" />
- <solid android:color="?androidprv:attr/colorAccentPrimary" />
+ <solid android:color="@color/color_accent_primary" />
</shape>
\ No newline at end of file
diff --git a/res/drawable/button_background.xml b/res/drawable/button_background.xml
new file mode 100644
index 0000000..24c7253
--- /dev/null
+++ b/res/drawable/button_background.xml
@@ -0,0 +1,20 @@
+<!--
+ 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="50dp" />
+ <solid android:color="@color/color_accent_primary" />
+</shape>
diff --git a/res/drawable/check_circle_grey_large.xml b/res/drawable/check_circle_grey_large.xml
index cf42bf3..f22c910 100644
--- a/res/drawable/check_circle_grey_large.xml
+++ b/res/drawable/check_circle_grey_large.xml
@@ -13,13 +13,12 @@
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"
- xmlns:androidprv="http://schemas.android.com/apk/prv/res/android">
+<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape android:shape="oval">
<size android:width="@dimen/center_check_size"
android:height="@dimen/center_check_size" />
- <solid android:color="?androidprv:attr/colorAccentPrimaryVariant" />
+ <solid android:color="@color/color_accent_primary_variant" />
</shape>
</item>
<item>
diff --git a/res/drawable/check_circle_grey_large_not_select.xml b/res/drawable/check_circle_grey_large_not_select.xml
index 544d852..bba494e 100644
--- a/res/drawable/check_circle_grey_large_not_select.xml
+++ b/res/drawable/check_circle_grey_large_not_select.xml
@@ -13,8 +13,7 @@
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"
- xmlns:androidprv="http://schemas.android.com/apk/prv/res/android">
+<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape android:shape="oval">
<size android:width="@dimen/center_check_size"
diff --git a/res/drawable/color_chip_seed_filled0.xml b/res/drawable/color_chip_seed_filled0.xml
index a93bc6b..2d4376c 100644
--- a/res/drawable/color_chip_seed_filled0.xml
+++ b/res/drawable/color_chip_seed_filled0.xml
@@ -19,10 +19,10 @@
<item>
<shape android:shape="rectangle">
<corners
- android:topLeftRadius="@dimen/component_color_chip_small_size_default" />
+ android:topLeftRadius="@dimen/component_color_chip_small_radius_default" />
<size
- android:width="@dimen/component_color_chip_small_size_default"
- android:height="@dimen/component_color_chip_small_size_default" />
+ android:width="@dimen/component_color_chip_small_radius_default"
+ android:height="@dimen/component_color_chip_small_radius_default" />
<solid android:color="@android:color/black" />
</shape>
</item>
diff --git a/res/drawable/color_chip_seed_filled1.xml b/res/drawable/color_chip_seed_filled1.xml
index a0672bc..1514939 100644
--- a/res/drawable/color_chip_seed_filled1.xml
+++ b/res/drawable/color_chip_seed_filled1.xml
@@ -19,10 +19,10 @@
<item>
<shape android:shape="rectangle">
<corners
- android:bottomLeftRadius="@dimen/component_color_chip_small_size_default" />
+ android:bottomLeftRadius="@dimen/component_color_chip_small_radius_default" />
<size
- android:width="@dimen/component_color_chip_small_size_default"
- android:height="@dimen/component_color_chip_small_size_default" />
+ android:width="@dimen/component_color_chip_small_radius_default"
+ android:height="@dimen/component_color_chip_small_radius_default" />
<solid android:color="@android:color/black" />
</shape>
</item>
diff --git a/res/drawable/color_chip_seed_filled2.xml b/res/drawable/color_chip_seed_filled2.xml
index 545fbdd..b415bb2 100644
--- a/res/drawable/color_chip_seed_filled2.xml
+++ b/res/drawable/color_chip_seed_filled2.xml
@@ -19,10 +19,10 @@
<item>
<shape android:shape="rectangle">
<corners
- android:topRightRadius="@dimen/component_color_chip_small_size_default" />
+ android:topRightRadius="@dimen/component_color_chip_small_radius_default" />
<size
- android:width="@dimen/component_color_chip_small_size_default"
- android:height="@dimen/component_color_chip_small_size_default" />
+ android:width="@dimen/component_color_chip_small_radius_default"
+ android:height="@dimen/component_color_chip_small_radius_default" />
<solid android:color="@android:color/black" />
</shape>
</item>
diff --git a/res/drawable/color_chip_seed_filled3.xml b/res/drawable/color_chip_seed_filled3.xml
index 0e286a5..49f429d 100644
--- a/res/drawable/color_chip_seed_filled3.xml
+++ b/res/drawable/color_chip_seed_filled3.xml
@@ -19,10 +19,10 @@
<item>
<shape android:shape="rectangle">
<corners
- android:bottomRightRadius="@dimen/component_color_chip_small_size_default" />
+ android:bottomRightRadius="@dimen/component_color_chip_small_radius_default" />
<size
- android:width="@dimen/component_color_chip_small_size_default"
- android:height="@dimen/component_color_chip_small_size_default" />
+ android:width="@dimen/component_color_chip_small_radius_default"
+ android:height="@dimen/component_color_chip_small_radius_default" />
<solid android:color="@android:color/black" />
</shape>
</item>
diff --git a/res/drawable/horizontal_divider_14dp.xml b/res/drawable/horizontal_divider_14dp.xml
new file mode 100644
index 0000000..c4c29cf
--- /dev/null
+++ b/res/drawable/horizontal_divider_14dp.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ 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">
+ <size
+ android:width="14dp"
+ android:height="0dp" />
+</shape>
diff --git a/res/drawable/keyguard_quick_affordance_icon_container_background.xml b/res/drawable/keyguard_quick_affordance_icon_container_background.xml
new file mode 100644
index 0000000..8bd8af4
--- /dev/null
+++ b/res/drawable/keyguard_quick_affordance_icon_container_background.xml
@@ -0,0 +1,20 @@
+<!--
+ 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
new file mode 100644
index 0000000..93a80eb
--- /dev/null
+++ b/res/drawable/keyguard_quick_affordance_icon_container_background_selected.xml
@@ -0,0 +1,34 @@
+<!--
+ 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/keyguard_quick_affordance_picker_background.xml
new file mode 100644
index 0000000..3a49d7a
--- /dev/null
+++ b/res/drawable/keyguard_quick_affordance_picker_background.xml
@@ -0,0 +1,20 @@
+<!--
+ 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="28dp" />
+ <solid android:color="@color/color_surface" />
+</shape>
diff --git a/res/drawable/keyguard_quick_affordance_slot_tab_background.xml b/res/drawable/keyguard_quick_affordance_slot_tab_background.xml
new file mode 100644
index 0000000..3fbced3
--- /dev/null
+++ b/res/drawable/keyguard_quick_affordance_slot_tab_background.xml
@@ -0,0 +1,20 @@
+<!--
+ 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="50dp" />
+ <solid android:color="@color/keyguard_quick_affordance_slot_tab_background_color" />
+</shape>
diff --git a/res/drawable/link_off.xml b/res/drawable/link_off.xml
new file mode 100644
index 0000000..f16a63f
--- /dev/null
+++ b/res/drawable/link_off.xml
@@ -0,0 +1,26 @@
+<?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.
+ ~
+ -->
+
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="@dimen/keyguard_quick_affordance_icon_size"
+ android:height="@dimen/keyguard_quick_affordance_icon_size"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
+ <path
+ android:fillColor="@android:color/white"
+ android:pathData="M14.39,11L16,12.61V11zM17,7h-4v1.9h4c1.71,0 3.1,1.39 3.1,3.1 0,1.27 -0.77,2.37 -1.87,2.84l1.4,1.4C21.05,15.36 22,13.79 22,12c0,-2.76 -2.24,-5 -5,-5zM2,4.27l3.11,3.11C3.29,8.12 2,9.91 2,12c0,2.76 2.24,5 5,5h4v-1.9H7c-1.71,0 -3.1,-1.39 -3.1,-3.1 0,-1.59 1.21,-2.9 2.76,-3.07L8.73,11H8v2h2.73L13,15.27V17h1.73l4.01,4.01 1.41,-1.41L3.41,2.86 2,4.27z"/>
+</vector>
diff --git a/res/drawable/option_border.xml b/res/drawable/option_border.xml
index 6a9d5e9..d0fde5c 100644
--- a/res/drawable/option_border.xml
+++ b/res/drawable/option_border.xml
@@ -14,7 +14,6 @@
limitations under the License.
-->
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
android:color="?android:attr/colorControlHighlight">
<item android:id="@android:id/mask">
<shape android:shape="rectangle">
@@ -24,7 +23,7 @@
</item>
<item>
<shape android:shape="rectangle">
- <solid android:color="?androidprv:attr/colorSurface"/>
+ <solid android:color="@color/color_surface"/>
<corners android:radius="@dimen/option_tile_radius" />
</shape>
</item>
diff --git a/res/drawable/option_border_color.xml b/res/drawable/option_border_color.xml
index ba5097b..cecb001 100644
--- a/res/drawable/option_border_color.xml
+++ b/res/drawable/option_border_color.xml
@@ -14,17 +14,16 @@
limitations under the License.
-->
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
android:color="?android:attr/colorControlHighlight">
<item android:id="@+id/systempalettecolor">
<shape android:shape="rectangle">
- <solid android:color="?androidprv:attr/colorSurface"/>
+ <solid android:color="@color/color_surface"/>
<corners android:radius="@dimen/option_tile_radius" />
</shape>
</item>
<item android:id="@android:id/mask">
<shape android:shape="rectangle">
- <solid android:color="?androidprv:attr/colorSurface"/>
+ <solid android:color="@color/color_surface"/>
<corners android:radius="@dimen/option_tile_radius" />
</shape>
</item>
diff --git a/res/drawable/option_border_new_selection.xml b/res/drawable/option_border_new_selection.xml
index 6c02caa..8045f17 100644
--- a/res/drawable/option_border_new_selection.xml
+++ b/res/drawable/option_border_new_selection.xml
@@ -14,7 +14,6 @@
limitations under the License.
-->
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
android:color="?android:attr/colorControlHighlight">
<item android:id="@android:id/mask">
<shape android:shape="rectangle">
diff --git a/res/drawable/selectable.xml b/res/drawable/selectable.xml
new file mode 100644
index 0000000..1364d68
--- /dev/null
+++ b/res/drawable/selectable.xml
@@ -0,0 +1,21 @@
+<?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.
+ ~
+ -->
+
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:state_selected="true" android:drawable="@drawable/selectable_selected" />
+ <item android:drawable="@android:color/transparent" />
+</selector>
diff --git a/res/drawable/selectable_selected.xml b/res/drawable/selectable_selected.xml
new file mode 100644
index 0000000..2ba8948
--- /dev/null
+++ b/res/drawable/selectable_selected.xml
@@ -0,0 +1,22 @@
+<?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.
+ ~
+ -->
+
+<shape xmlns:android="http://schemas.android.com/apk/res/android"
+ android:shape="rectangle">
+ <corners android:radius="8dp" />
+ <stroke android:width="2dp" android:color="@android:color/white" />
+</shape>
diff --git a/res/layout/check_circle_grey_large_not_select_background_color.xml b/res/layout/check_circle_grey_large_not_select_background_color.xml
index c023611..4a8a163 100644
--- a/res/layout/check_circle_grey_large_not_select_background_color.xml
+++ b/res/layout/check_circle_grey_large_not_select_background_color.xml
@@ -14,7 +14,6 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-<selector xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:androidprv="http://schemas.android.com/apk/prv/res/android">
- <item android:color="?androidprv:attr/textColorSecondaryInverse" />
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:color="@color/text_color_secondary_inverse" />
</selector>
\ No newline at end of file
diff --git a/res/layout/clock_section_view.xml b/res/layout/clock_section_view.xml
index d95e651..8512498 100644
--- a/res/layout/clock_section_view.xml
+++ b/res/layout/clock_section_view.xml
@@ -49,6 +49,7 @@
android:scaleType="center"
android:src="@drawable/ic_clock_24px"
android:background="@drawable/option_border_color"
- android:contentDescription="@string/clock_picker_entry_content_description" />
+ 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
diff --git a/res/layout/color_option.xml b/res/layout/color_option.xml
index 9bbfd7f..d9a7136 100644
--- a/res/layout/color_option.xml
+++ b/res/layout/color_option.xml
@@ -1,5 +1,4 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
+<?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");
@@ -14,50 +13,91 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
+<!-- Enclosing layout must be match_parent so that we can center content within -->
+<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="match_parent"
android:layout_height="wrap_content"
+ android:layout_gravity="center"
android:clipChildren="false"
- android:clipToPadding="false"
- android:orientation="vertical">
+ android:gravity="center"
+ android:padding="@dimen/option_tile_grid_tile_padding_min">
- <FrameLayout
- android:id="@+id/option_tile"
- android:layout_width="@dimen/option_tile_width"
- android:layout_height="@dimen/option_tile_width"
- android:layout_gravity="center_horizontal"
- android:background="@drawable/option_border_color">
- <ImageView
- android:id="@+id/color_preview_0"
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
+ <!--
+ This displays the background. It is dynamically sized, constrained remain square and
+ have a maximum size, and be centered within its parent.
+ -->
+ <androidx.constraintlayout.widget.ConstraintLayout
+ android:layout_width="0dp"
+ android:layout_height="0dp"
+ android:layout_gravity="center"
+ android:background="@drawable/option_border_color"
+ android:gravity="center"
+ android:padding="@dimen/option_tile_grid_icon_padding_min"
+ 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_max="@dimen/option_tile_width">
+
+ <!-- This is the color wheel itself, constrained to a maximum size and centered -->
+ <androidx.constraintlayout.widget.ConstraintLayout
+ android:id="@+id/option_tile"
+ android:layout_width="0dp"
+ android:layout_height="0dp"
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"/>
- <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"/>
- <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"/>
- <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"/>
- </FrameLayout>
-</FrameLayout>
+ android:gravity="center"
+ app:layout_constraintBottom_toBottomOf="parent"
+ app:layout_constraintEnd_toEndOf="parent"
+ app:layout_constraintHeight_max="@dimen/component_color_chip_small_diameter_default"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintTop_toTopOf="parent"
+ app:layout_constraintWidth_max="@dimen/component_color_chip_small_diameter_default">
+
+ <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>
+ </androidx.constraintlayout.widget.ConstraintLayout>
+</androidx.constraintlayout.widget.ConstraintLayout>
diff --git a/res/layout/fragment_lock_screen_quick_affordances.xml b/res/layout/fragment_lock_screen_quick_affordances.xml
new file mode 100644
index 0000000..331d501
--- /dev/null
+++ b/res/layout/fragment_lock_screen_quick_affordances.xml
@@ -0,0 +1,121 @@
+<?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="match_parent"
+ android:layout_height="match_parent"
+ android:orientation="vertical">
+
+ <FrameLayout
+ android:id="@+id/section_header_container"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content">
+
+ <include layout="@layout/section_header" />
+
+ </FrameLayout>
+
+ <com.android.wallpaper.picker.DisplayAspectRatioFrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="0dp"
+ android:layout_weight="1"
+ android:paddingTop="36dp"
+ android:paddingBottom="40dp">
+
+ <include
+ android:id="@+id/preview"
+ layout="@layout/wallpaper_preview_card"
+ android:layout_width="0dp"
+ android:layout_height="match_parent"
+ android:layout_gravity="center"/>
+
+ </com.android.wallpaper.picker.DisplayAspectRatioFrameLayout>
+
+ <LinearLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:orientation="vertical"
+ android:layout_marginHorizontal="24dp"
+ android:layout_marginBottom="28dp"
+ android:background="@drawable/keyguard_quick_affordance_picker_background"
+ android:paddingTop="22dp"
+ android:paddingBottom="62dp">
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ >
+
+ <androidx.recyclerview.widget.RecyclerView
+ android:id="@id/slot_tabs"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:clipToPadding="false"
+ android:paddingHorizontal="16dp" />
+
+ <!--
+ This is just an invisible placeholder put in place so that the parent keeps its height
+ stable as the RecyclerView updates from 0 items to N items. Keeping it stable allows the
+ layout logic to keep the size of the preview container stable as well, which bodes well
+ for setting up the SurfaceView for remote rendering without changing its size after the
+ content is loaded into the RecyclerView.
+
+ It's critical for any TextViews inside the included layout to have text.
+ -->
+ <include
+ layout="@layout/keyguard_quick_affordance_slot_tab"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:visibility="invisible" />
+
+ </FrameLayout>
+
+ <View
+ android:layout_width="0dp"
+ android:layout_height="22dp" />
+
+ <FrameLayout
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content">
+
+ <androidx.recyclerview.widget.RecyclerView
+ android:id="@id/affordances"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:clipToPadding="false"
+ android:paddingHorizontal="16dp" />
+
+ <!--
+ This is just an invisible placeholder put in place so that the parent keeps its height
+ stable as the RecyclerView updates from 0 items to N items. Keeping it stable allows the
+ layout logic to keep the size of the preview container stable as well, which bodes well
+ for setting up the SurfaceView for remote rendering without changing its size after the
+ content is loaded into the RecyclerView.
+
+ It's critical for any TextViews inside the included layout to have text.
+ -->
+ <include
+ layout="@layout/keyguard_quick_affordance"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:visibility="invisible" />
+
+ </FrameLayout>
+
+ </LinearLayout>
+
+</LinearLayout>
diff --git a/res/layout/keyguard_quick_affordance.xml b/res/layout/keyguard_quick_affordance.xml
new file mode 100644
index 0000000..b3b6893
--- /dev/null
+++ b/res/layout/keyguard_quick_affordance.xml
@@ -0,0 +1,55 @@
+<?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"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:layout_width="@dimen/keyguard_quick_affordance_picker_item_width"
+ android:layout_height="wrap_content"
+ android:orientation="vertical"
+ android:gravity="center_horizontal">
+
+ <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" >
+
+ <ImageView
+ android:id="@+id/icon"
+ android:layout_width="@dimen/keyguard_quick_affordance_icon_size"
+ android:layout_height="@dimen/keyguard_quick_affordance_icon_size"
+ android:layout_gravity="center"
+ android:tint="@color/text_color_primary" />
+
+ </FrameLayout>
+
+ <View
+ android:layout_width="0dp"
+ android:layout_height="8dp" />
+
+ <TextView
+ android:id="@+id/name"
+ 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>
\ No newline at end of file
diff --git a/res/layout/keyguard_quick_affordance_enablement_dialog.xml b/res/layout/keyguard_quick_affordance_enablement_dialog.xml
new file mode 100644
index 0000000..d6ba105
--- /dev/null
+++ b/res/layout/keyguard_quick_affordance_enablement_dialog.xml
@@ -0,0 +1,59 @@
+<?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/keyguard_quick_affordance_section_view.xml b/res/layout/keyguard_quick_affordance_section_view.xml
new file mode 100644
index 0000000..458f659
--- /dev/null
+++ b/res/layout/keyguard_quick_affordance_section_view.xml
@@ -0,0 +1,73 @@
+<?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.quickaffordance.ui.view.KeyguardQuickAffordanceSectionView
+ 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="horizontal">
+
+ <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/keyguard_quick_affordance_section_title"
+ style="@style/SectionTitleTextStyle" />
+
+ <TextView
+ android:id="@+id/keyguard_quick_affordance_description"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ style="@style/SectionSubtitleTextStyle"/>
+ </LinearLayout>
+
+ <LinearLayout
+ android:layout_width="@dimen/option_tile_width"
+ android:layout_height="@dimen/option_tile_width"
+ android:orientation="horizontal"
+ android:background="@drawable/option_border_color"
+ android:importantForAccessibility="noHideDescendants"
+ android:gravity="center"
+ android:divider="@drawable/horizontal_divider_14dp"
+ android:showDividers="middle">
+
+ <ImageView
+ android:id="@+id/icon_1"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:visibility="gone"
+ android:tint="@color/text_color_primary" />
+
+ <ImageView
+ android:id="@+id/icon_2"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:visibility="gone"
+ android:tint="@color/text_color_primary" />
+
+ </LinearLayout>
+
+
+</com.android.customization.picker.quickaffordance.ui.view.KeyguardQuickAffordanceSectionView>
\ No newline at end of file
diff --git a/res/layout/keyguard_quick_affordance_slot_tab.xml b/res/layout/keyguard_quick_affordance_slot_tab.xml
new file mode 100644
index 0000000..c4934d8
--- /dev/null
+++ b/res/layout/keyguard_quick_affordance_slot_tab.xml
@@ -0,0 +1,32 @@
+<?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.
+ ~
+ -->
+
+<TextView
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ 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:paddingVertical="8dp"
+ android:paddingHorizontal="16dp"
+ android:minWidth="48dp"
+ android:minHeight="48dp"
+ android:gravity="center"
+ android:background="@drawable/keyguard_quick_affordance_slot_tab_background"
+ android:text="Placeholder for stable size calculation, please do not remove."
+ tools:ignore="HardcodedText" />
diff --git a/res/layout/themed_icon_section_view.xml b/res/layout/themed_icon_section_view.xml
index a195e23..2ca84a9 100644
--- a/res/layout/themed_icon_section_view.xml
+++ b/res/layout/themed_icon_section_view.xml
@@ -16,7 +16,6 @@
-->
<com.android.customization.picker.themedicon.ThemedIconSectionView
xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="?selectableItemBackground"
diff --git a/res/values-af/strings.xml b/res/values-af/strings.xml
index 9cda091..6f73a7b 100644
--- a/res/values-af/strings.xml
+++ b/res/values-af/strings.xml
@@ -91,4 +91,15 @@
<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 8a8a533..33cb057 100644
--- a/res/values-am/strings.xml
+++ b/res/values-am/strings.xml
@@ -91,4 +91,15 @@
<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 50ed34d..0186d7e 100644
--- a/res/values-ar/strings.xml
+++ b/res/values-ar/strings.xml
@@ -91,4 +91,15 @@
<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 74fd947..c0106bd 100644
--- a/res/values-as/strings.xml
+++ b/res/values-as/strings.xml
@@ -91,4 +91,15 @@
<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 79ecb46..e97ce3c 100644
--- a/res/values-az/strings.xml
+++ b/res/values-az/strings.xml
@@ -91,4 +91,15 @@
<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ç bir"</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ç bir"</string>
</resources>
diff --git a/res/values-b+sr+Latn/strings.xml b/res/values-b+sr+Latn/strings.xml
index 713cea8..cfc988f 100644
--- a/res/values-b+sr+Latn/strings.xml
+++ b/res/values-b+sr+Latn/strings.xml
@@ -91,4 +91,15 @@
<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 d23f607..7c75af1 100644
--- a/res/values-be/strings.xml
+++ b/res/values-be/strings.xml
@@ -91,4 +91,15 @@
<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 21d5ac0..898aab8 100644
--- a/res/values-bg/strings.xml
+++ b/res/values-bg/strings.xml
@@ -91,4 +91,15 @@
<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 25241a8..7d8cea7 100644
--- a/res/values-bn/strings.xml
+++ b/res/values-bn/strings.xml
@@ -91,4 +91,15 @@
<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 901ac78..edff91b 100644
--- a/res/values-bs/strings.xml
+++ b/res/values-bs/strings.xml
@@ -91,4 +91,15 @@
<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 fa26aa9..3cfcce6 100644
--- a/res/values-ca/strings.xml
+++ b/res/values-ca/strings.xml
@@ -91,4 +91,15 @@
<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 5bee171..43f3c4d 100644
--- a/res/values-cs/strings.xml
+++ b/res/values-cs/strings.xml
@@ -91,4 +91,15 @@
<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 46f319b..1254892 100644
--- a/res/values-da/strings.xml
+++ b/res/values-da/strings.xml
@@ -91,4 +91,15 @@
<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 3bc3532..bb95b3d 100644
--- a/res/values-de/strings.xml
+++ b/res/values-de/strings.xml
@@ -91,4 +91,15 @@
<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 5fe9043..8bf703a 100644
--- a/res/values-el/strings.xml
+++ b/res/values-el/strings.xml
@@ -91,4 +91,15 @@
<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 6a8ca3d..7a8b69a 100644
--- a/res/values-en-rAU/strings.xml
+++ b/res/values-en-rAU/strings.xml
@@ -91,4 +91,15 @@
<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 6a8ca3d..5025853 100644
--- a/res/values-en-rCA/strings.xml
+++ b/res/values-en-rCA/strings.xml
@@ -91,4 +91,26 @@
<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 6a8ca3d..7a8b69a 100644
--- a/res/values-en-rGB/strings.xml
+++ b/res/values-en-rGB/strings.xml
@@ -91,4 +91,15 @@
<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 6a8ca3d..7a8b69a 100644
--- a/res/values-en-rIN/strings.xml
+++ b/res/values-en-rIN/strings.xml
@@ -91,4 +91,15 @@
<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 0dea21b..a009b89 100644
--- a/res/values-en-rXC/strings.xml
+++ b/res/values-en-rXC/strings.xml
@@ -91,4 +91,15 @@
<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 c6e1938..1f6dace 100644
--- a/res/values-es-rUS/strings.xml
+++ b/res/values-es-rUS/strings.xml
@@ -91,4 +91,15 @@
<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 6aceec2..ad64ee2 100644
--- a/res/values-es/strings.xml
+++ b/res/values-es/strings.xml
@@ -91,4 +91,15 @@
<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 bad77e8..210dbc7 100644
--- a/res/values-et/strings.xml
+++ b/res/values-et/strings.xml
@@ -91,4 +91,15 @@
<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 b7e748c..0c36cb4 100644
--- a/res/values-eu/strings.xml
+++ b/res/values-eu/strings.xml
@@ -91,4 +91,15 @@
<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 1d3a43a..5f38e44 100644
--- a/res/values-fa/strings.xml
+++ b/res/values-fa/strings.xml
@@ -91,4 +91,15 @@
<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 61047d8..2459a6f 100644
--- a/res/values-fi/strings.xml
+++ b/res/values-fi/strings.xml
@@ -91,4 +91,15 @@
<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 0d0d44d..3483dc2 100644
--- a/res/values-fr-rCA/strings.xml
+++ b/res/values-fr-rCA/strings.xml
@@ -91,4 +91,15 @@
<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 c87878d..e7925c9 100644
--- a/res/values-fr/strings.xml
+++ b/res/values-fr/strings.xml
@@ -91,4 +91,15 @@
<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 0f9743d..444235d 100644
--- a/res/values-gl/strings.xml
+++ b/res/values-gl/strings.xml
@@ -91,4 +91,15 @@
<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 4f501b2..38d7546 100644
--- a/res/values-gu/strings.xml
+++ b/res/values-gu/strings.xml
@@ -91,4 +91,15 @@
<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 0b0b8b7..5f68098 100644
--- a/res/values-hi/strings.xml
+++ b/res/values-hi/strings.xml
@@ -91,4 +91,15 @@
<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 bb33da1..88d0f50 100644
--- a/res/values-hr/strings.xml
+++ b/res/values-hr/strings.xml
@@ -91,4 +91,15 @@
<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 b814c0c..6f52030 100644
--- a/res/values-hu/strings.xml
+++ b/res/values-hu/strings.xml
@@ -91,4 +91,15 @@
<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 b3d5829..d8e3da4 100644
--- a/res/values-hy/strings.xml
+++ b/res/values-hy/strings.xml
@@ -91,4 +91,15 @@
<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 ffbfdbd..27bd725 100644
--- a/res/values-in/strings.xml
+++ b/res/values-in/strings.xml
@@ -91,4 +91,15 @@
<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 96f78b2..c0dd203 100644
--- a/res/values-is/strings.xml
+++ b/res/values-is/strings.xml
@@ -91,4 +91,15 @@
<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 1e24a3f..0403b12 100644
--- a/res/values-it/strings.xml
+++ b/res/values-it/strings.xml
@@ -91,4 +91,15 @@
<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 4f3556f..6cc8e61 100644
--- a/res/values-iw/strings.xml
+++ b/res/values-iw/strings.xml
@@ -91,4 +91,15 @@
<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 7eafb66..6ddd7ae 100644
--- a/res/values-ja/strings.xml
+++ b/res/values-ja/strings.xml
@@ -91,4 +91,15 @@
<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 a6b91ec..892779f 100644
--- a/res/values-ka/strings.xml
+++ b/res/values-ka/strings.xml
@@ -91,4 +91,15 @@
<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 abee0ba..7e85152 100644
--- a/res/values-kk/strings.xml
+++ b/res/values-kk/strings.xml
@@ -91,4 +91,15 @@
<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 eb1dca6..7c6d39b 100644
--- a/res/values-km/strings.xml
+++ b/res/values-km/strings.xml
@@ -91,4 +91,15 @@
<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 f1b6efe..c5ddca1 100644
--- a/res/values-kn/strings.xml
+++ b/res/values-kn/strings.xml
@@ -91,4 +91,15 @@
<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 ef1e573..d154cbf 100644
--- a/res/values-ko/strings.xml
+++ b/res/values-ko/strings.xml
@@ -91,4 +91,15 @@
<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 e292d1e..5dcfa46 100644
--- a/res/values-ky/strings.xml
+++ b/res/values-ky/strings.xml
@@ -91,4 +91,15 @@
<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 c70c1e7..63235c9 100644
--- a/res/values-lo/strings.xml
+++ b/res/values-lo/strings.xml
@@ -91,4 +91,15 @@
<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 2075eda..5722acd 100644
--- a/res/values-lt/strings.xml
+++ b/res/values-lt/strings.xml
@@ -91,4 +91,15 @@
<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 2c89c6d..b30a850 100644
--- a/res/values-lv/strings.xml
+++ b/res/values-lv/strings.xml
@@ -91,4 +91,15 @@
<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 b81d472..ffac0f4 100644
--- a/res/values-mk/strings.xml
+++ b/res/values-mk/strings.xml
@@ -91,4 +91,15 @@
<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 704dc54..60e4404 100644
--- a/res/values-ml/strings.xml
+++ b/res/values-ml/strings.xml
@@ -91,4 +91,15 @@
<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 d7c8034..29c7341 100644
--- a/res/values-mn/strings.xml
+++ b/res/values-mn/strings.xml
@@ -91,4 +91,15 @@
<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 f889992..298bcbc 100644
--- a/res/values-mr/strings.xml
+++ b/res/values-mr/strings.xml
@@ -91,4 +91,15 @@
<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 54e1b8b..96c5bc8 100644
--- a/res/values-ms/strings.xml
+++ b/res/values-ms/strings.xml
@@ -91,4 +91,15 @@
<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 9d5a12b..000d598 100644
--- a/res/values-my/strings.xml
+++ b/res/values-my/strings.xml
@@ -84,11 +84,22 @@
<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="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 c5baa00..9ba98f8 100644
--- a/res/values-nb/strings.xml
+++ b/res/values-nb/strings.xml
@@ -91,4 +91,15 @@
<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 b616454..e8862fe 100644
--- a/res/values-ne/strings.xml
+++ b/res/values-ne/strings.xml
@@ -91,4 +91,15 @@
<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 58d73e4..27397ec 100644
--- a/res/values-nl/strings.xml
+++ b/res/values-nl/strings.xml
@@ -91,4 +91,15 @@
<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 bc27705..9ce4e96 100644
--- a/res/values-or/strings.xml
+++ b/res/values-or/strings.xml
@@ -91,4 +91,15 @@
<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 e7168d7..393e4cf 100644
--- a/res/values-pa/strings.xml
+++ b/res/values-pa/strings.xml
@@ -91,4 +91,15 @@
<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 fa7a7ba..7496cd4 100644
--- a/res/values-pl/strings.xml
+++ b/res/values-pl/strings.xml
@@ -91,4 +91,15 @@
<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 ee1d738..1966564 100644
--- a/res/values-pt-rPT/strings.xml
+++ b/res/values-pt-rPT/strings.xml
@@ -91,4 +91,15 @@
<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 cd09d6a..e977269 100644
--- a/res/values-pt/strings.xml
+++ b/res/values-pt/strings.xml
@@ -91,4 +91,15 @@
<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 1f5aa49..6ccbbca 100644
--- a/res/values-ro/strings.xml
+++ b/res/values-ro/strings.xml
@@ -91,4 +91,15 @@
<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 9790be2..16567be 100644
--- a/res/values-ru/strings.xml
+++ b/res/values-ru/strings.xml
@@ -91,4 +91,15 @@
<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 ab6b828..05c1840 100644
--- a/res/values-si/strings.xml
+++ b/res/values-si/strings.xml
@@ -91,4 +91,15 @@
<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 5b78df5..9deb70e 100644
--- a/res/values-sk/strings.xml
+++ b/res/values-sk/strings.xml
@@ -91,4 +91,15 @@
<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 7b9e67a..218605a 100644
--- a/res/values-sl/strings.xml
+++ b/res/values-sl/strings.xml
@@ -91,4 +91,15 @@
<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 a4ecd13..5b8ad1c 100644
--- a/res/values-sq/strings.xml
+++ b/res/values-sq/strings.xml
@@ -91,4 +91,15 @@
<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 61a99a8..8fbb505 100644
--- a/res/values-sr/strings.xml
+++ b/res/values-sr/strings.xml
@@ -91,4 +91,15 @@
<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 8fb2165..5395735 100644
--- a/res/values-sv/strings.xml
+++ b/res/values-sv/strings.xml
@@ -91,4 +91,15 @@
<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 f093c1e..88fca60 100644
--- a/res/values-sw/strings.xml
+++ b/res/values-sw/strings.xml
@@ -83,7 +83,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 mada"</string>
+ <string name="themed_icon_title" msgid="7312460430471956558">"Aikoni zenye mitindo"</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,4 +91,15 @@
<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 e611b64..2be8940 100644
--- a/res/values-ta/strings.xml
+++ b/res/values-ta/strings.xml
@@ -91,4 +91,15 @@
<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 10a83cb..9e1829d 100644
--- a/res/values-te/strings.xml
+++ b/res/values-te/strings.xml
@@ -56,7 +56,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 +64,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,4 +91,15 @@
<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 8e5956e..101675d 100644
--- a/res/values-th/strings.xml
+++ b/res/values-th/strings.xml
@@ -91,4 +91,15 @@
<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 72a5dc7..3413b27 100644
--- a/res/values-tl/strings.xml
+++ b/res/values-tl/strings.xml
@@ -91,4 +91,15 @@
<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 ef52c16..864a1c2 100644
--- a/res/values-tr/strings.xml
+++ b/res/values-tr/strings.xml
@@ -91,4 +91,15 @@
<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 c7660dc..6409fbf 100644
--- a/res/values-uk/strings.xml
+++ b/res/values-uk/strings.xml
@@ -91,4 +91,15 @@
<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 a339231..a5a05b6 100644
--- a/res/values-ur/strings.xml
+++ b/res/values-ur/strings.xml
@@ -91,4 +91,15 @@
<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 d3fc6a8..78f5c63 100644
--- a/res/values-uz/strings.xml
+++ b/res/values-uz/strings.xml
@@ -91,4 +91,15 @@
<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 1489048..6ed629a 100644
--- a/res/values-vi/strings.xml
+++ b/res/values-vi/strings.xml
@@ -91,4 +91,15 @@
<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-w600dp-port/dimens.xml b/res/values-w600dp-port/dimens.xml
index ba92746..62a9946 100644
--- a/res/values-w600dp-port/dimens.xml
+++ b/res/values-w600dp-port/dimens.xml
@@ -17,8 +17,9 @@
<resources>
<!-- Dimensions for the customization option tiles -->
<dimen name="option_tile_width">79dp</dimen>
- <dimen name="option_tile_grid_padding_horizontal">8dp</dimen>
+ <dimen name="option_tile_linear_padding_horizontal">8dp</dimen>
- <dimen name="component_color_chip_small_size_default">30dp</dimen>
+ <dimen name="component_color_chip_small_radius_default">30dp</dimen>
+ <dimen name="component_color_chip_small_diameter_default">60dp</dimen>
<dimen name="color_seed_chip_margin">15dp</dimen>
</resources>
diff --git a/res/values-w800dp/dimens.xml b/res/values-w800dp/dimens.xml
index 4cd6242..6ba900e 100644
--- a/res/values-w800dp/dimens.xml
+++ b/res/values-w800dp/dimens.xml
@@ -17,5 +17,5 @@
<resources>
<!-- Dimensions for the customization option tiles -->
<dimen name="option_tile_width">87dp</dimen>
- <dimen name="option_tile_grid_padding_horizontal">8dp</dimen>
+ <dimen name="option_tile_linear_padding_horizontal">8dp</dimen>
</resources>
\ No newline at end of file
diff --git a/res/values-zh-rCN/strings.xml b/res/values-zh-rCN/strings.xml
index 654da3a..58b8a2a 100644
--- a/res/values-zh-rCN/strings.xml
+++ b/res/values-zh-rCN/strings.xml
@@ -91,4 +91,15 @@
<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 a06494b..017a0be 100644
--- a/res/values-zh-rHK/strings.xml
+++ b/res/values-zh-rHK/strings.xml
@@ -91,4 +91,15 @@
<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 6c7dbb5..09f59bb 100644
--- a/res/values-zh-rTW/strings.xml
+++ b/res/values-zh-rTW/strings.xml
@@ -91,4 +91,15 @@
<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 ebdf004..e4993c7 100644
--- a/res/values-zu/strings.xml
+++ b/res/values-zu/strings.xml
@@ -91,4 +91,15 @@
<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/dimens.xml b/res/values/dimens.xml
index d5dbb00..59903de 100644
--- a/res/values/dimens.xml
+++ b/res/values/dimens.xml
@@ -39,7 +39,12 @@
<dimen name="option_tile_margin_horizontal">6dp</dimen>
<dimen name="option_tile_padding_vertical">12dp</dimen>
<dimen name="option_tile_padding_horizontal">12dp</dimen>
- <dimen name="option_tile_grid_padding_horizontal">4dp</dimen>
+ <!-- Spacing between tiles in linear layout -->
+ <dimen name="option_tile_linear_padding_horizontal">4dp</dimen>
+ <!-- Minimum padding around entire tile in grid layout -->
+ <dimen name="option_tile_grid_tile_padding_min">2dp</dimen>
+ <!-- Minimum padding around icon within tile in grid layout -->
+ <dimen name="option_tile_grid_icon_padding_min">4dp</dimen>
<dimen name="option_icon_size">16dp</dimen>
<dimen name="theme_option_icon_sample_height">22dp</dimen>
<dimen name="theme_option_icon_sample_width">22dp</dimen>
@@ -132,8 +137,15 @@
<!-- For the color page. -->
<dimen name="color_page_indicator_margin_top">16dp</dimen>
- <dimen name="component_color_chip_small_size_default">29dp</dimen>
- <dimen name="color_seed_option_tile_padding">10dp</dimen>
- <dimen name="color_seed_option_tile_padding_selected">6dp</dimen>
+ <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>
+
+ <!-- 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>
</resources>
diff --git a/res/values/ids.xml b/res/values/ids.xml
new file mode 100644
index 0000000..1ed004d
--- /dev/null
+++ b/res/values/ids.xml
@@ -0,0 +1,23 @@
+<?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>
+ <item name="start_affordance" type="id" />
+ <item name="end_affordance" type="id" />
+ <item name="slot_tabs" type="id" />
+ <item name="affordances" type="id" />
+</resources>
diff --git a/res/values/strings.xml b/res/values/strings.xml
index 7aef401..13fc8a0 100755
--- a/res/values/strings.xml
+++ b/res/values/strings.xml
@@ -267,4 +267,81 @@
<!-- 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>
+
+ <!--
+ 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].
+ -->
+ <string name="keyguard_slot_name_bottom_start">Left button</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].
+ -->
+ <string name="keyguard_slot_name_bottom_end">Right button</string>
+
+ <!--
+ Name for an option to have no quick affordance selected for one of the sides of the lock
+ screen. We show this as an option in a settings experience, where users get to choose which
+ quick affordances (or buttons) are available on their device's lock screen. [CHAR LIMIT=10].
+ -->
+ <string name="keyguard_affordance_none">None</string>
+
+ <!--
+ Title for a popup dialog shown when the user attempts to select an option that is not currently
+ enabled. The dialog contains a list of instructions that the user needs to take in order to
+ enable the option before it can be selected again. [CHAR LIMIT=NONE].
+ -->
+ <string name="keyguard_affordance_enablement_dialog_title">To select `<xliff:g id="appName" example="Wallet">%1$s</xliff:g>` check the following</string>
+
+ <!--
+ Template for an action that opens a specific app. [CHAR LIMIT=16]
+ -->
+ <string name="keyguard_affordance_enablement_dialog_action_template">Open <xliff:g id="appName" example="Wallet">%1$s</xliff:g></string>
+
+ <!--
+ Template for a message shown right before a list of instructions that tell the user what to do
+ in order to enable a shortcut to a specific app. [CHAR LIMIT=NONE]
+ -->
+ <string name="keyguard_affordance_enablement_dialog_message">To add the <xliff:g id="appName" example="Wallet">%1$s</xliff:g> app as a shortcut, make sure</string>
+
+ <!--
+ Label for button in a dialog shown to the user with a list of instructions that the user should
+ follow in order to make a piece of functionality available as a lock screen quick affordance.
+ [CHAR LIMIT=10].
+ -->
+ <string name="keyguard_affordance_enablement_dialog_dismiss_button">Done</string>
+
+ <!--
+ Title for a screen where the user can configure the lock screen shortcut buttons that appear on
+ the device without unlocking.
+ [CHAR LIMIT=32].
+ -->
+ <string name="keyguard_quick_affordance_title">Shortcuts</string>
+
+ <!--
+ Label for a menu item on a settings screen that helps the user open a new screen where they can
+ configure the lock screen shortcut buttons that appear on the device without unlocking.
+ [CHAR LIMIT=16].
+ -->
+ <string name="keyguard_quick_affordance_section_title">Shortcuts</string>
+
+ <!--
+ Template for text that shows the names of two currently-selected lock screen shortcuts on the
+ lock screen. For example, it may say "Camera, Wallet", if the first selected shortcut opens the
+ camera app and the second one opens the tap-to-pay wallet experience.
+ [CHAR LIMIT=60].
+ -->
+ <string name="keyguard_quick_affordance_two_selected_template"><xliff:g id="first">%1$s</xliff:g>, <xliff:g id="second">%2$s</xliff:g></string>
+
+ <!--
+ Placeholder text that shows when no lock screen shortcuts are currently selected on the lock
+ screen. When selected, "None" is replaced by another string that shows what is currently
+ selected. For example, it may say "Camera, Wallet", if the first selected shortcut opens the
+ camera app and the second one opens the tap-to-pay wallet experience.
+ [CHAR LIMIT=60].
+ -->
+ <string name="keyguard_quick_affordance_none_selected">None</string>
</resources>
diff --git a/robolectric_tests/Android.mk b/robolectric_tests/Android.mk
deleted file mode 100644
index 7d9b0e1..0000000
--- a/robolectric_tests/Android.mk
+++ /dev/null
@@ -1,59 +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.
-
-#############################################
-# ThenePicker Robolectric test target. #
-#############################################
-LOCAL_PATH := $(call my-dir)
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := ThemePickerRoboTests
-LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0
-LOCAL_LICENSE_CONDITIONS := notice
-LOCAL_SDK_VERSION := system_current
-LOCAL_SRC_FILES := $(call all-java-files-under, src)
-LOCAL_STATIC_JAVA_LIBRARIES := \
- androidx.test.runner \
- androidx.test.rules \
- mockito-robolectric-prebuilt \
- truth-prebuilt
-LOCAL_JAVA_LIBRARIES := \
- platform-robolectric-4.5.1-prebuilt
-
-LOCAL_JAVA_RESOURCE_DIRS := config
-
-LOCAL_INSTRUMENTATION_FOR := ThemePicker
-LOCAL_MODULE_TAGS := optional
-
-include $(BUILD_STATIC_JAVA_LIBRARY)
-
-############################################
-# Target to run the previous target. #
-############################################
-include $(CLEAR_VARS)
-
-LOCAL_MODULE := RunThemePickerRoboTests
-LOCAL_LICENSE_KINDS := SPDX-license-identifier-Apache-2.0
-LOCAL_LICENSE_CONDITIONS := notice
-LOCAL_SDK_VERSION := system_current
-LOCAL_JAVA_LIBRARIES := \
- ThemePickerRoboTests
-
-LOCAL_TEST_PACKAGE := ThemePicker
-
-LOCAL_INSTRUMENT_SOURCE_DIRS := packages/apps/ThemePicker/src \
-
-LOCAL_ROBOTEST_TIMEOUT := 36000
-
-include prebuilts/misc/common/robolectric/3.6.2/run_robotests.mk
diff --git a/robolectric_tests/config/robolectric.properties b/robolectric_tests/config/robolectric.properties
deleted file mode 100644
index 6c518c0..0000000
--- a/robolectric_tests/config/robolectric.properties
+++ /dev/null
@@ -1,2 +0,0 @@
-manifest=packages/apps/ThemePicker/AndroidManifest.xml
-sdk=31
diff --git a/robolectric_tests/robolectric_gradle_config/robolectric.properties b/robolectric_tests/robolectric_gradle_config/robolectric.properties
deleted file mode 100644
index 2916ca9..0000000
--- a/robolectric_tests/robolectric_gradle_config/robolectric.properties
+++ /dev/null
@@ -1,3 +0,0 @@
-# Do not include the manifest definition in this version
-# as it is specified directly in the gradle file
-sdk=31
\ No newline at end of file
diff --git a/src/com/android/customization/model/clock/ClockSectionController.java b/src/com/android/customization/model/clock/ClockSectionController.java
deleted file mode 100644
index 8f98b88..0000000
--- a/src/com/android/customization/model/clock/ClockSectionController.java
+++ /dev/null
@@ -1,51 +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 androidx.annotation.Nullable;
-
-import com.android.customization.picker.clock.ClockCustomFragment;
-import com.android.customization.picker.clock.ClockSectionView;
-import com.android.wallpaper.R;
-import com.android.wallpaper.config.Flags;
-import com.android.wallpaper.model.CustomizationSectionController;
-
-/** A {@link CustomizationSectionController} for clock customization. */
-public class ClockSectionController implements CustomizationSectionController<ClockSectionView> {
-
- private final CustomizationSectionNavigationController mNavigationController;
-
- public ClockSectionController(CustomizationSectionNavigationController navigationController) {
- mNavigationController = navigationController;
- }
-
- @Override
- public boolean isAvailable(@Nullable Context context) {
- return Flags.enableClockCustomization;
- }
-
- @Override
- public ClockSectionView createView(Context context) {
- ClockSectionView view = (ClockSectionView) LayoutInflater.from(context).inflate(
- R.layout.clock_section_view,
- null);
- view.setOnClickListener(v -> mNavigationController.navigateTo(new ClockCustomFragment()));
- return view;
- }
-}
diff --git a/src/com/android/customization/model/clock/ClockSectionController.kt b/src/com/android/customization/model/clock/ClockSectionController.kt
new file mode 100644
index 0000000..1e339bb
--- /dev/null
+++ b/src/com/android/customization/model/clock/ClockSectionController.kt
@@ -0,0 +1,50 @@
+/*
+ * 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/ColorBundle.java b/src/com/android/customization/model/color/ColorBundle.java
index dc5a367..d34f3fc 100644
--- a/src/com/android/customization/model/color/ColorBundle.java
+++ b/src/com/android/customization/model/color/ColorBundle.java
@@ -15,18 +15,11 @@
*/
package com.android.customization.model.color;
-import static com.android.customization.model.ResourceConstants.PATH_SIZE;
-
import android.content.Context;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.graphics.Color;
-import android.graphics.Path;
import android.graphics.PorterDuff;
-import android.graphics.drawable.Drawable;
-import android.graphics.drawable.ShapeDrawable;
-import android.graphics.drawable.shapes.PathShape;
-import android.text.TextUtils;
import android.view.View;
import android.widget.ImageView;
@@ -34,16 +27,13 @@
import androidx.annotation.Dimension;
import androidx.annotation.NonNull;
import androidx.annotation.VisibleForTesting;
-import androidx.core.graphics.PathParser;
import com.android.customization.model.ResourceConstants;
import com.android.systemui.monet.Style;
import com.android.wallpaper.R;
-import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
-import java.util.List;
import java.util.Map;
/**
@@ -65,15 +55,11 @@
Resources res = view.getContext().getResources();
int primaryColor = mPreviewInfo.resolvePrimaryColor(res);
int secondaryColor = mPreviewInfo.resolveSecondaryColor(res);
- int padding = view.isActivated()
- ? res.getDimensionPixelSize(R.dimen.color_seed_option_tile_padding_selected)
- : res.getDimensionPixelSize(R.dimen.color_seed_option_tile_padding);
for (int i = 0; i < mPreviewColorIds.length; i++) {
ImageView colorPreviewImageView = view.findViewById(mPreviewColorIds[i]);
int color = i % 2 == 0 ? primaryColor : secondaryColor;
colorPreviewImageView.getDrawable().setColorFilter(color, PorterDuff.Mode.SRC);
- colorPreviewImageView.setPadding(padding, padding, padding, padding);
}
view.setContentDescription(getContentDescription(view.getContext()));
}
@@ -103,8 +89,6 @@
// Monet system palette and accent colors
@ColorInt public final int primaryColorLight;
@ColorInt public final int primaryColorDark;
- public final List<Drawable> icons;
- public final Drawable shapeDrawable;
@Dimension
public final int bottomSheetCornerRadius;
@@ -115,14 +99,11 @@
private PreviewInfo(
int secondaryColorLight, int secondaryColorDark, int colorSystemPaletteLight,
- int primaryColorDark, List<Drawable> icons, Drawable shapeDrawable,
- @Dimension int cornerRadius) {
+ int primaryColorDark, @Dimension int cornerRadius) {
this.secondaryColorLight = secondaryColorLight;
this.secondaryColorDark = secondaryColorDark;
this.primaryColorLight = colorSystemPaletteLight;
this.primaryColorDark = primaryColorDark;
- this.icons = icons;
- this.shapeDrawable = shapeDrawable;
this.bottomSheetCornerRadius = cornerRadius;
}
@@ -188,7 +169,6 @@
// System and Monet colors
@ColorInt private int mPrimaryColorLight = Color.TRANSPARENT;
@ColorInt private int mPrimaryColorDark = Color.TRANSPARENT;
- private List<Drawable> mIcons = new ArrayList<>();
private boolean mIsDefault;
private Style mStyle = Style.TONAL_SPOT;
private int mIndex;
@@ -213,26 +193,12 @@
* @return the {@link PreviewInfo} object
*/
public PreviewInfo createPreviewInfo(@NonNull Context context) {
- ShapeDrawable shapeDrawable = null;
Resources system = context.getResources().getSystem();
- String pathString = system.getString(
- system.getIdentifier(ResourceConstants.CONFIG_ICON_MASK,
- "string", ResourceConstants.ANDROID_PACKAGE));
- Path path = null;
- if (!TextUtils.isEmpty(pathString)) {
- path = PathParser.createPathFromPathData(pathString);
- }
- if (path != null) {
- PathShape shape = new PathShape(path, PATH_SIZE, PATH_SIZE);
- shapeDrawable = new ShapeDrawable(shape);
- shapeDrawable.setIntrinsicHeight((int) PATH_SIZE);
- shapeDrawable.setIntrinsicWidth((int) PATH_SIZE);
- }
return new PreviewInfo(mSecondaryColorLight,
- mSecondaryColorDark, mPrimaryColorLight, mPrimaryColorDark, mIcons,
- shapeDrawable, system.getDimensionPixelOffset(
- system.getIdentifier(ResourceConstants.CONFIG_CORNERRADIUS,
- "dimen", ResourceConstants.ANDROID_PACKAGE)));
+ mSecondaryColorDark, mPrimaryColorLight, mPrimaryColorDark,
+ system.getDimensionPixelOffset(
+ system.getIdentifier(ResourceConstants.CONFIG_CORNERRADIUS, "dimen",
+ ResourceConstants.ANDROID_PACKAGE)));
}
public Map<String, String> getPackages() {
@@ -298,16 +264,6 @@
}
/**
- * Sets icon for bundle
- * @param icon icon in {@link Drawable}
- * @return this of {@link Builder}
- */
- public Builder addIcon(Drawable icon) {
- mIcons.add(icon);
- return this;
- }
-
- /**
* Sets overlay package for bundle
* @param category the category of bundle
* @param packageName tha name of package in the category
diff --git a/src/com/android/customization/model/color/ColorBundlePreviewExtractor.java b/src/com/android/customization/model/color/ColorBundlePreviewExtractor.java
index b67eec8..55b637f 100644
--- a/src/com/android/customization/model/color/ColorBundlePreviewExtractor.java
+++ b/src/com/android/customization/model/color/ColorBundlePreviewExtractor.java
@@ -15,18 +15,12 @@
*/
package com.android.customization.model.color;
-import static com.android.customization.model.ResourceConstants.ANDROID_PACKAGE;
-import static com.android.customization.model.ResourceConstants.ICONS_FOR_PREVIEW;
import static com.android.customization.model.ResourceConstants.OVERLAY_CATEGORY_COLOR;
import static com.android.customization.model.ResourceConstants.OVERLAY_CATEGORY_SYSTEM_PALETTE;
import static com.android.customization.model.color.ColorUtils.toColorString;
import android.content.Context;
import android.content.pm.PackageManager;
-import android.content.pm.PackageManager.NameNotFoundException;
-import android.content.res.Resources;
-import android.content.res.Resources.NotFoundException;
-import android.graphics.drawable.Drawable;
import android.text.TextUtils;
import android.util.Log;
@@ -80,26 +74,4 @@
}
builder.setStyle(s);
}
-
- void addAndroidIconOverlay(ColorBundle.Builder builder) throws NameNotFoundException {
- addSystemDefaultIcons(builder, ICONS_FOR_PREVIEW);
- }
-
- void addSystemDefaultIcons(ColorBundle.Builder builder, String... previewIcons) {
- try {
- for (String iconName : previewIcons) {
- builder.addIcon(loadIconPreviewDrawable(iconName));
- }
- } catch (NameNotFoundException | NotFoundException e) {
- Log.w(TAG, "Didn't find android package icons, will skip preview", e);
- }
- }
-
- Drawable loadIconPreviewDrawable(String drawableName)
- throws NameNotFoundException, NotFoundException {
- Resources packageRes = mPackageManager.getResourcesForApplication(ANDROID_PACKAGE);
- Resources res = Resources.getSystem();
- return res.getDrawable(packageRes.getIdentifier(drawableName, "drawable",
- ANDROID_PACKAGE), null);
- }
}
diff --git a/src/com/android/customization/model/color/ColorProvider.kt b/src/com/android/customization/model/color/ColorProvider.kt
index a63f904..3d2cc7e 100644
--- a/src/com/android/customization/model/color/ColorProvider.kt
+++ b/src/com/android/customization/model/color/ColorProvider.kt
@@ -19,7 +19,6 @@
import android.content.Context
import android.content.res.ColorStateList
import android.content.res.Resources
-import android.text.TextUtils
import androidx.annotation.ColorInt
import androidx.core.graphics.ColorUtils.setAlphaComponent
import androidx.lifecycle.LifecycleOwner
@@ -29,8 +28,8 @@
import com.android.customization.model.ResourceConstants.COLOR_BUNDLE_MAIN_COLOR_PREFIX
import com.android.customization.model.ResourceConstants.COLOR_BUNDLE_NAME_PREFIX
import com.android.customization.model.ResourceConstants.COLOR_BUNDLE_STYLE_PREFIX
-import com.android.customization.model.ResourceConstants.OVERLAY_CATEGORY_SYSTEM_PALETTE
import com.android.customization.model.ResourceConstants.OVERLAY_CATEGORY_COLOR
+import com.android.customization.model.ResourceConstants.OVERLAY_CATEGORY_SYSTEM_PALETTE
import com.android.customization.model.ResourcesApkProvider
import com.android.customization.model.color.ColorOptionsProvider.COLOR_SOURCE_HOME
import com.android.customization.model.color.ColorOptionsProvider.COLOR_SOURCE_LOCK
@@ -39,19 +38,18 @@
import com.android.systemui.monet.Style
import com.android.wallpaper.compat.WallpaperManagerCompat
import com.android.wallpaper.module.InjectorProvider
+import java.util.*
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.SupervisorJob
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
-import java.util.*
/**
- * Default implementation of {@link ColorOptionsProvider} that reads preset colors from
- * a stub APK.
+ * Default implementation of {@link ColorOptionsProvider} that reads preset colors from a stub APK.
*/
class ColorProvider(context: Context, stubPackageName: String) :
- ResourcesApkProvider(context, stubPackageName), ColorOptionsProvider {
+ ResourcesApkProvider(context, stubPackageName), ColorOptionsProvider {
companion object {
const val themeStyleEnabled = true
@@ -64,36 +62,41 @@
private val monetEnabled = ColorUtils.isMonetEnabled(context)
// TODO(b/202145216): Use style method to fetch the list of style.
- private var styleList = if (themeStyleEnabled) arrayOf(
- Style.TONAL_SPOT, Style.SPRITZ, Style.VIBRANT, Style.EXPRESSIVE
- ) else arrayOf(Style.TONAL_SPOT)
+ private var styleList =
+ if (themeStyleEnabled)
+ arrayOf(Style.TONAL_SPOT, Style.SPRITZ, Style.VIBRANT, Style.EXPRESSIVE)
+ else arrayOf(Style.TONAL_SPOT)
- private val scope = if (mContext is LifecycleOwner) {
- mContext.lifecycleScope
- } else {
- CoroutineScope(Dispatchers.Default + SupervisorJob())
- }
+ private val scope =
+ if (mContext is LifecycleOwner) {
+ mContext.lifecycleScope
+ } else {
+ CoroutineScope(Dispatchers.Default + SupervisorJob())
+ }
private var colorsAvailable = true
private var colorBundles: List<ColorOption>? = null
private var homeWallpaperColors: WallpaperColors? = null
private var lockWallpaperColors: WallpaperColors? = null
-
override fun isAvailable(): Boolean {
return monetEnabled && super.isAvailable() && colorsAvailable
}
- override fun fetch(callback: OptionsFetchedListener<ColorOption>?, reload: Boolean,
- homeWallpaperColors: WallpaperColors?,
- lockWallpaperColors: WallpaperColors?) {
- val wallpaperColorsChanged = this.homeWallpaperColors != homeWallpaperColors
- || this.lockWallpaperColors != lockWallpaperColors
+ override fun fetch(
+ callback: OptionsFetchedListener<ColorOption>?,
+ reload: Boolean,
+ homeWallpaperColors: WallpaperColors?,
+ lockWallpaperColors: WallpaperColors?
+ ) {
+ val wallpaperColorsChanged =
+ this.homeWallpaperColors != homeWallpaperColors ||
+ this.lockWallpaperColors != lockWallpaperColors
if (wallpaperColorsChanged) {
this.homeWallpaperColors = homeWallpaperColors
this.lockWallpaperColors = lockWallpaperColors
}
- if(colorBundles == null || reload || wallpaperColorsChanged) {
+ if (colorBundles == null || reload || wallpaperColorsChanged) {
scope.launch {
try {
if (colorBundles == null || reload) {
@@ -119,46 +122,56 @@
// is the most recently set wallpaper
val manager = InjectorProvider.getInjector().getWallpaperManagerCompat(mContext)
return manager.getWallpaperId(WallpaperManagerCompat.FLAG_LOCK) >
- manager.getWallpaperId(WallpaperManagerCompat.FLAG_SYSTEM)
+ manager.getWallpaperId(WallpaperManagerCompat.FLAG_SYSTEM)
}
- private fun loadSeedColors(homeWallpaperColors: WallpaperColors?,
- lockWallpaperColors: WallpaperColors?) {
+ private fun loadSeedColors(
+ homeWallpaperColors: WallpaperColors?,
+ lockWallpaperColors: WallpaperColors?
+ ) {
if (homeWallpaperColors == null) return
val bundles: MutableList<ColorOption> = ArrayList()
- val colorsPerSource = if (lockWallpaperColors == null) {
- MAX_SEED_COLORS
- } else {
- MAX_SEED_COLORS / 2
- }
+ val colorsPerSource =
+ if (lockWallpaperColors == null) {
+ MAX_SEED_COLORS
+ } else {
+ MAX_SEED_COLORS / 2
+ }
if (lockWallpaperColors != null) {
val shouldLockColorsGoFirst = isLockScreenWallpaperLastApplied()
// First half of the colors
buildColorSeeds(
- if (shouldLockColorsGoFirst) lockWallpaperColors else homeWallpaperColors,
- colorsPerSource,
- if (shouldLockColorsGoFirst) COLOR_SOURCE_LOCK else COLOR_SOURCE_HOME,
- true,
- bundles)
+ if (shouldLockColorsGoFirst) lockWallpaperColors else homeWallpaperColors,
+ colorsPerSource,
+ if (shouldLockColorsGoFirst) COLOR_SOURCE_LOCK else COLOR_SOURCE_HOME,
+ true,
+ bundles
+ )
// Second half of the colors
buildColorSeeds(
- if (shouldLockColorsGoFirst) homeWallpaperColors else lockWallpaperColors,
- MAX_SEED_COLORS - bundles.size / styleSize,
- if (shouldLockColorsGoFirst) COLOR_SOURCE_HOME else COLOR_SOURCE_LOCK,
- false,
- bundles)
+ if (shouldLockColorsGoFirst) homeWallpaperColors else lockWallpaperColors,
+ MAX_SEED_COLORS - bundles.size / styleSize,
+ if (shouldLockColorsGoFirst) COLOR_SOURCE_HOME else COLOR_SOURCE_LOCK,
+ false,
+ bundles
+ )
} else {
buildColorSeeds(homeWallpaperColors, colorsPerSource, COLOR_SOURCE_HOME, true, bundles)
}
- bundles.addAll(colorBundles?.filterNot{it is ColorSeedOption} ?: emptyList())
+ bundles.addAll(colorBundles?.filterNot { it is ColorSeedOption } ?: emptyList())
colorBundles = bundles
}
- private fun buildColorSeeds(wallpaperColors: WallpaperColors, maxColors: Int, source: String,
- containsDefault: Boolean, bundles: MutableList<ColorOption>) {
+ private fun buildColorSeeds(
+ wallpaperColors: WallpaperColors,
+ maxColors: Int,
+ source: String,
+ containsDefault: Boolean,
+ bundles: MutableList<ColorOption>
+ ) {
val seedColors = ColorScheme.getSeedColors(wallpaperColors)
val defaultSeed = seedColors.first()
buildBundle(defaultSeed, 0, containsDefault, source, bundles)
@@ -167,19 +180,27 @@
}
}
- private fun buildBundle(colorInt: Int, i: Int, isDefault: Boolean, source: String,
- bundles: MutableList<ColorOption>) {
+ private fun buildBundle(
+ colorInt: Int,
+ i: Int,
+ isDefault: Boolean,
+ source: String,
+ bundles: MutableList<ColorOption>
+ ) {
// TODO(b/202145216): Measure time cost in the loop.
for (style in styleList) {
val builder = ColorSeedOption.Builder()
val lightColorScheme = ColorScheme(colorInt, /* darkTheme= */ false, style)
val darkColorScheme = ColorScheme(colorInt, /* darkTheme= */ true, style)
- builder.setLightColors(lightColorScheme.getLightColorPreview())
+ builder
+ .setLightColors(lightColorScheme.getLightColorPreview())
.setDarkColors(darkColorScheme.getDarkColorPreview())
- .addOverlayPackage(OVERLAY_CATEGORY_SYSTEM_PALETTE,
+ .addOverlayPackage(
+ OVERLAY_CATEGORY_SYSTEM_PALETTE,
if (isDefault) "" else toColorString(colorInt)
)
- .addOverlayPackage(OVERLAY_CATEGORY_COLOR,
+ .addOverlayPackage(
+ OVERLAY_CATEGORY_COLOR,
if (isDefault) "" else toColorString(colorInt)
)
.setSource(source)
@@ -194,88 +215,99 @@
}
/**
- * Returns the colors for the light theme version of the preview of a ColorScheme
- * based on this order:
- * |-------|
- * | 0 | 1 |
- * |---+---|
- * | 2 | 3 |
- * |-------|
+ * Returns the colors for the light theme version of the preview of a ColorScheme based on this
+ * order: |-------| | 0 | 1 | |---+---| | 2 | 3 | |-------|
*/
@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 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)
+ )
}
/**
- * Returns the color for the dark theme version of the preview of a ColorScheme
- * based on this order:
- * |-------|
- * | 0 | 1 |
- * |---+---|
- * | 2 | 3 |
- * |-------|
+ * Returns the color for the dark theme version of the preview of a ColorScheme based on this
+ * order: |-------| | 0 | 1 | |---+---| | 2 | 3 | |-------|
*/
@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 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)
+ )
}
private fun ColorScheme.getPresetColorPreview(seed: Int): IntArray {
- return when(this.style) {
+ return when (this.style) {
Style.FRUIT_SALAD -> intArrayOf(seed, this.accent1[2])
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])
}
}
- private suspend fun loadPreset() = withContext(Dispatchers.IO) {
- val extractor = ColorBundlePreviewExtractor(mContext)
- val bundles: MutableList<ColorOption> = ArrayList()
+ private suspend fun loadPreset() =
+ withContext(Dispatchers.IO) {
+ val extractor = ColorBundlePreviewExtractor(mContext)
+ val bundles: MutableList<ColorOption> = ArrayList()
- val bundleNames = getItemsFromStub(COLOR_BUNDLES_ARRAY_NAME)
- // Color option index value starts from 1.
- var index = 1
- val maxPresetColors = if (themeStyleEnabled) bundleNames.size else MAX_PRESET_COLORS
- for (bundleName in bundleNames.take(maxPresetColors)) {
- val builder = ColorBundle.Builder()
- builder.title = getItemStringFromStub(COLOR_BUNDLE_NAME_PREFIX, bundleName)
- builder.setIndex(index)
- val colorFromStub = getItemColorFromStub(COLOR_BUNDLE_MAIN_COLOR_PREFIX, bundleName)
- extractor.addPrimaryColor(builder, colorFromStub)
- extractor.addSecondaryColor(builder, colorFromStub)
- if (themeStyleEnabled) {
- val styleName = try {
- getItemStringFromStub(COLOR_BUNDLE_STYLE_PREFIX, bundleName)
- } catch (e: Resources.NotFoundException) {
- null
- }
- extractor.addColorStyle(builder, styleName)
- val style = try {
- if (styleName != null) Style.valueOf(styleName) else Style.TONAL_SPOT
- } catch (e: IllegalArgumentException) {
- Style.TONAL_SPOT
+ val bundleNames = getItemsFromStub(COLOR_BUNDLES_ARRAY_NAME)
+ // Color option index value starts from 1.
+ var index = 1
+ val maxPresetColors = if (themeStyleEnabled) bundleNames.size else MAX_PRESET_COLORS
+ for (bundleName in bundleNames.take(maxPresetColors)) {
+ val builder = ColorBundle.Builder()
+ builder.title = getItemStringFromStub(COLOR_BUNDLE_NAME_PREFIX, bundleName)
+ builder.setIndex(index)
+ val colorFromStub = getItemColorFromStub(COLOR_BUNDLE_MAIN_COLOR_PREFIX, bundleName)
+ extractor.addPrimaryColor(builder, colorFromStub)
+ extractor.addSecondaryColor(builder, colorFromStub)
+ if (themeStyleEnabled) {
+ val styleName =
+ try {
+ getItemStringFromStub(COLOR_BUNDLE_STYLE_PREFIX, bundleName)
+ } catch (e: Resources.NotFoundException) {
+ null
+ }
+ extractor.addColorStyle(builder, styleName)
+ val style =
+ try {
+ if (styleName != null) Style.valueOf(styleName) else Style.TONAL_SPOT
+ } catch (e: IllegalArgumentException) {
+ Style.TONAL_SPOT
+ }
+
+ if (
+ style == Style.MONOCHROMATIC &&
+ !InjectorProvider.getInjector().getFlags().isMonochromaticFlagEnabled()
+ ) {
+ continue
+ }
+
+ val darkColors =
+ ColorScheme(colorFromStub, true, style).getPresetColorPreview(colorFromStub)
+ val lightColors =
+ ColorScheme(colorFromStub, false, style)
+ .getPresetColorPreview(colorFromStub)
+ builder.setColorPrimaryDark(darkColors[0]).setColorSecondaryDark(darkColors[1])
+ builder
+ .setColorPrimaryLight(lightColors[0])
+ .setColorSecondaryLight(lightColors[1])
}
- val darkColors = ColorScheme(colorFromStub, true, style)
- .getPresetColorPreview(colorFromStub)
- val lightColors = ColorScheme(colorFromStub, false, style)
- .getPresetColorPreview(colorFromStub)
- builder.setColorPrimaryDark(darkColors[0]).setColorSecondaryDark(darkColors[1])
- builder.setColorPrimaryLight(lightColors[0]).setColorSecondaryLight(lightColors[1])
+ bundles.add(builder.build(mContext))
+ index++
}
- extractor.addAndroidIconOverlay(builder)
- bundles.add(builder.build(mContext))
- index++
+ colorBundles = bundles
}
-
- colorBundles = bundles
- }
}
diff --git a/src/com/android/customization/model/color/ColorSeedOption.java b/src/com/android/customization/model/color/ColorSeedOption.java
index 7bddcb0..53d3954 100644
--- a/src/com/android/customization/model/color/ColorSeedOption.java
+++ b/src/com/android/customization/model/color/ColorSeedOption.java
@@ -71,13 +71,9 @@
Resources res = view.getContext().getResources();
@ColorInt int[] colors = mPreviewInfo.resolveColors(res);
- int padding = view.isActivated()
- ? res.getDimensionPixelSize(R.dimen.color_seed_option_tile_padding_selected)
- : res.getDimensionPixelSize(R.dimen.color_seed_option_tile_padding);
for (int i = 0; i < mPreviewColorIds.length; i++) {
ImageView colorPreviewImageView = view.findViewById(mPreviewColorIds[i]);
colorPreviewImageView.getDrawable().setColorFilter(colors[i], Mode.SRC);
- colorPreviewImageView.setPadding(padding, padding, padding, padding);
}
view.setContentDescription(getContentDescription(view.getContext()));
diff --git a/src/com/android/customization/model/color/ColorUtils.kt b/src/com/android/customization/model/color/ColorUtils.kt
index f07ff31..9d925e1 100644
--- a/src/com/android/customization/model/color/ColorUtils.kt
+++ b/src/com/android/customization/model/color/ColorUtils.kt
@@ -22,18 +22,14 @@
import android.util.Log
import androidx.annotation.ColorInt
-/**
- * Utility to wrap Monet's color extraction
- */
+/** Utility to wrap Monet's color extraction */
object ColorUtils {
private const val TAG = "ColorUtils"
private const val MONET_FLAG = "flag_monet"
private var sSysuiRes: Resources? = null
private var sFlagId = 0
- /**
- * Returns true if color extraction is enabled in systemui.
- */
+ /** Returns true if color extraction is enabled in systemui. */
@JvmStatic
fun isMonetEnabled(context: Context): Boolean {
var monetEnabled = SystemProperties.getBoolean("persist.systemui.flag_monet", false)
@@ -41,8 +37,11 @@
if (sSysuiRes == null) {
try {
val pm = context.packageManager
- val sysUIInfo = pm.getApplicationInfo("com.android.systemui",
- PackageManager.GET_META_DATA or PackageManager.MATCH_SYSTEM_ONLY)
+ val sysUIInfo =
+ pm.getApplicationInfo(
+ "com.android.systemui",
+ PackageManager.GET_META_DATA or PackageManager.MATCH_SYSTEM_ONLY
+ )
if (sysUIInfo != null) {
sSysuiRes = pm.getResourcesForApplication(sysUIInfo)
}
@@ -51,8 +50,9 @@
}
}
if (sFlagId == 0) {
- sFlagId = if (sSysuiRes == null) 0 else sSysuiRes!!.getIdentifier(
- MONET_FLAG, "bool", "com.android.systemui")
+ sFlagId =
+ if (sSysuiRes == null) 0
+ else sSysuiRes!!.getIdentifier(MONET_FLAG, "bool", "com.android.systemui")
}
if (sFlagId > 0) {
monetEnabled = sSysuiRes!!.getBoolean(sFlagId)
@@ -65,4 +65,4 @@
fun toColorString(@ColorInt color: Int): String {
return String.format("%06X", 0xFFFFFF and color)
}
-}
\ No newline at end of file
+}
diff --git a/src/com/android/customization/module/CustomizationInjector.java b/src/com/android/customization/module/CustomizationInjector.java
deleted file mode 100644
index 85853de..0000000
--- a/src/com/android/customization/module/CustomizationInjector.java
+++ /dev/null
@@ -1,33 +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.module;
-
-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.wallpaper.module.Injector;
-
-public interface CustomizationInjector extends Injector {
-
- CustomizationPreferences getCustomizationPreferences(Context context);
-
- ThemeManager getThemeManager(ThemeBundleProvider provider, FragmentActivity activity,
- OverlayManagerCompat overlayManagerCompat, ThemesUserEventLogger logger);
-}
diff --git a/src/com/android/customization/module/CustomizationInjector.kt b/src/com/android/customization/module/CustomizationInjector.kt
new file mode 100644
index 0000000..3cf8393
--- /dev/null
+++ b/src/com/android/customization/module/CustomizationInjector.kt
@@ -0,0 +1,39 @@
+/*
+ * 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.module
+
+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.quickaffordance.domain.interactor.KeyguardQuickAffordancePickerInteractor
+import com.android.wallpaper.module.Injector
+
+interface CustomizationInjector : Injector {
+ fun getCustomizationPreferences(context: Context): CustomizationPreferences
+
+ fun getThemeManager(
+ provider: ThemeBundleProvider,
+ activity: FragmentActivity,
+ overlayManagerCompat: OverlayManagerCompat,
+ logger: ThemesUserEventLogger
+ ): ThemeManager
+
+ fun getKeyguardQuickAffordancePickerInteractor(
+ context: Context
+ ): KeyguardQuickAffordancePickerInteractor
+}
diff --git a/src/com/android/customization/module/DefaultCustomizationInjector.java b/src/com/android/customization/module/DefaultCustomizationInjector.java
deleted file mode 100644
index 220c406..0000000
--- a/src/com/android/customization/module/DefaultCustomizationInjector.java
+++ /dev/null
@@ -1,149 +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.module;
-
-import android.content.Context;
-import android.content.Intent;
-import android.net.Uri;
-
-import androidx.fragment.app.Fragment;
-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.wallpaper.model.CategoryProvider;
-import com.android.wallpaper.model.WallpaperInfo;
-import com.android.wallpaper.module.BaseWallpaperInjector;
-import com.android.wallpaper.module.CustomizationSections;
-import com.android.wallpaper.module.DefaultCategoryProvider;
-import com.android.wallpaper.module.LoggingOptInStatusProvider;
-import com.android.wallpaper.module.WallpaperPreferences;
-import com.android.wallpaper.module.WallpaperRotationRefresher;
-import com.android.wallpaper.monitor.PerformanceMonitor;
-import com.android.wallpaper.picker.CustomizationPickerActivity;
-import com.android.wallpaper.picker.PreviewFragment;
-
-public class DefaultCustomizationInjector extends BaseWallpaperInjector
- implements CustomizationInjector {
- private CategoryProvider mCategoryProvider;
- private ThemesUserEventLogger mUserEventLogger;
- private WallpaperRotationRefresher mWallpaperRotationRefresher;
- private PerformanceMonitor mPerformanceMonitor;
- private WallpaperPreferences mPrefs;
- private CustomizationSections mCustomizationSections;
-
- @Override
- public synchronized WallpaperPreferences getPreferences(Context context) {
- if (mPrefs == null) {
- mPrefs = new DefaultCustomizationPreferences(context.getApplicationContext());
- }
- return mPrefs;
- }
-
- @Override
- public CustomizationPreferences getCustomizationPreferences(Context context) {
- return (CustomizationPreferences) getPreferences(context);
- }
-
- @Override
- public synchronized CategoryProvider getCategoryProvider(Context context) {
- if (mCategoryProvider == null) {
- mCategoryProvider = new DefaultCategoryProvider(context.getApplicationContext());
- }
- return mCategoryProvider;
- }
-
- @Override
- public synchronized ThemesUserEventLogger getUserEventLogger(Context context) {
- if (mUserEventLogger == null) {
- mUserEventLogger = new StatsLogUserEventLogger(context);
- }
- return mUserEventLogger;
- }
-
- @Override
- public synchronized WallpaperRotationRefresher getWallpaperRotationRefresher() {
- if (mWallpaperRotationRefresher == null) {
- mWallpaperRotationRefresher = new WallpaperRotationRefresher() {
- @Override
- public void refreshWallpaper(Context context, Listener listener) {
- // Not implemented
- listener.onError();
- }
- };
- }
- return mWallpaperRotationRefresher;
- }
-
- @Override
- public Fragment getPreviewFragment(
- Context context,
- WallpaperInfo wallpaperInfo,
- int mode,
- boolean viewAsHome,
- boolean viewFullScreen,
- boolean testingModeEnabled) {
- return PreviewFragment.newInstance(wallpaperInfo, mode, viewAsHome, viewFullScreen,
- testingModeEnabled);
- }
-
- @Override
- public Intent getDeepLinkRedirectIntent(Context context, Uri uri) {
- Intent intent = new Intent();
- intent.setClass(context, CustomizationPickerActivity.class);
- intent.setData(uri);
- intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
- return intent;
- }
-
- @Override
- public String getDownloadableIntentAction() {
- return null;
- }
-
- @Override
- public synchronized PerformanceMonitor getPerformanceMonitor() {
- if (mPerformanceMonitor == null) {
- mPerformanceMonitor = new PerformanceMonitor() {
- @Override
- public void recordFullResPreviewLoadedMemorySnapshot() {
- // No Op
- }
- };
- }
- return mPerformanceMonitor;
- }
-
- @Override
- public synchronized LoggingOptInStatusProvider getLoggingOptInStatusProvider(Context context) {
- return null;
- }
-
- @Override
- public ThemeManager getThemeManager(ThemeBundleProvider provider, FragmentActivity activity,
- OverlayManagerCompat overlayManagerCompat, ThemesUserEventLogger logger) {
- return new ThemeManager(provider, activity, overlayManagerCompat, logger);
- }
-
- @Override
- public CustomizationSections getCustomizationSections() {
- if (mCustomizationSections == null) {
- mCustomizationSections = new DefaultCustomizationSections();
- }
- return mCustomizationSections;
- }
-}
diff --git a/src/com/android/customization/module/DefaultCustomizationSections.java b/src/com/android/customization/module/DefaultCustomizationSections.java
index cb5da01..809bbee 100644
--- a/src/com/android/customization/module/DefaultCustomizationSections.java
+++ b/src/com/android/customization/module/DefaultCustomizationSections.java
@@ -1,10 +1,11 @@
package com.android.customization.module;
-import android.app.Activity;
import android.os.Bundle;
import androidx.annotation.Nullable;
+import androidx.fragment.app.FragmentActivity;
import androidx.lifecycle.LifecycleOwner;
+import androidx.lifecycle.ViewModelProvider;
import com.android.customization.model.color.ColorSectionController;
import com.android.customization.model.font.FontManager;
@@ -19,6 +20,9 @@
import com.android.customization.model.theme.OverlayManagerCompat;
import com.android.customization.model.themedicon.ThemedIconSectionController;
import com.android.customization.model.themedicon.ThemedIconSwitchProvider;
+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.wallpaper.model.CustomizationSectionController;
import com.android.wallpaper.model.CustomizationSectionController.CustomizationSectionNavigationController;
import com.android.wallpaper.model.PermissionRequester;
@@ -26,7 +30,10 @@
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.ui.section.ScreenPreviewSectionController;
+import com.android.wallpaper.util.DisplayUtils;
import java.util.ArrayList;
import java.util.List;
@@ -34,20 +41,99 @@
/** {@link CustomizationSections} for the customization picker. */
public final class DefaultCustomizationSections implements CustomizationSections {
+ private final KeyguardQuickAffordancePickerInteractor mKeyguardQuickAffordancePickerInteractor;
+ private final KeyguardQuickAffordancePickerViewModel.Factory
+ mKeyguardQuickAffordancePickerViewModelFactory;
+
+ public DefaultCustomizationSections(
+ KeyguardQuickAffordancePickerInteractor keyguardQuickAffordancePickerInteractor,
+ KeyguardQuickAffordancePickerViewModel.Factory
+ keyguardQuickAffordancePickerViewModelFactory) {
+ mKeyguardQuickAffordancePickerInteractor = keyguardQuickAffordancePickerInteractor;
+ mKeyguardQuickAffordancePickerViewModelFactory =
+ keyguardQuickAffordancePickerViewModelFactory;
+ }
+
@Override
- public List<CustomizationSectionController<?>> getAllSectionControllers(Activity activity,
- LifecycleOwner lifecycleOwner, WallpaperColorsViewModel wallpaperColorsViewModel,
- WorkspaceViewModel workspaceViewModel, PermissionRequester permissionRequester,
+ public List<CustomizationSectionController<?>> getSectionControllersForScreen(
+ Screen screen,
+ FragmentActivity activity,
+ LifecycleOwner lifecycleOwner,
+ WallpaperColorsViewModel wallpaperColorsViewModel,
+ WorkspaceViewModel workspaceViewModel,
+ PermissionRequester permissionRequester,
WallpaperPreviewNavigator wallpaperPreviewNavigator,
CustomizationSectionNavigationController sectionNavigationController,
- @Nullable Bundle savedInstanceState) {
+ @Nullable Bundle savedInstanceState,
+ CurrentWallpaperInfoFactory wallpaperInfoFactory,
+ DisplayUtils displayUtils) {
+ List<CustomizationSectionController<?>> sectionControllers = new ArrayList<>();
+
+ // Wallpaper section.
+ sectionControllers.add(
+ new ScreenPreviewSectionController(
+ activity,
+ lifecycleOwner,
+ screen,
+ wallpaperInfoFactory,
+ wallpaperColorsViewModel,
+ displayUtils));
+
+ // Theme color section.
+ sectionControllers.add(new ColorSectionController(
+ activity, wallpaperColorsViewModel, lifecycleOwner, savedInstanceState));
+
+ switch (screen) {
+ case LOCK_SCREEN:
+ // Lock screen quick affordances section.
+ sectionControllers.add(
+ new KeyguardQuickAffordanceSectionController(
+ sectionNavigationController,
+ mKeyguardQuickAffordancePickerInteractor,
+ new ViewModelProvider(
+ activity,
+ mKeyguardQuickAffordancePickerViewModelFactory)
+ .get(KeyguardQuickAffordancePickerViewModel.class),
+ lifecycleOwner));
+ 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));
+
+ // App grid section.
+ sectionControllers.add(new GridSectionController(
+ GridOptionsManager.getInstance(activity), sectionNavigationController));
+ break;
+ }
+
+ return sectionControllers;
+ }
+
+ @Override
+ public List<CustomizationSectionController<?>> getAllSectionControllers(
+ FragmentActivity activity,
+ LifecycleOwner lifecycleOwner,
+ WallpaperColorsViewModel wallpaperColorsViewModel,
+ WorkspaceViewModel workspaceViewModel,
+ PermissionRequester permissionRequester,
+ WallpaperPreviewNavigator wallpaperPreviewNavigator,
+ CustomizationSectionNavigationController sectionNavigationController,
+ @Nullable Bundle savedInstanceState,
+ DisplayUtils displayUtils) {
List<CustomizationSectionController<?>> sectionControllers = new ArrayList<>();
// Wallpaper section.
sectionControllers.add(new WallpaperSectionController(
activity, lifecycleOwner, permissionRequester, wallpaperColorsViewModel,
workspaceViewModel, sectionNavigationController, wallpaperPreviewNavigator,
- savedInstanceState));
+ savedInstanceState, displayUtils));
// Theme color section.
sectionControllers.add(new ColorSectionController(
diff --git a/src/com/android/customization/module/StatsLogUserEventLogger.java b/src/com/android/customization/module/StatsLogUserEventLogger.java
index e3e4336..2b6767b 100644
--- a/src/com/android/customization/module/StatsLogUserEventLogger.java
+++ b/src/com/android/customization/module/StatsLogUserEventLogger.java
@@ -177,11 +177,23 @@
}
@Override
- public void logEffectApply(String effect, @EffectStatus int status) {
+ public void logEffectApply(String effect, @EffectStatus int status, long timeElapsedMillis,
+ int resultCode) {
new SysUiStatsLogger()
.setAction(StyleEnums.WALLPAPER_EFFECT_APPLIED)
.setEffectPreference(status)
.setEffectIdHash(getIdHashCode(effect))
+ .setTimeElapsed(timeElapsedMillis)
+ .setEffectResultCode(resultCode)
+ .log();
+ }
+
+ @Override
+ public void logEffectProbe(String effect, @EffectStatus int status) {
+ new SysUiStatsLogger()
+ .setAction(StyleEnums.WALLPAPER_EFFECT_PROBE)
+ .setEffectPreference(status)
+ .setEffectIdHash(getIdHashCode(effect))
.log();
}
diff --git a/src/com/android/customization/module/SysUiStatsLogger.kt b/src/com/android/customization/module/SysUiStatsLogger.kt
index eb3bcc0..318bf1f 100644
--- a/src/com/android/customization/module/SysUiStatsLogger.kt
+++ b/src/com/android/customization/module/SysUiStatsLogger.kt
@@ -19,9 +19,7 @@
import com.android.systemui.shared.system.SysUiStatsLog
import com.android.systemui.shared.system.SysUiStatsLog.STYLE_UI_CHANGED
-/**
- * The builder for [SysUiStatsLog].
- */
+/** The builder for [SysUiStatsLog]. */
class SysUiStatsLogger {
private var atom = STYLE_UI_CHANGED
@@ -45,68 +43,84 @@
private var firstWallpaperApplyDateSinceSetup = 0
private var appLaunchCount = 0
private var colorVariant = 0
+ private var timeElapsedMillis = 0L
+ private var effectResultCode = -1
- fun setAction(action: Int) =
- apply { this.action = action }
+ fun setAction(action: Int) = apply { this.action = action }
- fun setColorPackageHash(color_package_hash: Int) =
- apply { this.colorPackageHash = color_package_hash }
+ fun setColorPackageHash(color_package_hash: Int) = apply {
+ this.colorPackageHash = color_package_hash
+ }
- fun setFontPackageHash(font_package_hash: Int) =
- apply { this.fontPackageHash = font_package_hash }
+ fun setFontPackageHash(font_package_hash: Int) = apply {
+ this.fontPackageHash = font_package_hash
+ }
- fun setShapePackageHash(shape_package_hash: Int) =
- apply { this.shapePackageHash = shape_package_hash }
+ fun setShapePackageHash(shape_package_hash: Int) = apply {
+ this.shapePackageHash = shape_package_hash
+ }
- fun setClockPackageHash(clock_package_hash: Int) =
- apply { this.clockPackageHash = clock_package_hash }
+ fun setClockPackageHash(clock_package_hash: Int) = apply {
+ this.clockPackageHash = clock_package_hash
+ }
- fun setLauncherGrid(launcher_grid: Int) =
- apply { this.launcherGrid = launcher_grid }
+ fun setLauncherGrid(launcher_grid: Int) = apply { this.launcherGrid = launcher_grid }
- fun setWallpaperCategoryHash(wallpaper_category_hash: Int) =
- apply { this.wallpaperCategoryHash = wallpaper_category_hash }
+ fun setWallpaperCategoryHash(wallpaper_category_hash: Int) = apply {
+ this.wallpaperCategoryHash = wallpaper_category_hash
+ }
- fun setWallpaperIdHash(wallpaper_id_hash: Int) =
- apply { this.wallpaperIdHash = wallpaper_id_hash }
+ fun setWallpaperIdHash(wallpaper_id_hash: Int) = apply {
+ this.wallpaperIdHash = wallpaper_id_hash
+ }
- fun setColorPreference(color_preference: Int) =
- apply { this.colorPreference = color_preference }
+ fun setColorPreference(color_preference: Int) = apply {
+ this.colorPreference = color_preference
+ }
- fun setLocationPreference(location_preference: Int) =
- apply { this.locationPreference = location_preference }
+ fun setLocationPreference(location_preference: Int) = apply {
+ this.locationPreference = location_preference
+ }
- fun setDatePreference(date_preference: Int) =
- apply { this.datePreference = date_preference }
+ fun setDatePreference(date_preference: Int) = apply { this.datePreference = date_preference }
- fun setLaunchedPreference(launched_preference: Int) =
- apply { this.launchedPreference = launched_preference }
+ fun setLaunchedPreference(launched_preference: Int) = apply {
+ this.launchedPreference = launched_preference
+ }
- fun setEffectPreference(effect_preference: Int) =
- apply { this.effectPreference = effect_preference }
+ fun setEffectPreference(effect_preference: Int) = apply {
+ this.effectPreference = effect_preference
+ }
- fun setEffectIdHash(effect_id_hash: Int) =
- apply { this.effectIdHash = effect_id_hash }
+ fun setEffectIdHash(effect_id_hash: Int) = apply { this.effectIdHash = effect_id_hash }
- fun setLockWallpaperCategoryHash(lock_wallpaper_category_hash: Int) =
- apply { this.lockWallpaperCategoryHash = lock_wallpaper_category_hash }
+ fun setLockWallpaperCategoryHash(lock_wallpaper_category_hash: Int) = apply {
+ this.lockWallpaperCategoryHash = lock_wallpaper_category_hash
+ }
- fun setLockWallpaperIdHash(lock_wallpaper_id_hash: Int) =
- apply { this.lockWallpaperIdHash = lock_wallpaper_id_hash }
+ fun setLockWallpaperIdHash(lock_wallpaper_id_hash: Int) = apply {
+ this.lockWallpaperIdHash = lock_wallpaper_id_hash
+ }
- fun setFirstLaunchDateSinceSetup(first_launch_date_since_setup: Int) =
- apply { this.firstLaunchDateSinceSetup = first_launch_date_since_setup }
+ fun setFirstLaunchDateSinceSetup(first_launch_date_since_setup: Int) = apply {
+ this.firstLaunchDateSinceSetup = first_launch_date_since_setup
+ }
- fun setFirstWallpaperApplyDateSinceSetup(first_wallpaper_apply_date_since_setup: Int) =
- apply {
- this.firstWallpaperApplyDateSinceSetup = first_wallpaper_apply_date_since_setup
- }
+ fun setFirstWallpaperApplyDateSinceSetup(first_wallpaper_apply_date_since_setup: Int) = apply {
+ this.firstWallpaperApplyDateSinceSetup = first_wallpaper_apply_date_since_setup
+ }
- fun setAppLaunchCount(app_launch_count: Int) =
- apply { this.appLaunchCount = app_launch_count }
+ fun setAppLaunchCount(app_launch_count: Int) = apply { this.appLaunchCount = app_launch_count }
- fun setColorVariant(color_variant: Int) =
- apply { this.colorVariant = color_variant }
+ fun setColorVariant(color_variant: Int) = apply { this.colorVariant = color_variant }
+
+ fun setTimeElapsed(time_elapsed_millis: Long) = apply {
+ this.timeElapsedMillis = time_elapsed_millis
+ }
+
+ fun setEffectResultCode(effect_result_code: Int) = apply {
+ this.effectResultCode = effect_result_code
+ }
fun log() {
SysUiStatsLog.write(
@@ -130,7 +144,9 @@
firstLaunchDateSinceSetup,
firstWallpaperApplyDateSinceSetup,
appLaunchCount,
- colorVariant
+ colorVariant,
+ timeElapsedMillis,
+ effectResultCode,
)
}
-}
\ No newline at end of file
+}
diff --git a/src/com/android/customization/module/ThemePickerFragmentFactory.kt b/src/com/android/customization/module/ThemePickerFragmentFactory.kt
new file mode 100644
index 0000000..75c3403
--- /dev/null
+++ b/src/com/android/customization/module/ThemePickerFragmentFactory.kt
@@ -0,0 +1,33 @@
+/*
+ * 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.module
+
+import androidx.fragment.app.Fragment
+import com.android.customization.picker.quickaffordance.ui.fragment.KeyguardQuickAffordancePickerFragment
+import com.android.wallpaper.module.FragmentFactory
+
+class ThemePickerFragmentFactory : FragmentFactory {
+
+ override fun create(id: String): Fragment? {
+ return when (id) {
+ KeyguardQuickAffordancePickerFragment.DESTINATION_ID ->
+ KeyguardQuickAffordancePickerFragment.newInstance()
+ else -> null
+ }
+ }
+}
diff --git a/src/com/android/customization/module/ThemePickerInjector.kt b/src/com/android/customization/module/ThemePickerInjector.kt
new file mode 100644
index 0000000..b3f95d5
--- /dev/null
+++ b/src/com/android/customization/module/ThemePickerInjector.kt
@@ -0,0 +1,205 @@
+/*
+ * 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.module
+
+import android.app.Activity
+import android.content.Context
+import android.content.Intent
+import android.net.Uri
+import android.os.Bundle
+import androidx.fragment.app.Fragment
+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.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.customization.data.content.CustomizationProviderClient
+import com.android.systemui.shared.customization.data.content.CustomizationProviderClientImpl
+import com.android.wallpaper.model.LiveWallpaperInfo
+import com.android.wallpaper.model.WallpaperInfo
+import com.android.wallpaper.module.CustomizationSections
+import com.android.wallpaper.module.FragmentFactory
+import com.android.wallpaper.module.UserEventLogger
+import com.android.wallpaper.module.WallpaperPicker2Injector
+import com.android.wallpaper.module.WallpaperPreferences
+import com.android.wallpaper.picker.CustomizationPickerActivity
+import com.android.wallpaper.picker.ImagePreviewFragment
+import com.android.wallpaper.picker.LivePreviewFragment
+import com.android.wallpaper.picker.PreviewFragment
+import com.android.wallpaper.picker.undo.domain.interactor.SnapshotRestorer
+import kotlinx.coroutines.Dispatchers.IO
+
+open class ThemePickerInjector : WallpaperPicker2Injector(), CustomizationInjector {
+ private var customizationSections: CustomizationSections? = null
+ private var userEventLogger: UserEventLogger? = null
+ private var prefs: WallpaperPreferences? = null
+ private var keyguardQuickAffordancePickerInteractor: KeyguardQuickAffordancePickerInteractor? =
+ null
+ private var keyguardQuickAffordancePickerViewModelFactory:
+ KeyguardQuickAffordancePickerViewModel.Factory? =
+ null
+ private var customizationProviderClient: CustomizationProviderClient? = null
+ private var fragmentFactory: FragmentFactory? = null
+ private var keyguardQuickAffordanceSnapshotRestorer: KeyguardQuickAffordanceSnapshotRestorer? =
+ null
+
+ override fun getCustomizationSections(activity: Activity): CustomizationSections {
+ return customizationSections
+ ?: DefaultCustomizationSections(
+ getKeyguardQuickAffordancePickerInteractor(activity),
+ getKeyguardQuickAffordancePickerViewModelFactory(activity)
+ )
+ .also { customizationSections = it }
+ }
+
+ override fun getDeepLinkRedirectIntent(context: Context, uri: Uri): Intent {
+ val intent = Intent()
+ intent.setClass(context, CustomizationPickerActivity::class.java)
+ intent.data = uri
+ intent.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK
+ return intent
+ }
+
+ override fun getDownloadableIntentAction(): String? {
+ return null
+ }
+
+ override fun getPreviewFragment(
+ context: Context,
+ wallpaperInfo: WallpaperInfo,
+ mode: Int,
+ viewAsHome: Boolean,
+ viewFullScreen: Boolean,
+ testingModeEnabled: Boolean
+ ): Fragment {
+ return if (wallpaperInfo is LiveWallpaperInfo) LivePreviewFragment()
+ else
+ ImagePreviewFragment().apply {
+ arguments =
+ Bundle().apply {
+ putParcelable(PreviewFragment.ARG_WALLPAPER, wallpaperInfo)
+ putInt(PreviewFragment.ARG_PREVIEW_MODE, mode)
+ putBoolean(PreviewFragment.ARG_VIEW_AS_HOME, viewAsHome)
+ putBoolean(PreviewFragment.ARG_FULL_SCREEN, viewFullScreen)
+ putBoolean(PreviewFragment.ARG_TESTING_MODE_ENABLED, testingModeEnabled)
+ }
+ }
+ }
+
+ @Synchronized
+ override fun getUserEventLogger(context: Context): ThemesUserEventLogger {
+ return if (userEventLogger != null) userEventLogger as ThemesUserEventLogger
+ else StatsLogUserEventLogger(context).also { userEventLogger = it }
+ }
+
+ @Synchronized
+ override fun getPreferences(context: Context): WallpaperPreferences {
+ return prefs
+ ?: DefaultCustomizationPreferences(context.applicationContext).also { prefs = it }
+ }
+
+ override fun getFragmentFactory(): FragmentFactory? {
+ return fragmentFactory ?: ThemePickerFragmentFactory().also { fragmentFactory }
+ }
+
+ override fun getSnapshotRestorers(context: Context): Map<Int, SnapshotRestorer> {
+ return super<WallpaperPicker2Injector>.getSnapshotRestorers(context).toMutableMap().apply {
+ this[KEY_QUICK_AFFORDANCE_SNAPSHOT_RESTORER] =
+ getKeyguardQuickAffordanceSnapshotRestorer(context)
+ }
+ }
+
+ override fun getCustomizationPreferences(context: Context): CustomizationPreferences {
+ return getPreferences(context) as CustomizationPreferences
+ }
+
+ override fun getThemeManager(
+ provider: ThemeBundleProvider,
+ activity: FragmentActivity,
+ overlayManagerCompat: OverlayManagerCompat,
+ logger: ThemesUserEventLogger
+ ): ThemeManager {
+ return ThemeManager(provider, activity, overlayManagerCompat, logger)
+ }
+
+ override fun getKeyguardQuickAffordancePickerInteractor(
+ context: Context
+ ): KeyguardQuickAffordancePickerInteractor {
+ return keyguardQuickAffordancePickerInteractor
+ ?: getKeyguardQuickAffordancePickerInteractorImpl(context).also {
+ keyguardQuickAffordancePickerInteractor = it
+ }
+ }
+
+ fun getKeyguardQuickAffordancePickerViewModelFactory(
+ context: Context
+ ): KeyguardQuickAffordancePickerViewModel.Factory {
+ return keyguardQuickAffordancePickerViewModelFactory
+ ?: KeyguardQuickAffordancePickerViewModel.Factory(
+ context,
+ getKeyguardQuickAffordancePickerInteractor(context),
+ getUndoInteractor(context),
+ getCurrentWallpaperInfoFactory(context),
+ )
+ .also { keyguardQuickAffordancePickerViewModelFactory = it }
+ }
+
+ private fun getKeyguardQuickAffordancePickerInteractorImpl(
+ context: Context
+ ): KeyguardQuickAffordancePickerInteractor {
+ val client = getKeyguardQuickAffordancePickerProviderClient(context)
+ return KeyguardQuickAffordancePickerInteractor(
+ KeyguardQuickAffordancePickerRepository(client, IO),
+ client
+ ) { getKeyguardQuickAffordanceSnapshotRestorer(context) }
+ }
+
+ protected fun getKeyguardQuickAffordancePickerProviderClient(
+ context: Context
+ ): CustomizationProviderClient {
+ return customizationProviderClient
+ ?: CustomizationProviderClientImpl(context, IO).also {
+ customizationProviderClient = it
+ }
+ }
+
+ protected fun getKeyguardQuickAffordanceSnapshotRestorer(
+ context: Context
+ ): KeyguardQuickAffordanceSnapshotRestorer {
+ return keyguardQuickAffordanceSnapshotRestorer
+ ?: KeyguardQuickAffordanceSnapshotRestorer(
+ getKeyguardQuickAffordancePickerInteractor(context),
+ getKeyguardQuickAffordancePickerProviderClient(context)
+ )
+ .also { keyguardQuickAffordanceSnapshotRestorer = it }
+ }
+
+ companion object {
+ @JvmStatic
+ private val KEY_QUICK_AFFORDANCE_SNAPSHOT_RESTORER =
+ WallpaperPicker2Injector.MIN_SNAPSHOT_RESTORER_KEY
+
+ /**
+ * When this injector is overridden, this is the minimal value that should be used by
+ * restorers returns in [getSnapshotRestorers].
+ */
+ @JvmStatic
+ protected val MIN_SNAPSHOT_RESTORER_KEY = KEY_QUICK_AFFORDANCE_SNAPSHOT_RESTORER + 1
+ }
+}
diff --git a/src/com/android/customization/picker/CustomizationPickerApplication.java b/src/com/android/customization/picker/CustomizationPickerApplication.java
index 79d075a..178cfbf 100644
--- a/src/com/android/customization/picker/CustomizationPickerApplication.java
+++ b/src/com/android/customization/picker/CustomizationPickerApplication.java
@@ -17,7 +17,7 @@
import android.app.Application;
-import com.android.customization.module.DefaultCustomizationInjector;
+import com.android.customization.module.ThemePickerInjector;
import com.android.wallpaper.module.InjectorProvider;
public class CustomizationPickerApplication extends Application {
@@ -26,6 +26,6 @@
super.onCreate();
// Initialize the injector.
- InjectorProvider.setInjector(new DefaultCustomizationInjector());
+ InjectorProvider.setInjector(new ThemePickerInjector());
}
}
diff --git a/src/com/android/customization/picker/WallpaperPreviewer.java b/src/com/android/customization/picker/WallpaperPreviewer.java
index fa7dd81..354eec2 100644
--- a/src/com/android/customization/picker/WallpaperPreviewer.java
+++ b/src/com/android/customization/picker/WallpaperPreviewer.java
@@ -154,14 +154,16 @@
.loadPreviewImage(mActivity,
renderInImageWallpaperSurface ? homeImageWallpaper : mHomePreview,
ResourceUtils.getColorAttr(
- mActivity, android.R.attr.colorSecondary));
+ mActivity, android.R.attr.colorSecondary),
+ /* offsetToStart= */ true);
if (mWallpaper instanceof LiveWallpaperInfo) {
mWallpaper.getThumbAsset(mActivity.getApplicationContext())
.loadPreviewImage(
mActivity,
homeImageWallpaper,
ResourceUtils.getColorAttr(
- mActivity, android.R.attr.colorSecondary));
+ mActivity, android.R.attr.colorSecondary),
+ /* offsetToStart= */ true);
setUpLiveWallpaperPreview(mWallpaper);
} else {
// Ensure live wallpaper connection is disconnected.
diff --git a/src/com/android/customization/picker/clock/ClockCustomDemoFragment.kt b/src/com/android/customization/picker/clock/ClockCustomDemoFragment.kt
new file mode 100644
index 0000000..8648dca
--- /dev/null
+++ b/src/com/android/customization/picker/clock/ClockCustomDemoFragment.kt
@@ -0,0 +1,191 @@
+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/ClockSectionView.kt b/src/com/android/customization/picker/clock/ClockSectionView.kt
index c043209..fac975a 100644
--- a/src/com/android/customization/picker/clock/ClockSectionView.kt
+++ b/src/com/android/customization/picker/clock/ClockSectionView.kt
@@ -19,5 +19,5 @@
import android.util.AttributeSet
import com.android.wallpaper.picker.SectionView
-/** The [SectionView] for app clock. */
-class ClockSectionView(context: Context?, attrs: AttributeSet?) : SectionView(context, attrs)
\ No newline at end of file
+/** The [SectionView] for app clock. */
+class ClockSectionView(context: Context?, attrs: AttributeSet?) : SectionView(context, attrs)
diff --git a/src/com/android/customization/picker/clock/domain/interactor/ClocksSnapshotRestorer.kt b/src/com/android/customization/picker/clock/domain/interactor/ClocksSnapshotRestorer.kt
new file mode 100644
index 0000000..63b4a9b
--- /dev/null
+++ b/src/com/android/customization/picker/clock/domain/interactor/ClocksSnapshotRestorer.kt
@@ -0,0 +1,35 @@
+/*
+ * 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.domain.interactor
+
+import com.android.wallpaper.picker.undo.domain.interactor.SnapshotRestorer
+import com.android.wallpaper.picker.undo.shared.model.RestorableSnapshot
+
+/** Handles state restoration for clocks. */
+class ClocksSnapshotRestorer : SnapshotRestorer {
+ override suspend fun setUpSnapshotRestorer(
+ updater: (RestorableSnapshot) -> Unit,
+ ): RestorableSnapshot {
+ // TODO(b/262924055): implement as part of the clock settings screen.
+ return RestorableSnapshot(mapOf())
+ }
+
+ override suspend fun restoreToSnapshot(snapshot: RestorableSnapshot) {
+ // TODO(b/262924055): implement as part of the clock settings screen.
+ }
+}
diff --git a/src/com/android/customization/picker/grid/GridFragment.java b/src/com/android/customization/picker/grid/GridFragment.java
index c4029d6..d60ebca 100644
--- a/src/com/android/customization/picker/grid/GridFragment.java
+++ b/src/com/android/customization/picker/grid/GridFragment.java
@@ -160,7 +160,7 @@
getActivity(), view.findViewById(R.id.wallpaper_preview_image), wallpaperSurface);
// Loads current Wallpaper.
CurrentWallpaperInfoFactory factory = InjectorProvider.getInjector()
- .getCurrentWallpaperFactory(getContext().getApplicationContext());
+ .getCurrentWallpaperInfoFactory(getContext().getApplicationContext());
factory.createCurrentWallpaperInfos((homeWallpaper, lockWallpaper, presentationMode) -> {
mHomeWallpaper = homeWallpaper;
wallpaperPreviewer.setWallpaper(mHomeWallpaper, /* listener= */ null);
diff --git a/src/com/android/customization/picker/grid/GridOptionPreviewer.java b/src/com/android/customization/picker/grid/GridOptionPreviewer.java
index 5cf327e..7786d35 100644
--- a/src/com/android/customization/picker/grid/GridOptionPreviewer.java
+++ b/src/com/android/customization/picker/grid/GridOptionPreviewer.java
@@ -22,6 +22,7 @@
import com.android.customization.model.grid.GridOption;
import com.android.customization.model.grid.GridOptionsManager;
+import com.android.wallpaper.R;
import com.android.wallpaper.picker.WorkspaceSurfaceHolderCallback;
import com.android.wallpaper.util.PreviewUtils;
import com.android.wallpaper.util.SurfaceViewUtils;
@@ -80,7 +81,10 @@
private class GridOptionSurfaceHolderCallback extends WorkspaceSurfaceHolderCallback {
private GridOptionSurfaceHolderCallback(SurfaceView workspaceSurface, Context context) {
- super(workspaceSurface, context);
+ super(
+ workspaceSurface,
+ new PreviewUtils(
+ context, context.getString(R.string.grid_control_metadata_name)));
}
@Override
diff --git a/src/com/android/customization/picker/quickaffordance/data/repository/KeyguardQuickAffordancePickerRepository.kt b/src/com/android/customization/picker/quickaffordance/data/repository/KeyguardQuickAffordancePickerRepository.kt
new file mode 100644
index 0000000..fd553fe
--- /dev/null
+++ b/src/com/android/customization/picker/quickaffordance/data/repository/KeyguardQuickAffordancePickerRepository.kt
@@ -0,0 +1,95 @@
+/*
+ * 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.data.repository
+
+import com.android.customization.picker.quickaffordance.shared.model.KeyguardQuickAffordancePickerAffordanceModel as AffordanceModel
+import com.android.customization.picker.quickaffordance.shared.model.KeyguardQuickAffordancePickerSelectionModel as SelectionModel
+import com.android.customization.picker.quickaffordance.shared.model.KeyguardQuickAffordancePickerSlotModel as SlotModel
+import com.android.systemui.shared.customization.data.content.CustomizationProviderClient as Client
+import com.android.systemui.shared.customization.data.content.CustomizationProviderContract as Contract
+import kotlinx.coroutines.CoroutineDispatcher
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.map
+import kotlinx.coroutines.withContext
+
+/**
+ * Abstracts access to application state related to functionality for selecting, picking, or setting
+ * lock screen quick affordances.
+ */
+class KeyguardQuickAffordancePickerRepository(
+ private val client: Client,
+ private val backgroundDispatcher: CoroutineDispatcher,
+) {
+ /** Whether the feature is enabled. */
+ val isFeatureEnabled: Flow<Boolean> =
+ client.observeFlags().map { flags -> flags.isFeatureEnabled() }
+
+ /** List of slots available on the device. */
+ val slots: Flow<List<SlotModel>> =
+ client.observeSlots().map { slots -> slots.map { slot -> slot.toModel() } }
+
+ /** List of all available quick affordances. */
+ val affordances: Flow<List<AffordanceModel>> =
+ client.observeAffordances().map { affordances ->
+ affordances.map { affordance -> affordance.toModel() }
+ }
+
+ /** List of slot-affordance pairs, modeling what the user has currently chosen for each slot. */
+ val selections: Flow<List<SelectionModel>> =
+ client.observeSelections().map { selections ->
+ selections.map { selection -> selection.toModel() }
+ }
+
+ suspend fun isFeatureEnabled(): Boolean {
+ return withContext(backgroundDispatcher) { client.queryFlags().isFeatureEnabled() }
+ }
+
+ private fun List<Client.Flag>.isFeatureEnabled(): Boolean {
+ return find { flag ->
+ flag.name ==
+ Contract.FlagsTable.FLAG_NAME_CUSTOM_LOCK_SCREEN_QUICK_AFFORDANCES_ENABLED
+ }
+ ?.value == true
+ }
+
+ private fun Client.Slot.toModel(): SlotModel {
+ return SlotModel(
+ id = id,
+ maxSelectedQuickAffordances = capacity,
+ )
+ }
+
+ private fun Client.Affordance.toModel(): AffordanceModel {
+ return AffordanceModel(
+ id = id,
+ name = name,
+ iconResourceId = iconResourceId,
+ isEnabled = isEnabled,
+ enablementInstructions = enablementInstructions ?: emptyList(),
+ enablementActionText = enablementActionText,
+ enablementActionComponentName = enablementActionComponentName,
+ )
+ }
+
+ private fun Client.Selection.toModel(): SelectionModel {
+ return SelectionModel(
+ slotId = slotId,
+ affordanceId = affordanceId,
+ )
+ }
+}
diff --git a/src/com/android/customization/picker/quickaffordance/domain/interactor/KeyguardQuickAffordancePickerInteractor.kt b/src/com/android/customization/picker/quickaffordance/domain/interactor/KeyguardQuickAffordancePickerInteractor.kt
new file mode 100644
index 0000000..fbe303b
--- /dev/null
+++ b/src/com/android/customization/picker/quickaffordance/domain/interactor/KeyguardQuickAffordancePickerInteractor.kt
@@ -0,0 +1,96 @@
+/*
+ * 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.domain.interactor
+
+import android.graphics.drawable.Drawable
+import androidx.annotation.DrawableRes
+import com.android.customization.picker.quickaffordance.data.repository.KeyguardQuickAffordancePickerRepository
+import com.android.customization.picker.quickaffordance.shared.model.KeyguardQuickAffordancePickerAffordanceModel as AffordanceModel
+import com.android.customization.picker.quickaffordance.shared.model.KeyguardQuickAffordancePickerSelectionModel as SelectionModel
+import com.android.customization.picker.quickaffordance.shared.model.KeyguardQuickAffordancePickerSlotModel as SlotModel
+import com.android.systemui.shared.customization.data.content.CustomizationProviderClient as Client
+import javax.inject.Provider
+import kotlinx.coroutines.flow.Flow
+
+/**
+ * Single entry-point for all application state and business logic related to quick affordances on
+ * the lock screen.
+ */
+class KeyguardQuickAffordancePickerInteractor(
+ private val repository: KeyguardQuickAffordancePickerRepository,
+ private val client: Client,
+ private val snapshotRestorer: Provider<KeyguardQuickAffordanceSnapshotRestorer>,
+) {
+ /** List of slots available on the device. */
+ val slots: Flow<List<SlotModel>> = repository.slots
+
+ /** List of all available quick affordances. */
+ val affordances: Flow<List<AffordanceModel>> = repository.affordances
+
+ /** List of slot-affordance pairs, modeling what the user has currently chosen for each slot. */
+ val selections: Flow<List<SelectionModel>> = repository.selections
+
+ /**
+ * Selects an affordance with the given ID for a slot with the given ID.
+ *
+ * Note that the maximum affordance per slot is automatically managed. If trying to select an
+ * affordance for a slot that's already full, the oldest affordance is removed to make room.
+ *
+ * Note that if an affordance with the given ID is already selected on the slot with the given
+ * ID, that affordance is moved to the newest position on the slot.
+ */
+ suspend fun select(slotId: String, affordanceId: String) {
+ client.insertSelection(
+ slotId = slotId,
+ affordanceId = affordanceId,
+ )
+
+ 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(
+ slotId = slotId,
+ )
+
+ snapshotRestorer.get().storeSnapshot()
+ }
+
+ /** Returns a [Drawable] for the given resource ID, from the system UI package. */
+ suspend fun getAffordanceIcon(
+ @DrawableRes iconResourceId: Int,
+ ): Drawable {
+ return client.getAffordanceIcon(iconResourceId)
+ }
+
+ /** Returns `true` if the feature is enabled; `false` otherwise. */
+ suspend fun isFeatureEnabled(): Boolean {
+ return repository.isFeatureEnabled()
+ }
+}
diff --git a/src/com/android/customization/picker/quickaffordance/domain/interactor/KeyguardQuickAffordanceSnapshotRestorer.kt b/src/com/android/customization/picker/quickaffordance/domain/interactor/KeyguardQuickAffordanceSnapshotRestorer.kt
new file mode 100644
index 0000000..cb2dbdc
--- /dev/null
+++ b/src/com/android/customization/picker/quickaffordance/domain/interactor/KeyguardQuickAffordanceSnapshotRestorer.kt
@@ -0,0 +1,75 @@
+/*
+ * 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.domain.interactor
+
+import com.android.systemui.shared.customization.data.content.CustomizationProviderClient
+import com.android.wallpaper.picker.undo.domain.interactor.SnapshotRestorer
+import com.android.wallpaper.picker.undo.shared.model.RestorableSnapshot
+
+/** Handles state restoration for the quick affordances system. */
+class KeyguardQuickAffordanceSnapshotRestorer(
+ private val interactor: KeyguardQuickAffordancePickerInteractor,
+ private val client: CustomizationProviderClient,
+) : SnapshotRestorer {
+
+ private lateinit var snapshotUpdater: (RestorableSnapshot) -> Unit
+
+ suspend fun storeSnapshot() {
+ snapshotUpdater(snapshot())
+ }
+
+ override suspend fun setUpSnapshotRestorer(
+ updater: (RestorableSnapshot) -> Unit,
+ ): RestorableSnapshot {
+ snapshotUpdater = updater
+ return snapshot()
+ }
+
+ override suspend fun restoreToSnapshot(snapshot: RestorableSnapshot) {
+ val selections: List<Pair<String, String>> =
+ checkNotNull(snapshot.args[KEY_SELECTIONS]).split(SELECTION_SEPARATOR).map { selection
+ ->
+ val (slotId, affordanceId) = selection.split(SLOT_AFFORDANCE_SEPARATOR)
+ slotId to affordanceId
+ }
+
+ selections.forEach { (slotId, affordanceId) ->
+ interactor.select(
+ slotId,
+ affordanceId,
+ )
+ }
+ }
+
+ private suspend fun snapshot(): RestorableSnapshot {
+ return RestorableSnapshot(
+ mapOf(
+ KEY_SELECTIONS to
+ client.querySelections().joinToString(SELECTION_SEPARATOR) { selection ->
+ "${selection.slotId}${SLOT_AFFORDANCE_SEPARATOR}${selection.affordanceId}"
+ }
+ )
+ )
+ }
+
+ companion object {
+ private const val KEY_SELECTIONS = "selections"
+ private const val SLOT_AFFORDANCE_SEPARATOR = "->"
+ private const val SELECTION_SEPARATOR = "|"
+ }
+}
diff --git a/src/com/android/customization/picker/quickaffordance/shared/model/KeyguardQuickAffordancePickerAffordanceModel.kt b/src/com/android/customization/picker/quickaffordance/shared/model/KeyguardQuickAffordancePickerAffordanceModel.kt
new file mode 100644
index 0000000..1b18af7
--- /dev/null
+++ b/src/com/android/customization/picker/quickaffordance/shared/model/KeyguardQuickAffordancePickerAffordanceModel.kt
@@ -0,0 +1,45 @@
+/*
+ * 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.shared.model
+
+import androidx.annotation.DrawableRes
+
+/** Models a quick affordance. */
+data class KeyguardQuickAffordancePickerAffordanceModel(
+ val id: String,
+ val name: String,
+ /**
+ * The resource ID for a drawable of the icon. This is in the namespace of system UI so it
+ * should be queries from that package.
+ */
+ @DrawableRes val iconResourceId: Int,
+ /** Whether this quick affordance is enabled. */
+ val isEnabled: Boolean,
+ /** If not enabled, the list of user-visible steps to re-enable it. */
+ val enablementInstructions: List<String>,
+ /**
+ * If not enabled, an optional label for a button that takes the user to a destination where
+ * they can re-enable it.
+ */
+ val enablementActionText: String?,
+ /**
+ * If not enabled, an optional component name (package and action) for a button that takes the
+ * user to a destination where they can re-enable it.
+ */
+ val enablementActionComponentName: String?,
+)
diff --git a/src/com/android/customization/picker/quickaffordance/shared/model/KeyguardQuickAffordancePickerSelectionModel.kt b/src/com/android/customization/picker/quickaffordance/shared/model/KeyguardQuickAffordancePickerSelectionModel.kt
new file mode 100644
index 0000000..eea8b2a
--- /dev/null
+++ b/src/com/android/customization/picker/quickaffordance/shared/model/KeyguardQuickAffordancePickerSelectionModel.kt
@@ -0,0 +1,24 @@
+/*
+ * 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.shared.model
+
+/** Models a selection of an affordance on a slot. */
+data class KeyguardQuickAffordancePickerSelectionModel(
+ val slotId: String,
+ val affordanceId: String,
+)
diff --git a/src/com/android/customization/picker/quickaffordance/shared/model/KeyguardQuickAffordancePickerSlotModel.kt b/src/com/android/customization/picker/quickaffordance/shared/model/KeyguardQuickAffordancePickerSlotModel.kt
new file mode 100644
index 0000000..7e662e0
--- /dev/null
+++ b/src/com/android/customization/picker/quickaffordance/shared/model/KeyguardQuickAffordancePickerSlotModel.kt
@@ -0,0 +1,25 @@
+/*
+ * 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.shared.model
+
+/** Models a lock screen quick affordance slot (or position) where affordances can be displayed. */
+data class KeyguardQuickAffordancePickerSlotModel(
+ val id: String,
+ /** Maximum number of affordances allowed to be set on this slot. */
+ val maxSelectedQuickAffordances: Int,
+)
diff --git a/src/com/android/customization/picker/quickaffordance/ui/adapter/AffordancesAdapter.kt b/src/com/android/customization/picker/quickaffordance/ui/adapter/AffordancesAdapter.kt
new file mode 100644
index 0000000..b0dc350
--- /dev/null
+++ b/src/com/android/customization/picker/quickaffordance/ui/adapter/AffordancesAdapter.kt
@@ -0,0 +1,95 @@
+/*
+ * 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
new file mode 100644
index 0000000..acafef4
--- /dev/null
+++ b/src/com/android/customization/picker/quickaffordance/ui/adapter/SlotTabAdapter.kt
@@ -0,0 +1,70 @@
+/*
+ * 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.TextView
+import androidx.recyclerview.widget.RecyclerView
+import com.android.customization.picker.quickaffordance.ui.viewmodel.KeyguardQuickAffordanceSlotViewModel
+import com.android.wallpaper.R
+
+/** Adapts between lock screen quick affordance slot items and views. */
+class SlotTabAdapter : RecyclerView.Adapter<SlotTabAdapter.ViewHolder>() {
+
+ private val items = mutableListOf<KeyguardQuickAffordanceSlotViewModel>()
+
+ fun setItems(items: List<KeyguardQuickAffordanceSlotViewModel>) {
+ 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.keyguard_quick_affordance_slot_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/quickaffordance/ui/binder/KeyguardQuickAffordanceEnablementDialogBinder.kt b/src/com/android/customization/picker/quickaffordance/ui/binder/KeyguardQuickAffordanceEnablementDialogBinder.kt
new file mode 100644
index 0000000..809e09d
--- /dev/null
+++ b/src/com/android/customization/picker/quickaffordance/ui/binder/KeyguardQuickAffordanceEnablementDialogBinder.kt
@@ -0,0 +1,58 @@
+/*
+ * 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
new file mode 100644
index 0000000..389f8f6
--- /dev/null
+++ b/src/com/android/customization/picker/quickaffordance/ui/binder/KeyguardQuickAffordancePickerBinder.kt
@@ -0,0 +1,145 @@
+/*
+ * 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.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 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.quickaffordance.ui.adapter.SlotTabAdapter
+import com.android.customization.picker.quickaffordance.ui.viewmodel.KeyguardQuickAffordancePickerViewModel
+import com.android.wallpaper.R
+import kotlinx.coroutines.flow.distinctUntilChanged
+import kotlinx.coroutines.flow.map
+import kotlinx.coroutines.launch
+
+object KeyguardQuickAffordancePickerBinder {
+
+ /** Binds view with view-model for a lock screen quick affordance picker experience. */
+ @JvmStatic
+ fun bind(
+ view: View,
+ viewModel: KeyguardQuickAffordancePickerViewModel,
+ lifecycleOwner: LifecycleOwner,
+ ) {
+ val slotTabView: RecyclerView = view.requireViewById(R.id.slot_tabs)
+ val affordancesView: RecyclerView = view.requireViewById(R.id.affordances)
+
+ val slotTabAdapter = SlotTabAdapter()
+ slotTabView.adapter = slotTabAdapter
+ slotTabView.layoutManager =
+ LinearLayoutManager(view.context, RecyclerView.HORIZONTAL, false)
+ slotTabView.addItemDecoration(ItemSpacing())
+ val affordancesAdapter = AffordancesAdapter()
+ affordancesView.adapter = affordancesAdapter
+ affordancesView.layoutManager =
+ LinearLayoutManager(view.context, RecyclerView.HORIZONTAL, false)
+ affordancesView.addItemDecoration(ItemSpacing())
+
+ var dialog: Dialog? = null
+
+ lifecycleOwner.lifecycleScope.launch {
+ lifecycleOwner.repeatOnLifecycle(Lifecycle.State.STARTED) {
+ launch {
+ viewModel.slots
+ .map { slotById -> slotById.values }
+ .collect { slots -> slotTabAdapter.setItems(slots.toList()) }
+ }
+
+ launch {
+ viewModel.quickAffordances.collect { affordances ->
+ affordancesAdapter.setItems(affordances)
+ }
+ }
+
+ launch {
+ viewModel.dialog.distinctUntilChanged().collect { dialogRequest ->
+ dialog?.dismiss()
+ dialog =
+ if (dialogRequest != null) {
+ showDialog(
+ context = view.context,
+ request = dialogRequest,
+ onDismissed = viewModel::onDialogDismissed
+ )
+ } else {
+ null
+ }
+ }
+ }
+ }
+ }
+ }
+
+ private fun showDialog(
+ context: Context,
+ request: KeyguardQuickAffordancePickerViewModel.DialogViewModel,
+ onDismissed: () -> Unit,
+ ): Dialog {
+ val view: View =
+ LayoutInflater.from(context)
+ .inflate(
+ R.layout.keyguard_quick_affordance_enablement_dialog,
+ null,
+ )
+ KeyguardQuickAffordanceEnablementDialogBinder.bind(
+ view = view,
+ 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
new file mode 100644
index 0000000..9248d66
--- /dev/null
+++ b/src/com/android/customization/picker/quickaffordance/ui/binder/KeyguardQuickAffordancePreviewBinder.kt
@@ -0,0 +1,71 @@
+/*
+ * 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.app.Activity
+import android.os.Bundle
+import androidx.cardview.widget.CardView
+import androidx.lifecycle.Lifecycle
+import androidx.lifecycle.LifecycleOwner
+import androidx.lifecycle.flowWithLifecycle
+import androidx.lifecycle.lifecycleScope
+import com.android.customization.picker.quickaffordance.ui.viewmodel.KeyguardQuickAffordancePickerViewModel
+import com.android.systemui.shared.quickaffordance.shared.model.KeyguardQuickAffordancePreviewConstants
+import com.android.wallpaper.R
+import com.android.wallpaper.picker.customization.ui.binder.ScreenPreviewBinder
+import kotlinx.coroutines.launch
+
+object KeyguardQuickAffordancePreviewBinder {
+
+ /** Binds view for the preview of the lock screen. */
+ @JvmStatic
+ fun bind(
+ activity: Activity,
+ previewView: CardView,
+ viewModel: KeyguardQuickAffordancePickerViewModel,
+ lifecycleOwner: LifecycleOwner,
+ offsetToStart: Boolean,
+ ) {
+ val binding =
+ ScreenPreviewBinder.bind(
+ activity = activity,
+ previewView = previewView,
+ viewModel = viewModel.preview,
+ lifecycleOwner = lifecycleOwner,
+ offsetToStart = offsetToStart,
+ )
+
+ previewView.contentDescription =
+ previewView.context.getString(
+ R.string.lockscreen_wallpaper_preview_card_content_description
+ )
+
+ lifecycleOwner.lifecycleScope.launch {
+ viewModel.selectedSlotId
+ .flowWithLifecycle(lifecycleOwner.lifecycle, Lifecycle.State.STARTED)
+ .collect { slotId ->
+ binding.sendMessage(
+ KeyguardQuickAffordancePreviewConstants.MESSAGE_ID_SLOT_SELECTED,
+ Bundle().apply {
+ putString(KeyguardQuickAffordancePreviewConstants.KEY_SLOT_ID, slotId)
+ },
+ )
+ }
+ }
+ }
+}
diff --git a/src/com/android/customization/picker/quickaffordance/ui/binder/KeyguardQuickAffordanceSectionViewBinder.kt b/src/com/android/customization/picker/quickaffordance/ui/binder/KeyguardQuickAffordanceSectionViewBinder.kt
new file mode 100644
index 0000000..c8880b9
--- /dev/null
+++ b/src/com/android/customization/picker/quickaffordance/ui/binder/KeyguardQuickAffordanceSectionViewBinder.kt
@@ -0,0 +1,61 @@
+/*
+ * 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 androidx.core.view.isVisible
+import androidx.lifecycle.Lifecycle
+import androidx.lifecycle.LifecycleOwner
+import androidx.lifecycle.flowWithLifecycle
+import androidx.lifecycle.lifecycleScope
+import com.android.customization.picker.quickaffordance.ui.viewmodel.KeyguardQuickAffordancePickerViewModel
+import com.android.wallpaper.R
+import kotlinx.coroutines.flow.collectLatest
+import kotlinx.coroutines.launch
+
+object KeyguardQuickAffordanceSectionViewBinder {
+ fun bind(
+ view: View,
+ viewModel: KeyguardQuickAffordancePickerViewModel,
+ lifecycleOwner: LifecycleOwner,
+ onClicked: () -> Unit,
+ ) {
+ view.setOnClickListener { onClicked() }
+
+ val descriptionView: TextView =
+ view.requireViewById(R.id.keyguard_quick_affordance_description)
+ val icon1: ImageView = view.requireViewById(R.id.icon_1)
+ val icon2: ImageView = view.requireViewById(R.id.icon_2)
+
+ lifecycleOwner.lifecycleScope.launch {
+ viewModel.summary
+ .flowWithLifecycle(lifecycleOwner.lifecycle, Lifecycle.State.RESUMED)
+ .collectLatest { summary ->
+ descriptionView.text = summary.description
+
+ icon1.setImageDrawable(summary.icon1)
+ icon1.isVisible = summary.icon1 != null
+
+ icon2.setImageDrawable(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
new file mode 100644
index 0000000..51b98ef
--- /dev/null
+++ b/src/com/android/customization/picker/quickaffordance/ui/fragment/KeyguardQuickAffordancePickerFragment.kt
@@ -0,0 +1,91 @@
+/*
+ * 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.fragment
+
+import android.os.Bundle
+import android.view.LayoutInflater
+import android.view.View
+import android.view.ViewGroup
+import androidx.lifecycle.ViewModelProvider
+import androidx.lifecycle.get
+import com.android.customization.module.ThemePickerInjector
+import com.android.customization.picker.quickaffordance.ui.binder.KeyguardQuickAffordancePickerBinder
+import com.android.customization.picker.quickaffordance.ui.binder.KeyguardQuickAffordancePreviewBinder
+import com.android.customization.picker.quickaffordance.ui.viewmodel.KeyguardQuickAffordancePickerViewModel
+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)
+class KeyguardQuickAffordancePickerFragment : AppbarFragment() {
+ companion object {
+ const val DESTINATION_ID = "quick_affordances"
+ @JvmStatic
+ fun newInstance(): KeyguardQuickAffordancePickerFragment {
+ return KeyguardQuickAffordancePickerFragment()
+ }
+ }
+
+ override fun onCreateView(
+ inflater: LayoutInflater,
+ container: ViewGroup?,
+ savedInstanceState: Bundle?
+ ): View {
+ val view =
+ inflater.inflate(
+ R.layout.fragment_lock_screen_quick_affordances,
+ container,
+ false,
+ )
+ setUpToolbar(view)
+ val injector = InjectorProvider.getInjector() as ThemePickerInjector
+ val viewModel: KeyguardQuickAffordancePickerViewModel =
+ ViewModelProvider(
+ requireActivity(),
+ 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(),
+ previewView = view.requireViewById(R.id.preview),
+ viewModel = viewModel,
+ lifecycleOwner = this,
+ offsetToStart =
+ injector.getDisplayUtils(requireActivity()).isOnWallpaperDisplay(requireActivity())
+ )
+ KeyguardQuickAffordancePickerBinder.bind(
+ view = view,
+ viewModel = viewModel,
+ lifecycleOwner = this,
+ )
+ return view
+ }
+
+ override fun getDefaultTitle(): CharSequence {
+ return requireContext().getString(R.string.keyguard_quick_affordance_title)
+ }
+}
diff --git a/src/com/android/customization/picker/quickaffordance/ui/section/KeyguardQuickAffordanceSectionController.kt b/src/com/android/customization/picker/quickaffordance/ui/section/KeyguardQuickAffordanceSectionController.kt
new file mode 100644
index 0000000..6b35d7c
--- /dev/null
+++ b/src/com/android/customization/picker/quickaffordance/ui/section/KeyguardQuickAffordanceSectionController.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.quickaffordance.ui.section
+
+import android.content.Context
+import android.view.LayoutInflater
+import androidx.lifecycle.LifecycleOwner
+import com.android.customization.picker.quickaffordance.domain.interactor.KeyguardQuickAffordancePickerInteractor
+import com.android.customization.picker.quickaffordance.ui.binder.KeyguardQuickAffordanceSectionViewBinder
+import com.android.customization.picker.quickaffordance.ui.fragment.KeyguardQuickAffordancePickerFragment
+import com.android.customization.picker.quickaffordance.ui.view.KeyguardQuickAffordanceSectionView
+import com.android.customization.picker.quickaffordance.ui.viewmodel.KeyguardQuickAffordancePickerViewModel
+import com.android.wallpaper.R
+import com.android.wallpaper.model.CustomizationSectionController
+import com.android.wallpaper.model.CustomizationSectionController.CustomizationSectionNavigationController as NavigationController
+import kotlinx.coroutines.runBlocking
+
+class KeyguardQuickAffordanceSectionController(
+ private val navigationController: NavigationController,
+ private val interactor: KeyguardQuickAffordancePickerInteractor,
+ private val viewModel: KeyguardQuickAffordancePickerViewModel,
+ private val lifecycleOwner: LifecycleOwner,
+) : CustomizationSectionController<KeyguardQuickAffordanceSectionView> {
+
+ private val isFeatureEnabled: Boolean = runBlocking { interactor.isFeatureEnabled() }
+
+ override fun isAvailable(context: Context?): Boolean {
+ return isFeatureEnabled
+ }
+
+ override fun createView(context: Context?): KeyguardQuickAffordanceSectionView {
+ val view =
+ LayoutInflater.from(context)
+ .inflate(
+ R.layout.keyguard_quick_affordance_section_view,
+ null,
+ ) as KeyguardQuickAffordanceSectionView
+ KeyguardQuickAffordanceSectionViewBinder.bind(
+ view = view,
+ viewModel = viewModel,
+ lifecycleOwner = lifecycleOwner,
+ ) {
+ navigationController.navigateTo(KeyguardQuickAffordancePickerFragment.newInstance())
+ }
+ return view
+ }
+}
diff --git a/src/com/android/customization/picker/quickaffordance/ui/view/KeyguardQuickAffordanceSectionView.kt b/src/com/android/customization/picker/quickaffordance/ui/view/KeyguardQuickAffordanceSectionView.kt
new file mode 100644
index 0000000..daace7d
--- /dev/null
+++ b/src/com/android/customization/picker/quickaffordance/ui/view/KeyguardQuickAffordanceSectionView.kt
@@ -0,0 +1,31 @@
+/*
+ * 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.view
+
+import android.content.Context
+import android.util.AttributeSet
+import com.android.wallpaper.picker.SectionView
+
+class KeyguardQuickAffordanceSectionView(
+ context: Context?,
+ attrs: AttributeSet?,
+) :
+ SectionView(
+ context,
+ attrs,
+ )
diff --git a/src/com/android/customization/picker/quickaffordance/ui/viewmodel/KeyguardQuickAffordancePickerViewModel.kt b/src/com/android/customization/picker/quickaffordance/ui/viewmodel/KeyguardQuickAffordancePickerViewModel.kt
new file mode 100644
index 0000000..d879045
--- /dev/null
+++ b/src/com/android/customization/picker/quickaffordance/ui/viewmodel/KeyguardQuickAffordancePickerViewModel.kt
@@ -0,0 +1,389 @@
+/*
+ * 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.content.Intent
+import android.graphics.drawable.Drawable
+import android.os.Bundle
+import androidx.annotation.DrawableRes
+import androidx.lifecycle.ViewModel
+import androidx.lifecycle.ViewModelProvider
+import androidx.lifecycle.viewModelScope
+import com.android.customization.picker.quickaffordance.domain.interactor.KeyguardQuickAffordancePickerInteractor
+import com.android.systemui.shared.customization.data.content.CustomizationProviderContract
+import com.android.systemui.shared.keyguard.shared.model.KeyguardQuickAffordanceSlots
+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.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.util.PreviewUtils
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.flow.Flow
+import kotlinx.coroutines.flow.MutableStateFlow
+import kotlinx.coroutines.flow.StateFlow
+import kotlinx.coroutines.flow.asStateFlow
+import kotlinx.coroutines.flow.combine
+import kotlinx.coroutines.flow.map
+import kotlinx.coroutines.launch
+import kotlinx.coroutines.suspendCancellableCoroutine
+
+/** Models UI state for a lock screen quick affordance picker experience. */
+@OptIn(ExperimentalCoroutinesApi::class)
+class KeyguardQuickAffordancePickerViewModel
+private constructor(
+ context: Context,
+ private val quickAffordanceInteractor: KeyguardQuickAffordancePickerInteractor,
+ undoInteractor: UndoInteractor,
+ private val wallpaperInfoFactory: CurrentWallpaperInfoFactory,
+) : ViewModel() {
+
+ @SuppressLint("StaticFieldLeak") private val applicationContext = context.applicationContext
+
+ val preview =
+ ScreenPreviewViewModel(
+ previewUtils =
+ PreviewUtils(
+ context = applicationContext,
+ authority =
+ applicationContext.getString(
+ R.string.lock_screen_preview_provider_authority,
+ ),
+ ),
+ initialExtrasProvider = {
+ Bundle().apply {
+ putString(
+ KeyguardQuickAffordancePreviewConstants.KEY_INITIALLY_SELECTED_SLOT_ID,
+ selectedSlotId.value,
+ )
+ }
+ },
+ wallpaperInfoProvider = {
+ suspendCancellableCoroutine { continuation ->
+ wallpaperInfoFactory.createCurrentWallpaperInfos(
+ { homeWallpaper, lockWallpaper, _ ->
+ continuation.resume(lockWallpaper ?: homeWallpaper, null)
+ },
+ /* forceRefresh= */ true,
+ )
+ }
+ },
+ )
+
+ val undo: UndoViewModel =
+ UndoViewModel(
+ interactor = undoInteractor,
+ )
+
+ private val _selectedSlotId = MutableStateFlow<String?>(null)
+ val selectedSlotId: StateFlow<String?> = _selectedSlotId.asStateFlow()
+
+ /** View-models for each slot, keyed by slot ID. */
+ val slots: Flow<Map<String, KeyguardQuickAffordanceSlotViewModel>> =
+ combine(
+ quickAffordanceInteractor.slots,
+ 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()
+ }
+
+ /** The list of all available quick affordances for the selected slot. */
+ val quickAffordances: Flow<List<KeyguardQuickAffordanceViewModel>> =
+ 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 =
+ selections
+ .filter { selection -> selection.slotId == selectedSlot.id }
+ .map { selection -> selection.affordanceId }
+ .toSet()
+ 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) {
+ {
+ viewModelScope.launch {
+ if (isSelected) {
+ quickAffordanceInteractor.unselect(
+ slotId = selectedSlot.id,
+ affordanceId = affordance.id,
+ )
+ } else {
+ quickAffordanceInteractor.select(
+ slotId = selectedSlot.id,
+ affordanceId = affordance.id,
+ )
+ }
+ }
+ }
+ } else {
+ {
+ showEnablementDialog(
+ icon = affordanceIcon,
+ name = affordance.name,
+ instructions = affordance.enablementInstructions,
+ actionText = affordance.enablementActionText,
+ actionComponentName =
+ affordance.enablementActionComponentName,
+ )
+ }
+ },
+ isEnabled = affordance.isEnabled,
+ )
+ }
+ }
+
+ @SuppressLint("UseCompatLoadingForDrawables")
+ val summary: Flow<KeyguardQuickAffordanceSummaryViewModel> =
+ slots.map { slots ->
+ val icon2 =
+ slots[KeyguardQuickAffordanceSlots.SLOT_ID_BOTTOM_END]
+ ?.selectedQuickAffordances
+ ?.firstOrNull()
+ ?.icon
+ val icon1 =
+ slots[KeyguardQuickAffordanceSlots.SLOT_ID_BOTTOM_START]
+ ?.selectedQuickAffordances
+ ?.firstOrNull()
+ ?.icon
+
+ KeyguardQuickAffordanceSummaryViewModel(
+ description = toDescriptionText(context, slots),
+ icon1 = icon1
+ ?: if (icon2 == null) {
+ context.getDrawable(R.drawable.link_off)
+ } else {
+ null
+ },
+ icon2 = icon2,
+ )
+ }
+
+ private val _dialog = MutableStateFlow<DialogViewModel?>(null)
+ /**
+ * The current dialog to show. If `null`, no dialog should be shown.
+ *
+ * When the dialog is dismissed, [onDialogDismissed] must be called.
+ */
+ val dialog: Flow<DialogViewModel?> = _dialog.asStateFlow()
+
+ /** Notifies that the dialog has been dismissed in the UI. */
+ fun onDialogDismissed() {
+ _dialog.value = null
+ }
+
+ private fun showEnablementDialog(
+ icon: Drawable,
+ name: String,
+ instructions: List<String>,
+ actionText: String?,
+ actionComponentName: String?,
+ ) {
+ _dialog.value =
+ DialogViewModel(
+ icon = icon,
+ name = name,
+ instructions = instructions,
+ actionText = actionText
+ ?: applicationContext.getString(
+ R.string.keyguard_affordance_enablement_dialog_dismiss_button
+ ),
+ intent = actionComponentName.toIntent(),
+ )
+ }
+
+ @SuppressLint("UseCompatLoadingForDrawables")
+ private fun none(
+ slotId: String,
+ isSelected: Boolean,
+ ): KeyguardQuickAffordanceViewModel {
+ return KeyguardQuickAffordanceViewModel.none(
+ context = applicationContext,
+ isSelected = isSelected,
+ onSelected = {
+ viewModelScope.launch { quickAffordanceInteractor.unselectAll(slotId) }
+ },
+ )
+ }
+
+ private fun getSlotName(slotId: String): String {
+ return applicationContext.getString(
+ when (slotId) {
+ KeyguardQuickAffordanceSlots.SLOT_ID_BOTTOM_START ->
+ R.string.keyguard_slot_name_bottom_start
+ KeyguardQuickAffordanceSlots.SLOT_ID_BOTTOM_END ->
+ R.string.keyguard_slot_name_bottom_end
+ else -> error("No name for slot with ID of \"$slotId\"!")
+ }
+ )
+ }
+
+ private suspend fun getAffordanceIcon(@DrawableRes iconResourceId: Int): Drawable {
+ return quickAffordanceInteractor.getAffordanceIcon(iconResourceId)
+ }
+
+ private fun String?.toIntent(): Intent? {
+ if (isNullOrEmpty()) {
+ return null
+ }
+
+ val splitUp =
+ split(
+ CustomizationProviderContract.LockScreenQuickAffordances.AffordanceTable
+ .COMPONENT_NAME_SEPARATOR
+ )
+ check(splitUp.size == 1 || splitUp.size == 2) {
+ "Illegal component name \"$this\". Must be either just an action or a package and an" +
+ " action separated by a" +
+ " \"${CustomizationProviderContract.LockScreenQuickAffordances.AffordanceTable.COMPONENT_NAME_SEPARATOR}\"!"
+ }
+
+ return Intent(splitUp.last()).apply {
+ if (splitUp.size > 1) {
+ setPackage(splitUp[0])
+ }
+ }
+ }
+
+ /** 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 {
+ val bottomStartAffordanceName =
+ slots[KeyguardQuickAffordanceSlots.SLOT_ID_BOTTOM_START]
+ ?.selectedQuickAffordances
+ ?.firstOrNull()
+ ?.contentDescription
+ val bottomEndAffordanceName =
+ slots[KeyguardQuickAffordanceSlots.SLOT_ID_BOTTOM_END]
+ ?.selectedQuickAffordances
+ ?.firstOrNull()
+ ?.contentDescription
+
+ return when {
+ !bottomStartAffordanceName.isNullOrEmpty() &&
+ !bottomEndAffordanceName.isNullOrEmpty() -> {
+ context.getString(
+ R.string.keyguard_quick_affordance_two_selected_template,
+ bottomStartAffordanceName,
+ bottomEndAffordanceName,
+ )
+ }
+ !bottomStartAffordanceName.isNullOrEmpty() -> bottomStartAffordanceName
+ !bottomEndAffordanceName.isNullOrEmpty() -> bottomEndAffordanceName
+ else -> context.getString(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,
+ ) : ViewModelProvider.Factory {
+ override fun <T : ViewModel> create(modelClass: Class<T>): T {
+ @Suppress("UNCHECKED_CAST")
+ return KeyguardQuickAffordancePickerViewModel(
+ context = context,
+ quickAffordanceInteractor = quickAffordanceInteractor,
+ undoInteractor = undoInteractor,
+ wallpaperInfoFactory = wallpaperInfoFactory,
+ )
+ 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
new file mode 100644
index 0000000..bb9b29b
--- /dev/null
+++ b/src/com/android/customization/picker/quickaffordance/ui/viewmodel/KeyguardQuickAffordanceSlotViewModel.kt
@@ -0,0 +1,44 @@
+/*
+ * 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
+
+/** Models UI state for a single lock screen quick affordance slot in a picker experience. */
+data class KeyguardQuickAffordanceSlotViewModel(
+ /** User-visible name for the slot. */
+ val name: String,
+
+ /** Whether this is the currently-selected slot in the picker. */
+ val isSelected: Boolean,
+
+ /**
+ * The list of quick affordances selected for this slot.
+ *
+ * Useful for preview.
+ */
+ val selectedQuickAffordances: List<KeyguardQuickAffordanceViewModel>,
+
+ /**
+ * The maximum number of quick affordances that can be selected for this slot.
+ *
+ * Useful for picker and preview.
+ */
+ val maxSelectedQuickAffordances: Int,
+
+ /** Notifies that the slot has been clicked by the user. */
+ val onClicked: (() -> Unit)?,
+)
diff --git a/src/com/android/customization/picker/quickaffordance/ui/viewmodel/KeyguardQuickAffordanceSummaryViewModel.kt b/src/com/android/customization/picker/quickaffordance/ui/viewmodel/KeyguardQuickAffordanceSummaryViewModel.kt
new file mode 100644
index 0000000..d5fc79b
--- /dev/null
+++ b/src/com/android/customization/picker/quickaffordance/ui/viewmodel/KeyguardQuickAffordanceSummaryViewModel.kt
@@ -0,0 +1,26 @@
+/*
+ * 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.graphics.drawable.Drawable
+
+data class KeyguardQuickAffordanceSummaryViewModel(
+ val description: String,
+ val icon1: Drawable?,
+ val icon2: Drawable?,
+)
diff --git a/src/com/android/customization/picker/quickaffordance/ui/viewmodel/KeyguardQuickAffordanceViewModel.kt b/src/com/android/customization/picker/quickaffordance/ui/viewmodel/KeyguardQuickAffordanceViewModel.kt
new file mode 100644
index 0000000..d720b0c
--- /dev/null
+++ b/src/com/android/customization/picker/quickaffordance/ui/viewmodel/KeyguardQuickAffordanceViewModel.kt
@@ -0,0 +1,63 @@
+/*
+ * 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/theme/CustomThemeNameFragment.java b/src/com/android/customization/picker/theme/CustomThemeNameFragment.java
index 6f20a1a..ea9099f 100644
--- a/src/com/android/customization/picker/theme/CustomThemeNameFragment.java
+++ b/src/com/android/customization/picker/theme/CustomThemeNameFragment.java
@@ -69,7 +69,7 @@
mTitle = view.findViewById(R.id.component_options_title);
mTitle.setText(mTitleResId);
CurrentWallpaperInfoFactory currentWallpaperFactory = InjectorProvider.getInjector()
- .getCurrentWallpaperFactory(getActivity().getApplicationContext());
+ .getCurrentWallpaperInfoFactory(getActivity().getApplicationContext());
CustomizationInjector injector = (CustomizationInjector) InjectorProvider.getInjector();
mCustomizationPreferences = injector.getCustomizationPreferences(getContext());
diff --git a/src/com/android/customization/picker/theme/ThemeFragment.java b/src/com/android/customization/picker/theme/ThemeFragment.java
index f5d56ca..3a9a56f 100644
--- a/src/com/android/customization/picker/theme/ThemeFragment.java
+++ b/src/com/android/customization/picker/theme/ThemeFragment.java
@@ -115,7 +115,7 @@
mLoading = view.findViewById(R.id.loading_indicator);
mError = view.findViewById(R.id.error_section);
mCurrentWallpaperFactory = InjectorProvider.getInjector()
- .getCurrentWallpaperFactory(getActivity().getApplicationContext());
+ .getCurrentWallpaperInfoFactory(getActivity().getApplicationContext());
mOptionsContainer = view.findViewById(R.id.options_container);
mThemeOptionPreviewer = new ThemeOptionPreviewer(
diff --git a/src/com/android/customization/widget/OptionSelectorController.java b/src/com/android/customization/widget/OptionSelectorController.java
index d76449d..d1351c9 100644
--- a/src/com/android/customization/widget/OptionSelectorController.java
+++ b/src/com/android/customization/widget/OptionSelectorController.java
@@ -44,8 +44,6 @@
import com.android.customization.model.CustomizationManager;
import com.android.customization.model.CustomizationOption;
import com.android.wallpaper.R;
-import com.android.wallpaper.widget.GridPaddingDecoration;
-import com.android.wallpaper.widget.GridRowSpacerDecoration;
import java.util.HashSet;
import java.util.List;
@@ -286,17 +284,9 @@
Resources res = mContainer.getContext().getResources();
mContainer.setAdapter(mAdapter);
- mContainer.setItemAnimator(null);
- final int padding = res.getDimensionPixelSize(
- R.dimen.option_tile_grid_padding_horizontal);
- final int fixWidth = res.getDimensionPixelSize(R.dimen.options_container_width);
final DisplayMetrics metrics = new DisplayMetrics();
mContainer.getContext().getSystemService(WindowManager.class)
.getDefaultDisplay().getMetrics(metrics);
- // This is based on the assumption that the parent view is the same width as the screen.
- final int availableDynamicWidth = metrics.widthPixels - 2 * res.getDimensionPixelSize(
- R.dimen.section_horizontal_padding);
- final int availableWidth = (fixWidth != 0) ? fixWidth : availableDynamicWidth;
final boolean hasDecoration = mContainer.getItemDecorationCount() != 0;
if (mUseGrid) {
@@ -304,24 +294,15 @@
GridLayoutManager gridLayoutManager = new GridLayoutManager(mContainer.getContext(),
numColumns);
mContainer.setLayoutManager(gridLayoutManager);
- if (!hasDecoration) {
- mContainer.addItemDecoration(new GridPaddingDecoration(padding, 0));
- }
- // Measure RecyclerView to get to the total amount of space used by all options.
- mContainer.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED);
- while (mContainer.getMeasuredWidth() > availableWidth && numColumns > 1) {
- numColumns -= 1;
- gridLayoutManager.setSpanCount(numColumns);
- mContainer.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED);
- }
- if (!hasDecoration && numColumns > 1) {
- mContainer.addItemDecoration(new GridRowSpacerDecoration(2 * padding));
- }
} else {
+ final int padding = res.getDimensionPixelSize(
+ R.dimen.option_tile_linear_padding_horizontal);
final int widthPerItem = res.getDimensionPixelSize(R.dimen.option_tile_width) + (
hasDecoration ? 0 : 2 * padding);
mContainer.setLayoutManager(new LinearLayoutManager(mContainer.getContext(),
LinearLayoutManager.HORIZONTAL, false));
+ mContainer.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED);
+ int availableWidth = metrics.widthPixels;
int extraSpace = availableWidth - mContainer.getMeasuredWidth();
if (extraSpace >= 0) {
mContainer.setOverScrollMode(View.OVER_SCROLL_NEVER);
@@ -333,10 +314,8 @@
- mContainer.getPaddingLeft();
int itemEndMargin =
spaceBetweenItems / (int) mLinearLayoutHorizontalDisplayOptionsMax;
- if (itemEndMargin <= 0) {
- itemEndMargin = res.getDimensionPixelOffset(
- R.dimen.option_tile_margin_horizontal);
- }
+ itemEndMargin = Math.max(itemEndMargin, res.getDimensionPixelOffset(
+ R.dimen.option_tile_margin_horizontal));
mContainer.addItemDecoration(new ItemEndHorizontalSpaceItemDecoration(
mContainer.getContext(), itemEndMargin));
return;
diff --git a/src_override/com/android/wallpaper/config/Flags.java b/src_override/com/android/wallpaper/config/Flags.java
index 76549cb..d35d88f 100644
--- a/src_override/com/android/wallpaper/config/Flags.java
+++ b/src_override/com/android/wallpaper/config/Flags.java
@@ -16,5 +16,4 @@
package com.android.wallpaper.config;
public class Flags extends BaseFlags {
- public static boolean enableClockCustomization = false;
}
diff --git a/src_override/com/android/wallpaper/module/WallpapersInjector.java b/src_override/com/android/wallpaper/module/WallpapersInjector.java
deleted file mode 100755
index 9f8fe9c..0000000
--- a/src_override/com/android/wallpaper/module/WallpapersInjector.java
+++ /dev/null
@@ -1,112 +0,0 @@
-/*
- * Copyright (C) 2018 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.wallpaper.module;
-
-import android.content.Context;
-import android.content.Intent;
-import android.net.Uri;
-
-import androidx.fragment.app.Fragment;
-
-import com.android.wallpaper.model.CategoryProvider;
-import com.android.wallpaper.model.WallpaperInfo;
-import com.android.wallpaper.monitor.PerformanceMonitor;
-import com.android.wallpaper.picker.CustomizationPickerActivity;
-import com.android.wallpaper.picker.ImagePreviewFragment;
-
-/**
- * A concrete, real implementation of the dependency provider.
- */
-public class WallpapersInjector extends BaseWallpaperInjector {
- private CategoryProvider mCategoryProvider;
- private UserEventLogger mUserEventLogger;
- private WallpaperRotationRefresher mWallpaperRotationRefresher;
- private PerformanceMonitor mPerformanceMonitor;
-
- @Override
- public synchronized CategoryProvider getCategoryProvider(Context context) {
- if (mCategoryProvider == null) {
- mCategoryProvider = new DefaultCategoryProvider(context.getApplicationContext());
- }
- return mCategoryProvider;
- }
-
- @Override
- public synchronized UserEventLogger getUserEventLogger(Context context) {
- if (mUserEventLogger == null) {
- mUserEventLogger = new NoOpUserEventLogger();
- }
- return mUserEventLogger;
- }
-
- @Override
- public synchronized WallpaperRotationRefresher getWallpaperRotationRefresher() {
- if (mWallpaperRotationRefresher == null) {
- mWallpaperRotationRefresher = new WallpaperRotationRefresher() {
- @Override
- public void refreshWallpaper(Context context, Listener listener) {
- // Not implemented
- listener.onError();
- }
- };
- }
- return mWallpaperRotationRefresher;
- }
-
- @Override
- public Fragment getPreviewFragment(
- Context context,
- WallpaperInfo wallpaperInfo,
- int mode,
- boolean viewAsHome,
- boolean viewFullScreen,
- boolean testingModeEnabled) {
- return ImagePreviewFragment.newInstance(wallpaperInfo, mode, viewAsHome, viewFullScreen,
- testingModeEnabled);
- }
-
- @Override
- public Intent getDeepLinkRedirectIntent(Context context, Uri uri) {
- Intent intent = new Intent();
- intent.setClass(context, CustomizationPickerActivity.class);
- intent.setData(uri);
- intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK | Intent.FLAG_ACTIVITY_CLEAR_TASK);
- return intent;
- }
-
- @Override
- public synchronized PerformanceMonitor getPerformanceMonitor() {
- if (mPerformanceMonitor == null) {
- mPerformanceMonitor = new PerformanceMonitor() {
- @Override
- public void recordFullResPreviewLoadedMemorySnapshot() {
- // No Op
- }
- };
- }
- return mPerformanceMonitor;
- }
-
- @Override
- public synchronized LoggingOptInStatusProvider getLoggingOptInStatusProvider(Context context) {
- return null;
- }
-
- @Override
- public String getDownloadableIntentAction() {
- return null;
- }
-}
diff --git a/tests/Android.bp b/tests/Android.bp
new file mode 100644
index 0000000..9fed740
--- /dev/null
+++ b/tests/Android.bp
@@ -0,0 +1,47 @@
+// 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.
+//
+
+//
+// Build rule for WallpaperPicker2 tests
+//
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+android_test {
+ name: "ThemePickerTests",
+
+ defaults: ["ThemePicker_defaults"],
+ srcs: [
+ "src/**/*.java",
+ "src/**/*.kt",
+ ],
+ static_libs: [
+ "WallpaperPicker2TestLib",
+ "androidx.test.rules",
+ "junit",
+ "kotlinx_coroutines_test",
+ "truth-prebuilt",
+ ],
+ libs: [
+ "android.test.runner",
+ "android.test.base",
+ "android.test.mock",
+ ],
+
+ kotlincflags: ["-Xjvm-default=enable"],
+ platform_apis: true,
+ test_suites: ["device-tests"],
+}
diff --git a/tests/AndroidManifest.xml b/tests/AndroidManifest.xml
new file mode 100644
index 0000000..2fd6b3f
--- /dev/null
+++ b/tests/AndroidManifest.xml
@@ -0,0 +1,27 @@
+<?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.
+-->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.android.wallpaper">
+
+ <application>
+ <uses-library android:name="android.test.runner" />
+ </application>
+
+ <instrumentation android:name="androidx.test.runner.AndroidJUnitRunner"
+ android:targetPackage="com.android.wallpaper"
+ android:label="Tests for ThemePicker" />
+
+</manifest>
diff --git a/tests/AndroidTest.xml b/tests/AndroidTest.xml
new file mode 100644
index 0000000..be2119b
--- /dev/null
+++ b/tests/AndroidTest.xml
@@ -0,0 +1,28 @@
+<?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.
+-->
+<configuration description="Runs Tests for ThemePicker.">
+ <target_preparer class="com.android.tradefed.targetprep.TestAppInstallSetup">
+ <option name="test-file-name" value="ThemePickerTests.apk" />
+ </target_preparer>
+
+ <option name="test-suite-tag" value="apct" />
+ <option name="test-tag" value="ThemePickerTests" />
+ <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
+ <option name="package" value="com.android.wallpaper" />
+ <option name="runner" value="androidx.test.runner.AndroidJUnitRunner" />
+ <option name="hidden-api-checks" value="false"/>
+ </test>
+</configuration>
diff --git a/tests/robotests/Android.bp b/tests/robotests/Android.bp
new file mode 100644
index 0000000..e0a37c2
--- /dev/null
+++ b/tests/robotests/Android.bp
@@ -0,0 +1,17 @@
+
+package {
+ default_applicable_licenses: ["Android-Apache-2.0"],
+}
+android_robolectric_test {
+ name: "ThemePickerRoboTests",
+ srcs: [
+ "src/**/*.java",
+ "src/**/*.kt",
+ ],
+ java_resource_dirs: ["config"],
+ libs: [
+ "androidx.test.core",
+ "androidx.test.runner",
+ ],
+ instrumentation_for: "ThemePicker",
+}
diff --git a/tests/robotests/AndroidManifest.xml b/tests/robotests/AndroidManifest.xml
new file mode 100644
index 0000000..753aa9e
--- /dev/null
+++ b/tests/robotests/AndroidManifest.xml
@@ -0,0 +1,20 @@
+<!--
+ ~ 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.
+ -->
+
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+ package="com.android.customization">
+ <application/>
+</manifest>
diff --git a/tests/robotests/config/robolectric.properties b/tests/robotests/config/robolectric.properties
new file mode 100644
index 0000000..fab7251
--- /dev/null
+++ b/tests/robotests/config/robolectric.properties
@@ -0,0 +1 @@
+sdk=NEWEST_SDK
diff --git a/robolectric_tests/res/values/overlayable_icons_test.xml b/tests/robotests/res/values/overlayable_icons_test.xml
similarity index 100%
rename from robolectric_tests/res/values/overlayable_icons_test.xml
rename to tests/robotests/res/values/overlayable_icons_test.xml
diff --git a/robolectric_tests/src/com/android/customization/model/clock/BaseClockManagerTest.java b/tests/robotests/src/com/android/customization/model/clock/BaseClockManagerTest.java
similarity index 100%
rename from robolectric_tests/src/com/android/customization/model/clock/BaseClockManagerTest.java
rename to tests/robotests/src/com/android/customization/model/clock/BaseClockManagerTest.java
diff --git a/robolectric_tests/src/com/android/customization/model/clock/ClockManagerTest.java b/tests/robotests/src/com/android/customization/model/clock/ClockManagerTest.java
similarity index 100%
rename from robolectric_tests/src/com/android/customization/model/clock/ClockManagerTest.java
rename to tests/robotests/src/com/android/customization/model/clock/ClockManagerTest.java
diff --git a/robolectric_tests/src/com/android/customization/model/color/ColorCustomizationManagerTest.kt b/tests/robotests/src/com/android/customization/model/color/ColorCustomizationManagerTest.kt
similarity index 78%
rename from robolectric_tests/src/com/android/customization/model/color/ColorCustomizationManagerTest.kt
rename to tests/robotests/src/com/android/customization/model/color/ColorCustomizationManagerTest.kt
index f6f4227..80d01c6 100644
--- a/robolectric_tests/src/com/android/customization/model/color/ColorCustomizationManagerTest.kt
+++ b/tests/robotests/src/com/android/customization/model/color/ColorCustomizationManagerTest.kt
@@ -18,8 +18,8 @@
import android.app.WallpaperColors
import android.graphics.Color
import com.android.customization.model.CustomizationManager
-import com.android.customization.model.ResourceConstants.OVERLAY_CATEGORY_SYSTEM_PALETTE
import com.android.customization.model.ResourceConstants.OVERLAY_CATEGORY_COLOR
+import com.android.customization.model.ResourceConstants.OVERLAY_CATEGORY_SYSTEM_PALETTE
import com.android.customization.model.color.ColorOptionsProvider.COLOR_SOURCE_HOME
import com.android.customization.model.color.ColorOptionsProvider.COLOR_SOURCE_PRESET
import com.android.customization.model.color.ColorOptionsProvider.OVERLAY_COLOR_BOTH
@@ -30,6 +30,7 @@
import com.google.common.truth.Truth.assertThat
import org.json.JSONObject
import org.junit.Before
+import org.junit.Ignore
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
@@ -41,15 +42,12 @@
import org.robolectric.RobolectricTestRunner
import org.robolectric.RuntimeEnvironment
-/**
- * Tests of {@link ColorCustomizationManager}.
- */
+/** Tests of {@link ColorCustomizationManager}. */
// TODO(b/222433744): most of these tests are failing due to the manager apk missing in the image
@RunWith(RobolectricTestRunner::class)
class ColorCustomizationManagerTest {
- @get:Rule
- val rule: MockitoRule = MockitoJUnit.rule()
+ @get:Rule val rule: MockitoRule = MockitoJUnit.rule()
@Mock private lateinit var provider: ColorOptionsProvider
@Mock private lateinit var mockOM: OverlayManagerCompat
@@ -64,15 +62,19 @@
}
@Test
+ @Ignore("b/260925899")
fun testParseSettings() {
val source = COLOR_SOURCE_HOME
val style = Style.SPRITZ
val someColor = "aabbcc"
val someOtherColor = "bbccdd"
- val settings = mapOf(OVERLAY_CATEGORY_SYSTEM_PALETTE to someColor,
+ val settings =
+ mapOf(
+ OVERLAY_CATEGORY_SYSTEM_PALETTE to someColor,
OVERLAY_CATEGORY_COLOR to someOtherColor,
OVERLAY_COLOR_SOURCE to source,
- ColorOption.TIMESTAMP_FIELD to "12345")
+ ColorOption.TIMESTAMP_FIELD to "12345"
+ )
val json = JSONObject(settings).toString()
manager.parseSettings(json)
@@ -82,10 +84,11 @@
assertThat(manager.currentOverlays.size).isEqualTo(2)
assertThat(manager.currentOverlays.get(OVERLAY_CATEGORY_COLOR)).isEqualTo(someOtherColor)
assertThat(manager.currentOverlays.get(OVERLAY_CATEGORY_SYSTEM_PALETTE))
- .isEqualTo(someColor)
+ .isEqualTo(someColor)
}
@Test
+ @Ignore("b/260925899")
fun apply_ColorBundle_index() {
testApplyColorBundle(1, "1")
testApplyColorBundle(2, "2")
@@ -94,10 +97,13 @@
}
private fun testApplyColorBundle(index: Int, value: String) {
- manager.apply(getColorBundle(index), object : CustomizationManager.Callback {
- override fun onSuccess() {}
- override fun onError(throwable: Throwable?) {}
- })
+ manager.apply(
+ getColorBundle(index),
+ object : CustomizationManager.Callback {
+ override fun onSuccess() {}
+ override fun onError(throwable: Throwable?) {}
+ }
+ )
val overlaysJson = JSONObject(manager.storedOverlays)
@@ -106,7 +112,8 @@
private fun getColorBundle(index: Int): ColorBundle {
return ColorBundle(
- "fake color", mapOf("fake_package" to "fake_color"),
+ "fake color",
+ mapOf("fake_package" to "fake_color"),
/* isDefault= */ false,
null,
/* index= */ index,
@@ -115,6 +122,7 @@
}
@Test
+ @Ignore("b/260925899")
fun apply_ColorSeed_index() {
testApplyColorSeed(1, "1")
testApplyColorSeed(2, "2")
@@ -123,10 +131,13 @@
}
private fun testApplyColorSeed(index: Int, value: String) {
- manager.apply(getColorSeed(index), object : CustomizationManager.Callback {
- override fun onSuccess() {}
- override fun onError(throwable: Throwable?) {}
- })
+ manager.apply(
+ getColorSeed(index),
+ object : CustomizationManager.Callback {
+ override fun onSuccess() {}
+ override fun onError(throwable: Throwable?) {}
+ }
+ )
val overlaysJson = JSONObject(manager.storedOverlays)
assertThat(overlaysJson.getString(OVERLAY_COLOR_INDEX)).isEqualTo(value)
@@ -145,29 +156,37 @@
}
@Test
+ @Ignore("b/260925899")
fun testApply_colorSeedFromWallpaperBoth_shouldReturnBothValue() {
val wallpaperColor = WallpaperColors(Color.valueOf(Color.RED), null, null)
manager.setWallpaperColors(wallpaperColor, wallpaperColor)
- manager.apply(getColorSeed(anyInt()), object : CustomizationManager.Callback {
- override fun onSuccess() {}
- override fun onError(throwable: Throwable?) {}
- })
+ manager.apply(
+ getColorSeed(anyInt()),
+ object : CustomizationManager.Callback {
+ override fun onSuccess() {}
+ override fun onError(throwable: Throwable?) {}
+ }
+ )
val overlaysJson = JSONObject(manager.storedOverlays)
assertThat(overlaysJson.getString(OVERLAY_COLOR_BOTH)).isEqualTo("1")
}
@Test
+ @Ignore("b/260925899")
fun testApply_colorSeedFromWallpaperDifferent_shouldReturnNonBothValue() {
val wallpaperColor1 = WallpaperColors(Color.valueOf(Color.RED), null, null)
val wallpaperColor2 = WallpaperColors(Color.valueOf(Color.BLUE), null, null)
manager.setWallpaperColors(wallpaperColor1, wallpaperColor2)
- manager.apply(getColorSeed(anyInt()), object : CustomizationManager.Callback {
- override fun onSuccess() {}
- override fun onError(throwable: Throwable?) {}
- })
+ manager.apply(
+ getColorSeed(anyInt()),
+ object : CustomizationManager.Callback {
+ override fun onSuccess() {}
+ override fun onError(throwable: Throwable?) {}
+ }
+ )
val overlaysJson = JSONObject(manager.storedOverlays)
assertThat(overlaysJson.getString(OVERLAY_COLOR_BOTH)).isEqualTo("0")
diff --git a/robolectric_tests/src/com/android/customization/model/color/ColorOptionTest.kt b/tests/robotests/src/com/android/customization/model/color/ColorOptionTest.kt
similarity index 70%
rename from robolectric_tests/src/com/android/customization/model/color/ColorOptionTest.kt
rename to tests/robotests/src/com/android/customization/model/color/ColorOptionTest.kt
index 271aa83..0431c19 100644
--- a/robolectric_tests/src/com/android/customization/model/color/ColorOptionTest.kt
+++ b/tests/robotests/src/com/android/customization/model/color/ColorOptionTest.kt
@@ -21,6 +21,7 @@
import com.android.systemui.monet.Style
import com.google.common.truth.Truth.assertThat
import org.junit.Assert.assertEquals
+import org.junit.Ignore
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
@@ -30,22 +31,25 @@
import org.mockito.junit.MockitoRule
import org.robolectric.RobolectricTestRunner
-/**
- * Tests of {@link ColorOption}.
- */
+/** Tests of {@link ColorOption}. */
@RunWith(RobolectricTestRunner::class)
class ColorOptionTest {
- @get:Rule
- val rule: MockitoRule = MockitoJUnit.rule()
+ @get:Rule val rule: MockitoRule = MockitoJUnit.rule()
- @Mock
- private lateinit var manager: ColorCustomizationManager
+ @Mock private lateinit var manager: ColorCustomizationManager
@Test
fun colorOption_Source_Preset() {
- val bundleOption: ColorOption = ColorBundle("fake color",
- mapOf("fake_package" to "fake_color"), false, null, /* index= */ 0, null)
+ val bundleOption: ColorOption =
+ ColorBundle(
+ "fake color",
+ mapOf("fake_package" to "fake_color"),
+ false,
+ null,
+ /* index= */ 0,
+ null
+ )
assertEquals(COLOR_SOURCE_PRESET, bundleOption.source)
}
@@ -58,8 +62,15 @@
}
private fun testBundleOptionIndex(index: Int) {
- val bundleOption: ColorBundle = ColorBundle("fake color",
- mapOf("fake_package" to "fake_color"), false, null, /* index= */ index, null)
+ val bundleOption: ColorBundle =
+ ColorBundle(
+ "fake color",
+ mapOf("fake_package" to "fake_color"),
+ false,
+ null,
+ /* index= */ index,
+ null
+ )
assertThat(bundleOption.index).isEqualTo(index)
}
@@ -70,8 +81,16 @@
}
private fun testSeedOptionSource(source: String) {
- val seedOption: ColorOption = ColorSeedOption("fake color",
- mapOf("fake_package" to "fake_color"), false, source, null, /* index= */ 0, null)
+ val seedOption: ColorOption =
+ ColorSeedOption(
+ "fake color",
+ mapOf("fake_package" to "fake_color"),
+ false,
+ source,
+ null,
+ /* index= */ 0,
+ null
+ )
assertThat(seedOption.source).isEqualTo(source)
}
@@ -84,9 +103,16 @@
}
private fun testSeedOptionStyle(style: Style) {
- val seedOption: ColorOption = ColorSeedOption("fake color",
- mapOf("fake_package" to "fake_color"), /* isDefault= */ false, "fake_source", style,
- 0, null)
+ val seedOption: ColorOption =
+ ColorSeedOption(
+ "fake color",
+ mapOf("fake_package" to "fake_color"),
+ /* isDefault= */ false,
+ "fake_source",
+ style,
+ 0,
+ null
+ )
assertThat(seedOption.style).isEqualTo(style)
}
@@ -99,31 +125,39 @@
}
private fun testSeedOptionIndex(index: Int) {
- val seedOption: ColorOption = ColorSeedOption("fake color",
+ val seedOption: ColorOption =
+ ColorSeedOption(
+ "fake color",
mapOf("fake_package" to "fake_color"),
/* isDefault= */ false,
"fake_source",
Style.TONAL_SPOT,
index,
- /* previewInfo= */ null)
+ /* previewInfo= */ null
+ )
assertThat(seedOption.index).isEqualTo(index)
}
- private fun setUpSeedOption(isDefault: Boolean, source: String = "some_source")
- : ColorSeedOption {
- val overlays = if (isDefault) {
- HashMap()
- } else {
- mapOf("package" to "value", "otherPackage" to "otherValue")
- }
+ private fun setUpSeedOption(
+ isDefault: Boolean,
+ source: String = "some_source"
+ ): ColorSeedOption {
+ val overlays =
+ if (isDefault) {
+ HashMap()
+ } else {
+ mapOf("package" to "value", "otherPackage" to "otherValue")
+ }
`when`(manager.currentOverlays).thenReturn(overlays)
- return ColorSeedOption("seed",
- overlays,
- isDefault,
- source,
- Style.TONAL_SPOT,
- /* index= */ 0,
- /* previewInfo= */ null)
+ return ColorSeedOption(
+ "seed",
+ overlays,
+ isDefault,
+ source,
+ Style.TONAL_SPOT,
+ /* index= */ 0,
+ /* previewInfo= */ null
+ )
}
@Test
@@ -170,6 +204,7 @@
}
@Test
+ @Ignore("b/260925899")
fun seedOption_isActive_default_nonEmptyOverlays() {
val seedOption = setUpSeedOption(true)
diff --git a/robolectric_tests/src/com/android/customization/model/color/ColorSectionControllerTest.java b/tests/robotests/src/com/android/customization/model/color/ColorSectionControllerTest.java
similarity index 100%
rename from robolectric_tests/src/com/android/customization/model/color/ColorSectionControllerTest.java
rename to tests/robotests/src/com/android/customization/model/color/ColorSectionControllerTest.java
diff --git a/robolectric_tests/src/com/android/customization/model/grid/GridOptionsManagerTest.java b/tests/robotests/src/com/android/customization/model/grid/GridOptionsManagerTest.java
similarity index 97%
rename from robolectric_tests/src/com/android/customization/model/grid/GridOptionsManagerTest.java
rename to tests/robotests/src/com/android/customization/model/grid/GridOptionsManagerTest.java
index 4268725..89ca676 100644
--- a/robolectric_tests/src/com/android/customization/model/grid/GridOptionsManagerTest.java
+++ b/tests/robotests/src/com/android/customization/model/grid/GridOptionsManagerTest.java
@@ -27,6 +27,7 @@
import com.android.customization.module.ThemesUserEventLogger;
import org.junit.Before;
+import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
@@ -66,6 +67,7 @@
}
@Test
+ @Ignore("b/260925899")
public void testFetch_backgroundThread() {
mManager.fetchOptions(null, false);
verify(mProvider).fetch(anyBoolean());
diff --git a/robolectric_tests/src/com/android/customization/model/theme/ThemeManagerTest.java b/tests/robotests/src/com/android/customization/model/theme/ThemeManagerTest.java
similarity index 100%
rename from robolectric_tests/src/com/android/customization/model/theme/ThemeManagerTest.java
rename to tests/robotests/src/com/android/customization/model/theme/ThemeManagerTest.java
diff --git a/tests/robotests/src/com/android/customization/picker/clock/ClockCustomDemoFragmentTest.kt b/tests/robotests/src/com/android/customization/picker/clock/ClockCustomDemoFragmentTest.kt
new file mode 100644
index 0000000..ad3dd1c
--- /dev/null
+++ b/tests/robotests/src/com/android/customization/picker/clock/ClockCustomDemoFragmentTest.kt
@@ -0,0 +1,99 @@
+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/robolectric_tests/src/com/android/customization/testutils/Condition.java b/tests/robotests/src/com/android/customization/testutils/Condition.java
similarity index 100%
rename from robolectric_tests/src/com/android/customization/testutils/Condition.java
rename to tests/robotests/src/com/android/customization/testutils/Condition.java
diff --git a/robolectric_tests/src/com/android/customization/testutils/OverlayManagerMocks.java b/tests/robotests/src/com/android/customization/testutils/OverlayManagerMocks.java
similarity index 78%
rename from robolectric_tests/src/com/android/customization/testutils/OverlayManagerMocks.java
rename to tests/robotests/src/com/android/customization/testutils/OverlayManagerMocks.java
index ed77224..79b2e43 100644
--- a/robolectric_tests/src/com/android/customization/testutils/OverlayManagerMocks.java
+++ b/tests/robotests/src/com/android/customization/testutils/OverlayManagerMocks.java
@@ -42,22 +42,22 @@
*/
public class OverlayManagerMocks {
private static class MockOverlay {
- final String packageName;
- final String targetPackage;
- final String category;
+ final String mPackageName;
+ final String mTargetPackage;
+ final String mCategory;
- public MockOverlay(String packageName, String targetPackage, String category) {
- this.packageName = packageName;
- this.targetPackage = targetPackage;
- this.category = category;
+ MockOverlay(String packageName, String targetPackage, String category) {
+ this.mPackageName = packageName;
+ this.mTargetPackage = targetPackage;
+ this.mCategory = category;
}
@Override
public boolean equals(Object obj) {
return obj instanceof MockOverlay
- && TextUtils.equals(((MockOverlay) obj).packageName, packageName)
- && TextUtils.equals(((MockOverlay) obj).targetPackage, targetPackage)
- && TextUtils.equals(((MockOverlay) obj).category, category);
+ && TextUtils.equals(((MockOverlay) obj).mPackageName, mPackageName)
+ && TextUtils.equals(((MockOverlay) obj).mTargetPackage, mTargetPackage)
+ && TextUtils.equals(((MockOverlay) obj).mCategory, mCategory);
}
}
@@ -69,8 +69,8 @@
return false;
}
Set<MockOverlay> packageOverlays = mAllOverlays.stream()
- .filter(mockOverlay -> mockOverlay.packageName.equals(packageName)).collect(
- Collectors.toSet());;
+ .filter(mockOverlay -> mockOverlay.mPackageName.equals(packageName)).collect(
+ Collectors.toSet());
if (packageOverlays.isEmpty()) {
return false;
}
@@ -101,9 +101,9 @@
(Answer<String>) inv ->
mEnabledOverlays.stream().filter(
mockOverlay ->
- mockOverlay.targetPackage.equals(inv.getArgument(0))
- && mockOverlay.category.equals(inv.getArgument(1)))
- .map(overlay -> overlay.packageName).findFirst().orElse(null));
+ mockOverlay.mTargetPackage.equals(inv.getArgument(0))
+ && mockOverlay.mCategory.equals(inv.getArgument(1)))
+ .map(overlay -> overlay.mPackageName).findFirst().orElse(null));
when(mockOverlayManager.disableOverlay(anyString(), anyInt())).then(
@@ -124,12 +124,12 @@
mEnabledOverlays.stream().filter(
overlay ->
Arrays.asList(inv.getArguments())
- .contains(overlay.targetPackage))
+ .contains(overlay.mTargetPackage))
.collect(Collectors.toMap(
overlay ->
- overlay.category,
+ overlay.mCategory,
(Function<MockOverlay, String>) overlay ->
- overlay.packageName))
+ overlay.mPackageName))
);
}
-}
\ No newline at end of file
+}
diff --git a/robolectric_tests/src/com/android/customization/testutils/Wait.java b/tests/robotests/src/com/android/customization/testutils/Wait.java
similarity index 100%
rename from robolectric_tests/src/com/android/customization/testutils/Wait.java
rename to tests/robotests/src/com/android/customization/testutils/Wait.java
diff --git a/tests/src/com/android/customization/model/picker/quickaffordance/data/repository/KeyguardQuickAffordancePickerRepositoryTest.kt b/tests/src/com/android/customization/model/picker/quickaffordance/data/repository/KeyguardQuickAffordancePickerRepositoryTest.kt
new file mode 100644
index 0000000..3f22ced
--- /dev/null
+++ b/tests/src/com/android/customization/model/picker/quickaffordance/data/repository/KeyguardQuickAffordancePickerRepositoryTest.kt
@@ -0,0 +1,100 @@
+/*
+ * 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.picker.quickaffordance.data.repository
+
+import androidx.test.filters.SmallTest
+import com.android.customization.picker.quickaffordance.data.repository.KeyguardQuickAffordancePickerRepository
+import com.android.systemui.shared.customization.data.content.CustomizationProviderContract
+import com.android.systemui.shared.customization.data.content.FakeCustomizationProviderClient
+import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.Dispatchers
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.flow.toList
+import kotlinx.coroutines.launch
+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 KeyguardQuickAffordancePickerRepositoryTest {
+
+ private lateinit var underTest: KeyguardQuickAffordancePickerRepository
+
+ private lateinit var testScope: TestScope
+ private lateinit var client: FakeCustomizationProviderClient
+
+ @Before
+ fun setUp() {
+ client = FakeCustomizationProviderClient()
+ val coroutineDispatcher = UnconfinedTestDispatcher()
+ testScope = TestScope(coroutineDispatcher)
+ Dispatchers.setMain(coroutineDispatcher)
+
+ underTest =
+ KeyguardQuickAffordancePickerRepository(
+ client = client,
+ backgroundDispatcher = coroutineDispatcher,
+ )
+ }
+
+ @After
+ fun tearDown() {
+ Dispatchers.resetMain()
+ }
+
+ @Test
+ fun `isFeatureEnabled - enabled`() =
+ testScope.runTest {
+ client.setFlag(
+ CustomizationProviderContract.FlagsTable
+ .FLAG_NAME_CUSTOM_LOCK_SCREEN_QUICK_AFFORDANCES_ENABLED,
+ true,
+ )
+ val values = mutableListOf<Boolean>()
+ val job = launch { underTest.isFeatureEnabled.toList(values) }
+
+ assertThat(values.last()).isTrue()
+
+ job.cancel()
+ }
+
+ @Test
+ fun `isFeatureEnabled - not enabled`() =
+ testScope.runTest {
+ client.setFlag(
+ CustomizationProviderContract.FlagsTable
+ .FLAG_NAME_CUSTOM_LOCK_SCREEN_QUICK_AFFORDANCES_ENABLED,
+ false,
+ )
+ val values = mutableListOf<Boolean>()
+ val job = launch { underTest.isFeatureEnabled.toList(values) }
+
+ assertThat(values.last()).isFalse()
+
+ job.cancel()
+ }
+}
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
new file mode 100644
index 0000000..9a2a0af
--- /dev/null
+++ b/tests/src/com/android/customization/model/picker/quickaffordance/domain/interactor/KeyguardQuickAffordancePickerInteractorTest.kt
@@ -0,0 +1,157 @@
+/*
+ * 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.picker.quickaffordance.domain.interactor
+
+import androidx.test.filters.SmallTest
+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.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.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.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 KeyguardQuickAffordancePickerInteractorTest {
+
+ private lateinit var underTest: KeyguardQuickAffordancePickerInteractor
+
+ private lateinit var testScope: TestScope
+ private lateinit var client: FakeCustomizationProviderClient
+
+ @Before
+ fun setUp() {
+ val testDispatcher = StandardTestDispatcher()
+ testScope = TestScope(testDispatcher)
+ Dispatchers.setMain(testDispatcher)
+ client = FakeCustomizationProviderClient()
+ underTest =
+ KeyguardQuickAffordancePickerInteractor(
+ repository =
+ KeyguardQuickAffordancePickerRepository(
+ client = client,
+ backgroundDispatcher = testDispatcher,
+ ),
+ client = client,
+ snapshotRestorer = {
+ KeyguardQuickAffordanceSnapshotRestorer(
+ interactor = underTest,
+ client = client,
+ )
+ .apply { runBlocking { setUpSnapshotRestorer {} } }
+ },
+ )
+ }
+
+ @After
+ fun tearDown() {
+ Dispatchers.resetMain()
+ }
+
+ @Test
+ fun select() =
+ testScope.runTest {
+ val selections = collectLastValue(underTest.selections)
+
+ underTest.select(
+ slotId = KeyguardQuickAffordanceSlots.SLOT_ID_BOTTOM_START,
+ affordanceId = FakeCustomizationProviderClient.AFFORDANCE_1,
+ )
+ assertThat(selections())
+ .isEqualTo(
+ listOf(
+ KeyguardQuickAffordancePickerSelectionModel(
+ slotId = KeyguardQuickAffordanceSlots.SLOT_ID_BOTTOM_START,
+ affordanceId = FakeCustomizationProviderClient.AFFORDANCE_1,
+ ),
+ )
+ )
+
+ underTest.select(
+ slotId = KeyguardQuickAffordanceSlots.SLOT_ID_BOTTOM_START,
+ affordanceId = FakeCustomizationProviderClient.AFFORDANCE_2,
+ )
+ assertThat(selections())
+ .isEqualTo(
+ listOf(
+ KeyguardQuickAffordancePickerSelectionModel(
+ slotId = KeyguardQuickAffordanceSlots.SLOT_ID_BOTTOM_START,
+ affordanceId = FakeCustomizationProviderClient.AFFORDANCE_2,
+ ),
+ )
+ )
+ }
+
+ @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)
+ val selections = collectLastValue(underTest.selections)
+ underTest.select(
+ slotId = KeyguardQuickAffordanceSlots.SLOT_ID_BOTTOM_END,
+ affordanceId = FakeCustomizationProviderClient.AFFORDANCE_1,
+ )
+ underTest.select(
+ slotId = KeyguardQuickAffordanceSlots.SLOT_ID_BOTTOM_END,
+ affordanceId = FakeCustomizationProviderClient.AFFORDANCE_2,
+ )
+ underTest.select(
+ slotId = KeyguardQuickAffordanceSlots.SLOT_ID_BOTTOM_END,
+ affordanceId = FakeCustomizationProviderClient.AFFORDANCE_3,
+ )
+
+ underTest.unselectAll(
+ slotId = KeyguardQuickAffordanceSlots.SLOT_ID_BOTTOM_END,
+ )
+
+ assertThat(selections()).isEmpty()
+ }
+}
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
new file mode 100644
index 0000000..d1214c1
--- /dev/null
+++ b/tests/src/com/android/customization/model/picker/quickaffordance/ui/viewmodel/KeyguardQuickAffordancePickerViewModelTest.kt
@@ -0,0 +1,438 @@
+/*
+ * 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.picker.quickaffordance.ui.viewmodel
+
+import android.content.Context
+import androidx.test.filters.SmallTest
+import androidx.test.platform.app.InstrumentationRegistry
+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.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.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.testing.TestCurrentWallpaperInfoFactory
+import com.android.wallpaper.testing.TestInjector
+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 KeyguardQuickAffordancePickerViewModelTest {
+
+ private lateinit var underTest: KeyguardQuickAffordancePickerViewModel
+
+ private lateinit var context: Context
+ private lateinit var testScope: TestScope
+ private lateinit var client: FakeCustomizationProviderClient
+ private lateinit var quickAffordanceInteractor: KeyguardQuickAffordancePickerInteractor
+
+ @Before
+ fun setUp() {
+ InjectorProvider.setInjector(TestInjector())
+ context = InstrumentationRegistry.getInstrumentation().targetContext
+ val testDispatcher = StandardTestDispatcher()
+ testScope = TestScope(testDispatcher)
+ Dispatchers.setMain(testDispatcher)
+ client = FakeCustomizationProviderClient()
+
+ quickAffordanceInteractor =
+ KeyguardQuickAffordancePickerInteractor(
+ repository =
+ KeyguardQuickAffordancePickerRepository(
+ client = client,
+ backgroundDispatcher = testDispatcher,
+ ),
+ client = client,
+ snapshotRestorer = {
+ KeyguardQuickAffordanceSnapshotRestorer(
+ interactor = quickAffordanceInteractor,
+ client = client,
+ )
+ .apply { runBlocking { setUpSnapshotRestorer {} } }
+ },
+ )
+ val undoInteractor =
+ UndoInteractor(
+ scope = testScope.backgroundScope,
+ repository = UndoRepository(),
+ restorerByOwnerId = FAKE_RESTORERS,
+ )
+ underTest =
+ KeyguardQuickAffordancePickerViewModel.Factory(
+ context = context,
+ quickAffordanceInteractor = quickAffordanceInteractor,
+ undoInteractor = undoInteractor,
+ wallpaperInfoFactory = TestCurrentWallpaperInfoFactory(context),
+ )
+ .create(KeyguardQuickAffordancePickerViewModel::class.java)
+ }
+
+ @After
+ fun tearDown() {
+ Dispatchers.resetMain()
+ }
+
+ @Test
+ fun `Select an affordance for each side`() =
+ testScope.runTest {
+ val slots = collectLastValue(underTest.slots)
+ val quickAffordances = collectLastValue(underTest.quickAffordances)
+
+ // Initially, the first slot is selected with the "none" affordance selected.
+ assertPickerUiState(
+ slots = slots(),
+ affordances = quickAffordances(),
+ selectedSlotText = "Left button",
+ selectedAffordanceText = "None",
+ )
+ assertPreviewUiState(
+ slots = slots(),
+ expectedAffordanceNameBySlotId =
+ mapOf(
+ KeyguardQuickAffordanceSlots.SLOT_ID_BOTTOM_START to null,
+ KeyguardQuickAffordanceSlots.SLOT_ID_BOTTOM_END to null,
+ ),
+ )
+
+ // Select "affordance 1" for the first slot.
+ quickAffordances()?.get(1)?.onClicked?.invoke()
+ assertPickerUiState(
+ slots = slots(),
+ affordances = quickAffordances(),
+ selectedSlotText = "Left button",
+ selectedAffordanceText = FakeCustomizationProviderClient.AFFORDANCE_1,
+ )
+ assertPreviewUiState(
+ slots = slots(),
+ expectedAffordanceNameBySlotId =
+ mapOf(
+ KeyguardQuickAffordanceSlots.SLOT_ID_BOTTOM_START to
+ FakeCustomizationProviderClient.AFFORDANCE_1,
+ KeyguardQuickAffordanceSlots.SLOT_ID_BOTTOM_END to null,
+ ),
+ )
+
+ // 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()
+ assertPickerUiState(
+ slots = slots(),
+ affordances = quickAffordances(),
+ selectedSlotText = "Right button",
+ selectedAffordanceText = FakeCustomizationProviderClient.AFFORDANCE_3,
+ )
+ assertPreviewUiState(
+ slots = slots(),
+ expectedAffordanceNameBySlotId =
+ mapOf(
+ KeyguardQuickAffordanceSlots.SLOT_ID_BOTTOM_START to
+ FakeCustomizationProviderClient.AFFORDANCE_1,
+ KeyguardQuickAffordanceSlots.SLOT_ID_BOTTOM_END to
+ FakeCustomizationProviderClient.AFFORDANCE_3,
+ ),
+ )
+
+ // Select a different affordance for the second slot.
+ quickAffordances()?.get(2)?.onClicked?.invoke()
+ assertPickerUiState(
+ slots = slots(),
+ affordances = quickAffordances(),
+ selectedSlotText = "Right button",
+ selectedAffordanceText = FakeCustomizationProviderClient.AFFORDANCE_2,
+ )
+ assertPreviewUiState(
+ slots = slots(),
+ expectedAffordanceNameBySlotId =
+ mapOf(
+ KeyguardQuickAffordanceSlots.SLOT_ID_BOTTOM_START to
+ FakeCustomizationProviderClient.AFFORDANCE_1,
+ KeyguardQuickAffordanceSlots.SLOT_ID_BOTTOM_END to
+ FakeCustomizationProviderClient.AFFORDANCE_2,
+ ),
+ )
+ }
+
+ @Test
+ fun `Unselect - AKA selecting the none affordance - on one side`() =
+ testScope.runTest {
+ val slots = collectLastValue(underTest.slots)
+ val quickAffordances = collectLastValue(underTest.quickAffordances)
+
+ // Select "affordance 1" for the first slot.
+ quickAffordances()?.get(1)?.onClicked?.invoke()
+ // 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()
+
+ // 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()
+
+ assertPickerUiState(
+ slots = slots(),
+ affordances = quickAffordances(),
+ selectedSlotText = "Left button",
+ selectedAffordanceText = "None",
+ )
+ assertPreviewUiState(
+ slots = slots(),
+ expectedAffordanceNameBySlotId =
+ mapOf(
+ KeyguardQuickAffordanceSlots.SLOT_ID_BOTTOM_START to null,
+ KeyguardQuickAffordanceSlots.SLOT_ID_BOTTOM_END to
+ FakeCustomizationProviderClient.AFFORDANCE_3,
+ ),
+ )
+ }
+
+ @Test
+ fun `Show enablement dialog when selecting a disabled affordance`() =
+ testScope.runTest {
+ val slots = collectLastValue(underTest.slots)
+ val quickAffordances = collectLastValue(underTest.quickAffordances)
+ val dialog = collectLastValue(underTest.dialog)
+
+ val enablementInstructions = listOf("instruction1", "instruction2")
+ val enablementActionText = "enablementActionText"
+ val packageName = "packageName"
+ val action = "action"
+ val enablementActionComponentName = "$packageName/$action"
+ // Lets add a disabled affordance to the picker:
+ val affordanceIndex =
+ client.addAffordance(
+ CustomizationProviderClient.Affordance(
+ id = "disabled",
+ name = "disabled",
+ iconResourceId = 1,
+ isEnabled = false,
+ enablementInstructions = enablementInstructions,
+ enablementActionText = enablementActionText,
+ enablementActionComponentName = enablementActionComponentName,
+ )
+ )
+
+ // Lets try to select that disabled affordance:
+ quickAffordances()?.get(affordanceIndex + 1)?.onClicked?.invoke()
+
+ // 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)
+
+ // Once we report that the dialog has been dismissed by the user, we expect there to be
+ // no
+ // dialog to be shown:
+ underTest.onDialogDismissed()
+ assertThat(dialog()).isNull()
+ }
+
+ @Test
+ fun `summary - affordance selected in both bottom-start and bottom-end`() =
+ testScope.runTest {
+ val slots = collectLastValue(underTest.slots)
+ val quickAffordances = collectLastValue(underTest.quickAffordances)
+ val summary = collectLastValue(underTest.summary)
+
+ // Select "affordance 1" for the first slot.
+ quickAffordances()?.get(1)?.onClicked?.invoke()
+ // 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()
+
+ assertThat(summary())
+ .isEqualTo(
+ KeyguardQuickAffordanceSummaryViewModel(
+ description =
+ "${FakeCustomizationProviderClient.AFFORDANCE_1}," +
+ " ${FakeCustomizationProviderClient.AFFORDANCE_3}",
+ icon1 = FakeCustomizationProviderClient.ICON_1,
+ icon2 = FakeCustomizationProviderClient.ICON_3,
+ )
+ )
+ }
+
+ @Test
+ fun `summary - affordance selected only on bottom-start`() =
+ testScope.runTest {
+ val slots = collectLastValue(underTest.slots)
+ val quickAffordances = collectLastValue(underTest.quickAffordances)
+ val summary = collectLastValue(underTest.summary)
+
+ // Select "affordance 1" for the first slot.
+ quickAffordances()?.get(1)?.onClicked?.invoke()
+
+ assertThat(summary())
+ .isEqualTo(
+ KeyguardQuickAffordanceSummaryViewModel(
+ description = FakeCustomizationProviderClient.AFFORDANCE_1,
+ icon1 = FakeCustomizationProviderClient.ICON_1,
+ icon2 = null,
+ )
+ )
+ }
+
+ @Test
+ fun `summary - affordance selected only on bottom-end`() =
+ testScope.runTest {
+ val slots = collectLastValue(underTest.slots)
+ val quickAffordances = collectLastValue(underTest.quickAffordances)
+ val summary = collectLastValue(underTest.summary)
+
+ // 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()
+
+ assertThat(summary())
+ .isEqualTo(
+ KeyguardQuickAffordanceSummaryViewModel(
+ description = FakeCustomizationProviderClient.AFFORDANCE_3,
+ icon1 = null,
+ icon2 = FakeCustomizationProviderClient.ICON_3,
+ )
+ )
+ }
+
+ @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()?.icon1).isNotNull()
+ assertThat(summary()?.icon2).isNull()
+ }
+
+ /**
+ * Asserts the entire picker UI state is what is expected. This includes the slot tabs and the
+ * affordance list.
+ *
+ * @param slots The observed slot view-models, keyed by slot ID
+ * @param affordances The observed affordances
+ * @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(
+ slots: Map<String, KeyguardQuickAffordanceSlotViewModel>?,
+ affordances: List<KeyguardQuickAffordanceViewModel>?,
+ selectedSlotText: String,
+ selectedAffordanceText: String,
+ ) {
+ assertSlotTabUiState(
+ slots = slots,
+ slotId = KeyguardQuickAffordanceSlots.SLOT_ID_BOTTOM_START,
+ isSelected = "Left button" == selectedSlotText,
+ )
+ assertSlotTabUiState(
+ slots = slots,
+ slotId = KeyguardQuickAffordanceSlots.SLOT_ID_BOTTOM_END,
+ isSelected = "Right button" == selectedSlotText,
+ )
+
+ 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}"
+ )
+ .that(affordance.isSelected)
+ .isEqualTo(nameMatchesSelectedName)
+ foundSelectedAffordance = foundSelectedAffordance || nameMatchesSelectedName
+ }
+ assertWithMessage("No affordance is selected!").that(foundSelectedAffordance).isTrue()
+ }
+
+ /**
+ * Asserts that a slot tab has the correct UI state.
+ *
+ * @param slots The observed slot view-models, keyed by slot ID
+ * @param slotId the ID of the slot to assert
+ * @param isSelected Whether that slot should be selected
+ */
+ private fun assertSlotTabUiState(
+ slots: Map<String, KeyguardQuickAffordanceSlotViewModel>?,
+ slotId: String,
+ isSelected: Boolean,
+ ) {
+ val viewModel = slots?.get(slotId) ?: error("No slot with ID \"$slotId\"!")
+ assertThat(viewModel.isSelected).isEqualTo(isSelected)
+ }
+
+ /**
+ * Asserts the UI state of the preview.
+ *
+ * @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
+ */
+ private fun assertPreviewUiState(
+ slots: Map<String, KeyguardQuickAffordanceSlotViewModel>?,
+ expectedAffordanceNameBySlotId: Map<String, String?>,
+ ) {
+ assertThat(slots).isNotNull()
+ slots?.forEach { (slotId, slotViewModel) ->
+ val expectedAffordanceName = expectedAffordanceNameBySlotId[slotId]
+ val actualAffordanceName =
+ slotViewModel.selectedQuickAffordances.firstOrNull()?.contentDescription
+ assertWithMessage(
+ "At slotId=\"$slotId\", expected affordance=\"$expectedAffordanceName\" but" +
+ " was \"$actualAffordanceName\"!"
+ )
+ .that(actualAffordanceName)
+ .isEqualTo(expectedAffordanceName)
+ }
+ }
+}
diff --git a/tests/src/com/android/customization/testing/TestCustomizationInjector.java b/tests/src/com/android/customization/testing/TestCustomizationInjector.java
index dbbdb74..d609335 100644
--- a/tests/src/com/android/customization/testing/TestCustomizationInjector.java
+++ b/tests/src/com/android/customization/testing/TestCustomizationInjector.java
@@ -10,11 +10,23 @@
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.
*/
@@ -24,6 +36,10 @@
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) {
@@ -68,4 +84,60 @@
}
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/themes/res/values-af/strings.xml b/themes/res/values-af/strings.xml
index 59e659c..a0da3f8 100644
--- a/themes/res/values-af/strings.xml
+++ b/themes/res/values-af/strings.xml
@@ -24,4 +24,5 @@
<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
index 7b22f4c..c5d0492 100644
--- a/themes/res/values-am/strings.xml
+++ b/themes/res/values-am/strings.xml
@@ -24,4 +24,5 @@
<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
index e1fb282..89ef13e 100644
--- a/themes/res/values-ar/strings.xml
+++ b/themes/res/values-ar/strings.xml
@@ -24,4 +24,5 @@
<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
index 38642d5..a42cbca 100644
--- a/themes/res/values-as/strings.xml
+++ b/themes/res/values-as/strings.xml
@@ -24,4 +24,5 @@
<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
index ed3a3dc..37719fe 100644
--- a/themes/res/values-az/strings.xml
+++ b/themes/res/values-az/strings.xml
@@ -24,4 +24,5 @@
<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
index 4227e14..0497600 100644
--- a/themes/res/values-b+sr+Latn/strings.xml
+++ b/themes/res/values-b+sr+Latn/strings.xml
@@ -24,4 +24,5 @@
<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
index 7e0130d..b9e2dc5 100644
--- a/themes/res/values-be/strings.xml
+++ b/themes/res/values-be/strings.xml
@@ -24,4 +24,5 @@
<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
index 1aa2b0a..99e1b0d 100644
--- a/themes/res/values-bg/strings.xml
+++ b/themes/res/values-bg/strings.xml
@@ -24,4 +24,5 @@
<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
index 942eea1..8a90e02 100644
--- a/themes/res/values-bn/strings.xml
+++ b/themes/res/values-bn/strings.xml
@@ -24,4 +24,5 @@
<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
index 4227e14..1f9990a 100644
--- a/themes/res/values-bs/strings.xml
+++ b/themes/res/values-bs/strings.xml
@@ -24,4 +24,5 @@
<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
index 6ccf839..55c487e 100644
--- a/themes/res/values-ca/strings.xml
+++ b/themes/res/values-ca/strings.xml
@@ -24,4 +24,5 @@
<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
index 6be2bc6..b58134e 100644
--- a/themes/res/values-cs/strings.xml
+++ b/themes/res/values-cs/strings.xml
@@ -24,4 +24,5 @@
<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
index ef759c2..ae6595a 100644
--- a/themes/res/values-da/strings.xml
+++ b/themes/res/values-da/strings.xml
@@ -24,4 +24,5 @@
<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
index ba95a0b..c941c1e 100644
--- a/themes/res/values-de/strings.xml
+++ b/themes/res/values-de/strings.xml
@@ -24,4 +24,5 @@
<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
index 5e47c23..4b62b5d 100644
--- a/themes/res/values-el/strings.xml
+++ b/themes/res/values-el/strings.xml
@@ -24,4 +24,5 @@
<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
index f10dfca..ae4e8c5 100644
--- a/themes/res/values-en-rAU/strings.xml
+++ b/themes/res/values-en-rAU/strings.xml
@@ -24,4 +24,5 @@
<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
index f10dfca..780a3c9 100644
--- a/themes/res/values-en-rCA/strings.xml
+++ b/themes/res/values-en-rCA/strings.xml
@@ -24,4 +24,6 @@
<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
index f10dfca..ae4e8c5 100644
--- a/themes/res/values-en-rGB/strings.xml
+++ b/themes/res/values-en-rGB/strings.xml
@@ -24,4 +24,5 @@
<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
index f10dfca..ae4e8c5 100644
--- a/themes/res/values-en-rIN/strings.xml
+++ b/themes/res/values-en-rIN/strings.xml
@@ -24,4 +24,5 @@
<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
index c6114a4..170b178 100644
--- a/themes/res/values-en-rXC/strings.xml
+++ b/themes/res/values-en-rXC/strings.xml
@@ -24,4 +24,5 @@
<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
index a5f43a3..413e3f0 100644
--- a/themes/res/values-es-rUS/strings.xml
+++ b/themes/res/values-es-rUS/strings.xml
@@ -24,4 +24,5 @@
<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
index f32bbcc..65b9081 100644
--- a/themes/res/values-es/strings.xml
+++ b/themes/res/values-es/strings.xml
@@ -24,4 +24,5 @@
<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
index c80e028..a4907c1 100644
--- a/themes/res/values-et/strings.xml
+++ b/themes/res/values-et/strings.xml
@@ -24,4 +24,5 @@
<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
index def8ca4..2525de7 100644
--- a/themes/res/values-eu/strings.xml
+++ b/themes/res/values-eu/strings.xml
@@ -24,4 +24,5 @@
<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
index e6628d4..3a03e5f 100644
--- a/themes/res/values-fa/strings.xml
+++ b/themes/res/values-fa/strings.xml
@@ -24,4 +24,5 @@
<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
index 385c7c8..9f24dec 100644
--- a/themes/res/values-fi/strings.xml
+++ b/themes/res/values-fi/strings.xml
@@ -24,4 +24,5 @@
<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
index 38a69e4..5bb81e9 100644
--- a/themes/res/values-fr-rCA/strings.xml
+++ b/themes/res/values-fr-rCA/strings.xml
@@ -24,4 +24,5 @@
<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
index 1141778..7942935 100644
--- a/themes/res/values-fr/strings.xml
+++ b/themes/res/values-fr/strings.xml
@@ -24,4 +24,5 @@
<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
index 874f304..7317086 100644
--- a/themes/res/values-gl/strings.xml
+++ b/themes/res/values-gl/strings.xml
@@ -24,4 +24,5 @@
<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
index b9f0ca4..b8c6c25 100644
--- a/themes/res/values-gu/strings.xml
+++ b/themes/res/values-gu/strings.xml
@@ -24,4 +24,5 @@
<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
index eb63fb5..f2e122b 100644
--- a/themes/res/values-hi/strings.xml
+++ b/themes/res/values-hi/strings.xml
@@ -24,4 +24,5 @@
<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
index acfe739..6d8b772 100644
--- a/themes/res/values-hr/strings.xml
+++ b/themes/res/values-hr/strings.xml
@@ -24,4 +24,5 @@
<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
index 1daa4ec..d830cd3 100644
--- a/themes/res/values-hu/strings.xml
+++ b/themes/res/values-hu/strings.xml
@@ -24,4 +24,5 @@
<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
index 433aa7d..1b7a791 100644
--- a/themes/res/values-hy/strings.xml
+++ b/themes/res/values-hy/strings.xml
@@ -24,4 +24,5 @@
<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
index fd1ad80..ab3df36 100644
--- a/themes/res/values-in/strings.xml
+++ b/themes/res/values-in/strings.xml
@@ -24,4 +24,5 @@
<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
index dd333db..1e34499 100644
--- a/themes/res/values-is/strings.xml
+++ b/themes/res/values-is/strings.xml
@@ -24,4 +24,5 @@
<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
index b57ac74..1ebec4c 100644
--- a/themes/res/values-it/strings.xml
+++ b/themes/res/values-it/strings.xml
@@ -24,4 +24,5 @@
<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
index 50a7541..49feaed 100644
--- a/themes/res/values-iw/strings.xml
+++ b/themes/res/values-iw/strings.xml
@@ -24,4 +24,5 @@
<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
index 24e552d..7a259e6 100644
--- a/themes/res/values-ja/strings.xml
+++ b/themes/res/values-ja/strings.xml
@@ -24,4 +24,5 @@
<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
index ea2d235..041dfc4 100644
--- a/themes/res/values-ka/strings.xml
+++ b/themes/res/values-ka/strings.xml
@@ -24,4 +24,5 @@
<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
index bc6aa76..b9d3952 100644
--- a/themes/res/values-kk/strings.xml
+++ b/themes/res/values-kk/strings.xml
@@ -24,4 +24,5 @@
<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
index b3ace48..a182c7a 100644
--- a/themes/res/values-km/strings.xml
+++ b/themes/res/values-km/strings.xml
@@ -24,4 +24,5 @@
<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
index abd1b72..a899325 100644
--- a/themes/res/values-kn/strings.xml
+++ b/themes/res/values-kn/strings.xml
@@ -24,4 +24,5 @@
<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
index 3c5710e..2a77dc8 100644
--- a/themes/res/values-ko/strings.xml
+++ b/themes/res/values-ko/strings.xml
@@ -24,4 +24,5 @@
<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
index abcc95e..1aaf2e0 100644
--- a/themes/res/values-ky/strings.xml
+++ b/themes/res/values-ky/strings.xml
@@ -24,4 +24,5 @@
<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
index e4d1ebf..8e5f1a2 100644
--- a/themes/res/values-lo/strings.xml
+++ b/themes/res/values-lo/strings.xml
@@ -24,4 +24,5 @@
<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
index 0a6396e..542eea7 100644
--- a/themes/res/values-lt/strings.xml
+++ b/themes/res/values-lt/strings.xml
@@ -24,4 +24,5 @@
<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
index 9b4038e..58b15e8 100644
--- a/themes/res/values-lv/strings.xml
+++ b/themes/res/values-lv/strings.xml
@@ -24,4 +24,5 @@
<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
index 82a9b2c..94d1098 100644
--- a/themes/res/values-mk/strings.xml
+++ b/themes/res/values-mk/strings.xml
@@ -24,4 +24,5 @@
<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
index fac9906..60f5acb 100644
--- a/themes/res/values-ml/strings.xml
+++ b/themes/res/values-ml/strings.xml
@@ -24,4 +24,5 @@
<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
index ac9d8ba..1a8c146 100644
--- a/themes/res/values-mn/strings.xml
+++ b/themes/res/values-mn/strings.xml
@@ -24,4 +24,5 @@
<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
index 742cb47..cd0f1e7 100644
--- a/themes/res/values-mr/strings.xml
+++ b/themes/res/values-mr/strings.xml
@@ -24,4 +24,5 @@
<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
index eda40ca..52a945b 100644
--- a/themes/res/values-ms/strings.xml
+++ b/themes/res/values-ms/strings.xml
@@ -24,4 +24,5 @@
<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
index 58d3f31..6a12ed8 100644
--- a/themes/res/values-my/strings.xml
+++ b/themes/res/values-my/strings.xml
@@ -24,4 +24,5 @@
<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
index cc42d6c..f099b11 100644
--- a/themes/res/values-nb/strings.xml
+++ b/themes/res/values-nb/strings.xml
@@ -24,4 +24,5 @@
<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
index a5c223e..3100185 100644
--- a/themes/res/values-ne/strings.xml
+++ b/themes/res/values-ne/strings.xml
@@ -24,4 +24,5 @@
<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
index 1a10728..be6785e 100644
--- a/themes/res/values-nl/strings.xml
+++ b/themes/res/values-nl/strings.xml
@@ -24,4 +24,5 @@
<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
index be0b57d..3b10876 100644
--- a/themes/res/values-or/strings.xml
+++ b/themes/res/values-or/strings.xml
@@ -24,4 +24,5 @@
<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
index dae483e..aee99a2 100644
--- a/themes/res/values-pa/strings.xml
+++ b/themes/res/values-pa/strings.xml
@@ -24,4 +24,5 @@
<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
index c34d133..718067b 100644
--- a/themes/res/values-pl/strings.xml
+++ b/themes/res/values-pl/strings.xml
@@ -24,4 +24,5 @@
<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
index 0558b58..70525b6 100644
--- a/themes/res/values-pt-rPT/strings.xml
+++ b/themes/res/values-pt-rPT/strings.xml
@@ -24,4 +24,5 @@
<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
index 0558b58..70525b6 100644
--- a/themes/res/values-pt/strings.xml
+++ b/themes/res/values-pt/strings.xml
@@ -24,4 +24,5 @@
<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
index 35c2abe..c07e7c0 100644
--- a/themes/res/values-ro/strings.xml
+++ b/themes/res/values-ro/strings.xml
@@ -24,4 +24,5 @@
<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
index 77e82f8..f714ff7 100644
--- a/themes/res/values-ru/strings.xml
+++ b/themes/res/values-ru/strings.xml
@@ -24,4 +24,5 @@
<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
index 1da790a..107a988 100644
--- a/themes/res/values-si/strings.xml
+++ b/themes/res/values-si/strings.xml
@@ -24,4 +24,5 @@
<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
index e08467f..9368e6b 100644
--- a/themes/res/values-sk/strings.xml
+++ b/themes/res/values-sk/strings.xml
@@ -24,4 +24,5 @@
<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
index 6c808c3..051a9a3 100644
--- a/themes/res/values-sl/strings.xml
+++ b/themes/res/values-sl/strings.xml
@@ -24,4 +24,5 @@
<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
index 7c4f53c..b9c3ac9 100644
--- a/themes/res/values-sq/strings.xml
+++ b/themes/res/values-sq/strings.xml
@@ -24,4 +24,5 @@
<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
index 68155e0..dca38db 100644
--- a/themes/res/values-sr/strings.xml
+++ b/themes/res/values-sr/strings.xml
@@ -24,4 +24,5 @@
<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
index c6f7f20..a16f98c 100644
--- a/themes/res/values-sv/strings.xml
+++ b/themes/res/values-sv/strings.xml
@@ -24,4 +24,5 @@
<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
index 0b1b90a..26a08f3 100644
--- a/themes/res/values-sw/strings.xml
+++ b/themes/res/values-sw/strings.xml
@@ -24,4 +24,5 @@
<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
index 4b76331..d9f63f9 100644
--- a/themes/res/values-ta/strings.xml
+++ b/themes/res/values-ta/strings.xml
@@ -24,4 +24,5 @@
<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
index e6b0246..7193b3f 100644
--- a/themes/res/values-te/strings.xml
+++ b/themes/res/values-te/strings.xml
@@ -24,4 +24,5 @@
<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
index e597d2b..fed6f85 100644
--- a/themes/res/values-th/strings.xml
+++ b/themes/res/values-th/strings.xml
@@ -24,4 +24,5 @@
<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
index c57e5be..56b9341 100644
--- a/themes/res/values-tl/strings.xml
+++ b/themes/res/values-tl/strings.xml
@@ -24,4 +24,5 @@
<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
index e825d77..7c8a549 100644
--- a/themes/res/values-tr/strings.xml
+++ b/themes/res/values-tr/strings.xml
@@ -24,4 +24,5 @@
<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
index a839046..39bdab6 100644
--- a/themes/res/values-uk/strings.xml
+++ b/themes/res/values-uk/strings.xml
@@ -24,4 +24,5 @@
<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
index de5bd32..744ee5c 100644
--- a/themes/res/values-ur/strings.xml
+++ b/themes/res/values-ur/strings.xml
@@ -24,4 +24,5 @@
<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
index f077f56..6a09e63 100644
--- a/themes/res/values-uz/strings.xml
+++ b/themes/res/values-uz/strings.xml
@@ -24,4 +24,5 @@
<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
index 4eaf609..46e41b9 100644
--- a/themes/res/values-vi/strings.xml
+++ b/themes/res/values-vi/strings.xml
@@ -24,4 +24,5 @@
<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
index e49ed58..074e0c6 100644
--- a/themes/res/values-zh-rCN/strings.xml
+++ b/themes/res/values-zh-rCN/strings.xml
@@ -24,4 +24,5 @@
<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
index 007c561..ce97c07 100644
--- a/themes/res/values-zh-rHK/strings.xml
+++ b/themes/res/values-zh-rHK/strings.xml
@@ -24,4 +24,5 @@
<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
index 79c9ba6..ce67534 100644
--- a/themes/res/values-zh-rTW/strings.xml
+++ b/themes/res/values-zh-rTW/strings.xml
@@ -24,4 +24,5 @@
<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
index 290c1e9..75240f6 100644
--- a/themes/res/values-zu/strings.xml
+++ b/themes/res/values-zu/strings.xml
@@ -24,4 +24,5 @@
<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>
diff --git a/themes/res/values/color-bundles.xml b/themes/res/values/color-bundles.xml
index 4d7cc63..ced594e 100644
--- a/themes/res/values/color-bundles.xml
+++ b/themes/res/values/color-bundles.xml
@@ -16,6 +16,7 @@
-->
<resources>
<array name="color_bundles">
+ <item>monochromatic</item>
<item>rainbow1</item>
<item>rainbow2</item>
<item>rainbow3</item>
diff --git a/themes/res/values/colors.xml b/themes/res/values/colors.xml
index 3ffb9fc..53a4966 100644
--- a/themes/res/values/colors.xml
+++ b/themes/res/values/colors.xml
@@ -15,6 +15,8 @@
~ limitations under the License.
-->
<resources>
+<!--TODO(b/257218629)-->
+ <color name="color_secondary_monochromatic">#FFFF00</color>
<color name="color_secondary_rainbow1">#FFB2B5</color>
<color name="color_secondary_rainbow2">#FFB868</color>
<color name="color_secondary_rainbow3">#E9C44A</color>
diff --git a/themes/res/values/strings.xml b/themes/res/values/strings.xml
index 8bc04bd..31363f7 100644
--- a/themes/res/values/strings.xml
+++ b/themes/res/values/strings.xml
@@ -23,6 +23,7 @@
<string name="rainbow_color_name_blue">Blue</string>
<string name="rainbow_color_name_purple">Purple</string>
<string name="rainbow_color_name_magenta">Magenta</string>
+ <string name="monochromatic_name">Monochromatic</string>
<string name="bundle_name_rainbow1" translatable="false">@string/rainbow_color_name_red</string>
<string name="bundle_name_rainbow2" translatable="false">@string/rainbow_color_name_orange</string>
@@ -31,6 +32,7 @@
<string name="bundle_name_rainbow5" translatable="false">@string/rainbow_color_name_blue</string>
<string name="bundle_name_rainbow6" translatable="false">@string/rainbow_color_name_purple</string>
<string name="bundle_name_rainbow7" translatable="false">@string/rainbow_color_name_magenta</string>
+ <string name="bundle_name_monochromatic" translatable="false">@string/monochromatic_name</string>
<string name="color_style_rainbow1" translatable="false">RAINBOW</string>
<string name="color_style_rainbow2" translatable="false">RAINBOW</string>
@@ -39,4 +41,5 @@
<string name="color_style_rainbow5" translatable="false">RAINBOW</string>
<string name="color_style_rainbow6" translatable="false">RAINBOW</string>
<string name="color_style_rainbow7" translatable="false">RAINBOW</string>
+ <string name="color_style_monochromatic" translatable="false">MONOCHROMATIC</string>
</resources>